版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、资料简介:本程序简单的示范了如何使用ATMEGA16勺TWI读写AT24C02 IIC EEPROMTWI 协议(即 IIC 协议,请认真参考 IIC 协议的内容,否则根本就不能掌握 )一主多从的应用,M16作主机(M16做从机和多主多从的应用不多,请自行参考相关文档)中断模式(因为AVR的速度很高,而IIC的速度相对较低,采用查询模式会长时间独占CPU令CPU的利用率明显下降。特别是 IIC 速度受环境影响只能低速通讯时,对系统的实时性产生严重的影响。 查询模式可以参考其它文档和软件模拟 IIC 的文档 )AT24C02/04/08 的操作特点 出于简化程序考虑,各种数据没有对外输出,学习时
2、建议使用JTAG ICE 硬件仿真器*/#include #include #include #include / 时钟定为外部晶振 7.3728MHz,F_CPU=7372800#include /定义了各种模式下的状态码列表(TWSR已屏蔽预分频位),本文后面附上中文描述/ 管脚定义#define pinSCL0/PC0 SCL#define pinSDA1/PC1 SDA/为保险起见,最好在SCL/SDA接上 110K的外部上拉电阻到 VCC#define fSCL 100000 /TWI 时钟为 100KHz/ 预分频系数 =1(TWPS=0)#if F_CPU fSCL*36#def
3、i ne TWBR_SET10;/TWBR 必须大于等于 10#else#define TWBR_SET(F_CPU/fSCL-16)/2;/ 计算 TWBR值#endif #define TW_ACT (1TWINT)|(1TWEN)|(1TWIE)/24Cxx 系列的厂商器件地址 ( 高四位 )/TWCR只能IN/OUT,直接赋值比逻辑运算(|= &=)更节省空间 #define SLA_24CXX 0xA0#define ADDR_24C02 0x00/ AT24C02 的地址线A2/1/0 全部接地,SLAW=0xA0+0x001+0x00,SLAR=0xA0+0x008)1;i&=0
4、x06;/考虑了 24C04/08的EEPRO地址高位放在 SLA里面strTWI.SLA=sla+i;strTWI.ADDR=addr;strTWI.pBUF=ptr; strTWI.DATALEN=len;strTWI.STATE=ST_START;strTWI.FAILCNT=0;TWCR=(1=0x60)|(status=0x00)/ 总线错误或从机模式引发的中断 , 不予处理 return; switch(state)case ST_START: /START 状态检查 if(status=TW_START) / 发送 start 信号成功TWDR=strTWI.SLA&0xFE;/
5、 发送器件地址写 SLAWTWCR=TW_ACT;/ 触发下一步动作,同时清start 发送标志 else / 发送 start 信号出错 state=ST_FAIL; break;case ST_SLAW: /SLAW 状态检查 if(status=TW_MT_SLA_ACK)/ 发送器件地址成功TWDR=strTWI.ADDR; / 发送 eeprom 地址 TWCR=TW_ACT;/ 触发下一步动作else/ 发送器件地址出错state=ST_FAIL; break;case ST_WADDR: /ADDR 状态检查if(status=TW_MT_DATA_ACK)/ 发送 eeprom
6、 地址成功 if (action=TW_READ) / 读操作模式TWCR=(1TWSTA)|TW_ACT; / 发送 restart 信号,下一步将跳到 RESTAR分支 else/ 写操作模式TWDR=*strTWI.pBUF+;/ 写第一个字节strTWI.DATALEN-;state=ST_WDATA-1; / 下一步将跳到 WDAT分支TWCR=TW_ACT;/ 触发下一步动作else/ 发送 eeprom 地址出错state=ST_FAIL;break;case ST_RESTART: /RESTART状态检查,只有读操作模式才能跳到这里 if(status=TW_REP_STAR
7、T)/ 发送 restart 信号成功TWDR=strTWI.SLA; / 发器件地址读 SLAR TWCR=TW_ACT;/ 触发下一步动作,同时清 start 发送标志else/ 重发 start 信号出错 state=ST_FAIL;break;case ST_SLAR: /SLAR 状态检查,只有读操作模式才能跳到这里 if(status=TW_MR_SLA_ACK)/ 发送器件地址成功if (strTWI.DATALEN-)/ 多个数据TWCR=(1TWEA)|TW_ACT; / 设定 ACK 触发下一步动作else/ 只有一个数据TWCR=TW_ACT; /设定NAK触发下一步动作
8、else/ 发送器件地址出错state=ST_FAIL;break;case ST_RDATA: / 读取数据状态检查,只有读操作模式才能跳到这里state-;/ 循环 , 直到读完指定长度数据if(status=TW_MR_DATA_ACK)/ 读取数据成功,但不是最后一个数据*strTWI.pBUF+=TWDR;if (strTWI.DATALEN-)/ 还有多个数据TWCR=(1TWEA)|TW_ACT; / 设定 ACK 触发下一步动作else/ 准备读最后一个数据 TWCR=TW_ACT; /设定NAK触发下一步动作 else if(status=TW_MR_DATA_NACK)/
9、已经读完最后一个数据 *strTWI.pBUF+=TWDR;TWCR=(1TWSTO)|TW_ACT; / 发送停止信号,不会再产生中断了 strTWI.STATUS=TW_OK;else/ 读取数据出错 state=ST_FAIL; break;case ST_WDATA: / 写数据状态检查,只有写操作模式才能跳到这里 state-;/ 循环 , 直到写完指定长度数据if(status=TW_MT_DATA_ACK)/ 写数据成功if (strTWI.DATALEN)/ 还要写 TWDR=*strTWI.pBUF+; strTWI.DATALEN-;TWCR=TW_ACT;/ 触发下一步动
10、作else/ 写够了TWCR=(1TWSTO)|TW_ACT; / 发送停止信号,不会再产生中断了 strTWI.STATUS=TW_OK;/启动写命令后需要10ms(最大)的编程时间才能真正的把数据记录下来 / 编程期间器件不响应任何命令 else/ 写数据失败 state=ST_FAIL; break;default:/ 错误状态 state=ST_FAIL; break;if (state=ST_FAIL)/ 错误处理strTWI.FAILCNT+;if (strTWI.FAILCNTFAIL_MAX)/ 重试次数未超出最大值,TWCR=(1TWSTA)|TW_ACT; / 发生错误 ,
11、 启动 start 信号else/ 否则停止TWCR=(1TWSTO)|TW_ACT; / 发送停止信号,不会再产生中断了 strTWI.STATUS=TW_FAIL;state+;strTWI.STATE=state; / 保存状态int main(void)unsigned char i;/ 上电默认 DDRx=0x00,PORTx=0x00 输入,无上拉电阻PORTA=0xFF;PORTB=0xFF; PORTC=0xFF; PORTD=0xFF; /TWI 初始化 TWSR=0x00;/ 不用的管脚使能内部上拉电阻。/SCL,SDA 使能了内部的 10K 上拉电阻/预分频=0A4=1T
12、WBR=TWBR_SET;/ 主机模式,该地址无效/ 关闭 TWI 模块TWAR=0x00;TWCR=0x00;sei(); / 使能全局中断strTWI.STATUS=TW_OK;TWI_RW(SLA_24CXX+(ADDR_24C021)+TW_WRITE,0x10,&ORGDATA0,8); / 从 0x10 地址开始写入 8 个字节数据 while(strTWI.STATUS=TW_BUSY); / 等待操作完成if (strTWI.STATUS=TW_FAIL)/ 操作失败?_delay_ms(10);/ 延时等待编程完成while(1) i=TWI_RW(SLA_24CXX+(AD
13、DR_24C021)+TW_READ,0x10,&CMPDATA0,8);/ 从 0x10 地址开始读出 8 个字节数据 while(strTWI.STATUS=TW_BUSY); / 等待操作完成 / 如果不加等待,则需要检测返回值 i 才能知道当前操作是否执行了 / 0 OP_BUSY 之前的操作没完成,没执行当前操作/ 1 OP_RUN 当前操作执行中if (strTWI.STATUS=TW_FAIL)/ 操作失败?/读取成功,对比 ORGDAT和CMPDAT的数据 i=TWI_RW(SLA_24CXX+(ADDR_24C021)+TW_READ,0x00,&BUFFER0,256);/
14、 从 0x00 地址开始读出 256 个字节数据 ( 整个 ATC24C02) while(strTWI.STATUS=TW_BUSY); / 等待操作完成;/* 两线串行接口总线定义两线接口 TWI 很适合于典型的处理器应用。TWI 协议允许系统设计者只用两根双向传输线就可以将128 个不同的设备互连到一起。这两根线一是时钟 SCL 一是数据SDA外部硬件只需要两个上拉电阻,每根线上一个。 所有连接到总线上的设备都 (必须 )有自己的地址。注意 :就是说不能有两个相同地址的设备TWI协议解决了总线仲裁的问题。所有 TWI 兼容的器件的总线驱动都是漏极开路或集电极开路的。这样就实现了对接口操作
15、非常关键的线与功能。TWI器件输出为0 ”时,TWI总线会产生低电平。当所有的TWI器件输出为三态时,总线会输出高电平,允许上拉电阻将电压拉高。 注意:为保证所有的总线操作,凡是与 TWI 总线连接的 AVR 器件必须上电。与总线连接的器件数目受如下条件限制:总线电容要低于400pF,而且可以用7位从机地址进行寻址。 两个不同的规范,一种是总线速度低于 100 kHz ,而另外一种是总线速度高达 400 kHz。SCL和 SDA引脚SCL与SDA为MCI的TWI接口引脚。引脚的输出驱动器包含一个波形斜率限制器以满足 TWI 规范。 引脚的输入部分包括尖峰抑制单元以去除小于 50ns 的毛刺。当
16、相应的端口设置为 SCL与SDA引脚时,可以使能I/O 口内部的10K上拉电阻,这样可省掉外部的上拉电阻注意 :如果要作高速通讯或者从机数量较多,最好还是外接合适的上拉电阻比特率发生器单元TWI工作于主机模式时,比特率发生器控制时钟信号SCL的周期。具体由TWI状态寄存器TWSR勺预分频系数以及比特率寄存器TWBR设定。当TWI工作在从机模式时,不需要对比特率或预分频进行设定,但从机的CPU寸钟频率必须大于 TWI时钟线SCL频率的 16 倍。注意,从机可能会延长 SCL 低电平的时间,从而降低 TWI 总线的平均时钟周期。SCL的频率根据以下的公式产生:fSCL=fCPU/(16+2(TWB
17、R)(4TWPS)TWBR = TWI比特率寄存器的数值TWPS = TWI状态寄存器预分频的数值Note:TWI工作在主机模式时,TWBR直应该不小于10,否则主机会在SDA与SCL产生错误输出作为提示信号。 问题出现于 TWI 工作在主机模式下,向从机发送 Start + SLA + R/W 的时候 (不需要真的有从机与总线连接 )。控制单元控制单元监听TWI总线,并根据 TWI控制寄存器TWCR勺设置作出相应的响应。当TWI总线上产生需要应用程序干预处理的事件时,TWI中断标志位TWINT置位。在下一个时钟周期,TWI状态寄存器TWSR被表示这个事件的状态码字所更新。在其它时间里,TWS
18、R的内容为一个表示无事件发生的特殊状态字。一旦 TWINT 标志位置 1 ”,时钟线 SCL 即被拉低,暂停 TWI 总线上的数据传输,让用户程序处理事件。 在下列状况出现时, TWINT 标志位置位:?在TWI传送完START/REPEATED STAR信号之后?在TWI传送完SLA+R/W数据之后? 在 TWI 传送完地址字节之后? 在 TWI 总线仲裁失败之后? 在 TWI 被主机寻址之后 ( 广播方式或从机地址匹配 )? 在 TWI 接收到一个数据字节之后?作为从机工作时,TWI接收到STOP或REPEATED START!号之后?由于非法的START或STOP信号造成总线错误时TWI
19、 寄存器说明TWI 比特率寄存器 TWBR? Bits 7.0- TWI比特率寄存器TWBR为比特率发生器分频因子。比特率发生器是一个分频器,在主机模式下产生SCL时钟频率。比特率计算公式请见前面的 比特率发生器单元 TWI 控制寄存器 TWCRTWCF用来控制TWI操作。它用来使能TWI,通过施加START到总线上来启动主机访问,产生接收器应答,产生STOP状态,以及在写入数据到TWDR寄存器时控制总线的暂停等。这个寄存器还可以给出在 TWDR无法访问期间,试图将数据写入到TWDR而引起的写入冲突信息。? Bit 7- TWINT: TWI 中断标志当 TWI 完成当前工作,希望应用程序介入
20、时TWINT 置位。若SREG的I标志以及TWCF寄存器的TWIE标志也置位,则 MCU执行TWI中断例程。当TWINT置位时,SCL信号的低电平被延长。TWINT 标志的清零必须通过软件写 1 ” 来完成。 执行中断时硬件不会自动将其改写为 0”。 要注意的是,只要这一位被清零, TWI 立即开始工作。因此,在清零TWINT之前一定要首先完成对地址寄存器TWAR状态寄存器 TWSR以及数据寄存器 TWDR的访问。? Bit 6- TWEA:使能 TWI 应答TWEA标志控制应答脉冲的产生。若TWEA置位,出现如下条件时接口发出ACK脉冲:1. 器件的从机地址与主机发出的地址相符合2. TWA
21、R的TWGCE1位时接收到广播呼叫3. 在主机 / 从机接收模式下接收到一个字节的数据将TWEA清零可以使器件暂时脱离总线。置位后器件重新恢复地址识别。? Bit 5- TWSTA: TWI START 状态标志当CPU希望自己成为总线上的主机时需要置位TWSTATWI 硬件检测总线是否可用。 若总线空闲,接口就在总线上产生 START 状态。 若总线忙,接口就一直等待,直到检测到一个STOP状态,然后产生START以声明自己希望成为主机。发送START之后软件必须清零 TWSTA? Bit 4- TWST TWI STOP 状态标志在主机模式下,如果置位 TWSTO TWI接口将在总线上产生
22、 STOP状态,然后TWSTOI动清零。在从机模式下,置位 TWSTC可以使接口从错误状态恢复到未被寻址的状态。此时总线上不会有 STOP状态产生,但TWI返回一个定义好的未被寻址的从机模式且释放SCL与SDA为高阻态。? Bit 3- TWWC: TWI写碰撞标志当TWINT为低时写数据寄存器 TWDR将置位TWWC当TWINT为高时,每一次对 TWDR勺写访问都将更新此标志。? Bit 2- TWEN: TWI 使能TWEN位用于使能TWI操作与激活TWI接口。当TWEF位被写为1”时,TWI引脚将I/O引脚切换到SCL与SDA引脚,使能波形斜率限制器与尖峰滤波器。 如果该位清零, TWI
23、 接口模块将被关闭,所有 TWI 传输将被终止。? Bit 0- TWIE:使能 TWI 中断当SREG的I以及TWIE置位时,只要 TWINT为1 ”,TWI中断就激活。TWI 状态寄存器 TWSR? Bits 7.3- TWS: TWI 状态这 5 位用来反映 TWI 逻辑和总线的状态。 不同的状态代码将会在后面的部分描述。注意从TWSR卖出的值包括5位状态值与2位预分频值。检测状态位时设计者应屏蔽预分频位为 0 ”。这使状态检测独立于预分频器设置。? Bits 1.0- TWPS: TWI 预分频位这两位可卖 / 写,用于控制比特率预分频因子。预分频系数为 4 的 n 次方 计算比特率的
24、公式见前面的 比特率发生器单元 TWI 数据寄存器 TWDR在发送模式,TWDR包含了要发送的字节;在接收模式,TWDR包含了接收到的数据。当 TWI 接口没有进行移位工作 (TWINT 置位 ) 时这个寄存器是可写的。 在第一次中断发生之前用户不能够初始化数据寄存器。只要TWINT置位,TWDF的数据就是稳定的。 在数据移出时,总线上的数据同时移入寄存器。TWDR总是包含了总线上出现的最后一个字节,除非MCU是从掉电或省电模式被 TWI中断唤醒。此时 TWDR的内容没有定义。总线仲裁失败时,主机将切换为从机,但总线上出现的数据不会丢失。ACK 的处理由 TWI 逻辑自动管理, CPU 不能直
25、接访问 ACK。? Bits 7.0- TWD: TWI 数据寄存器根据状态的不同,其内容为要发送的下一个字节,或是接收到的数据。TWI(从机)地址寄存器TWARTWAR的高7位为从机地址。工作于从机模式时, TWI 将根据这个地址进行响应。 主机模式不需要此地址。在多主机系统中,TWAR需要进行设置以便其他主机访问自己。TWAR的LSB用于识别广播地址 (0x00)。 器件内有一个地址比较器。一旦接收到的地址和本机地址一致,芯片就请求中断。? Bits 7.1- TWA: TWI从机地址寄存器其值为从机地址。? Bit 0- TWGCE:使能TWI广播识另U置位后MCU可以识别TWI总线广播
26、。使用 TWIAVR的TWI接口是面向字节和基于中断的。START 信号等,都会产生一个 TWI 中断。所有的总线事件,如接收到一个字节或发送了一个由于 TWI 接口是基于中断的,因此TWI 接口在字节发送和接收过程中,不需要应用程序的干预。TWCF寄存器的TWI中断允许位TWIE和全局中断允许位I 一起决定了应用程序是否响应TWINT标志位产生的中断请求。如果 TWIE 被清零,应用程序只能采用轮询 TWINT 标志位的方法来检测 TWI 总线状态。当 TWINT 标志位置 1 ” 时,表示 TWI 接口完成了当前的操作,等待应用程序的响应。在这种情况下,TWI状态寄存器TWSR包含了表明当前 TWI总线状态的值。应用程序可以读取 TWCR的状态码,判别此时的状态是否正确,并通过设置TWCR与 TWDR寄存器,决定在下一个 TWI总线周期 TWI 接口应该如何工作。各种模式下的状态码列表(T
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
评论
0/150
提交评论