TWI接口和TWI接口器件使用.doc_第1页
TWI接口和TWI接口器件使用.doc_第2页
TWI接口和TWI接口器件使用.doc_第3页
TWI接口和TWI接口器件使用.doc_第4页
TWI接口和TWI接口器件使用.doc_第5页
已阅读5页,还剩4页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

TWI接口和TWI接口器件使用AVR单片机的很多型号也具有两线制接口,即TWI接口。实际上TWI接口时序和常见的总线是兼容的。我们这本书结合讲的单片机Atmega16就有这种接口。这种接口的使用也十分广泛。比如本文会结合介绍的EEPROM AT24C64;MAXIM公司的温度传感器(查出型号);有的A/D转换器;菲利普还有专门的用这种总线的I/O扩展芯片。TWI电路接线简单,占用I/O,并且可以很多期间共享一个总线,使用比较方便,系统也很简洁。AVR单片机用硬件实现了这种总线的时序,省去了很多编程工作。同时支持一条总线多个主设备的通讯。我们只需要控制相关寄存器就能实现通过TWI传输数据。很大程度上减少了我们的工作量,从而使代码更简洁,开发更容易。下面我们会介绍的基本知识,AVR的TWI接口的功能和使用,给出一个用TWI接口读写接口的EEPROM的例子,最后给出适用于AVR-GCC编译器的示例程序。一、总线的基本知识总线的信号线有两条,一条是时钟线SCL,另一条是数据线SDA。总线连接起来的时候,需要两个上拉电阻,器件内部这两个信号引脚是集电极开路(或者是漏极开路)的。这样总线上的器件只要有一个输出低电平总线就会被拉低(实际上就是所谓线与的逻辑),这主要用于总线仲裁。1.在总线上,有几个状态表示特殊的总线信号。开始和停止信号时序如下图所示:图上可以看出,在SCL位高电平时SDA的变化将产生总线开始和停止信号。SDA从高电平跳变到低电平表示开始,从低电平跳变到高电平表示停止。数据的建立和有效:上图表示在传输数据时,SCL高电平的时候,SDA上的数据不能变化,因为前面已经说明,这是数据的变化将会认为是开始或者结束的信号。在SCL低电平时数据可以改变。2.主器件和从器件总线上可以有很多设备但是同时只能有一个主设备进行传输,从设备都有设备地址,当总线上的地址和从设备设置的地址一致时,传输在主设备和被寻址的从设备之间进行,其他设备相当于和总线分离。主设备产生SCL信号。当总线上有多个主设备试图传输不同的数据的时候,就会产生总线仲裁问题。3. 的寻址过程在总线上的数据传输,除了开始和停止之外,由于可以多个从设备共用总线还会有一个寻址过程。寻址过程通过主设备发送一定格式的寻址命令进行。寻址命令由起个位的从设备地址、一位读写标志和一位响应信号组成。七位的从设备地址可以由设计者任意设定,不过0000000是一个通用寻址地址。当主设备需要向所有的从设备传输同样的信息的时候,可以使用通用寻址地址,这时,总线上的所有设备拉低SDA线,响应这个命令。此后,主设备往总线上写的数据会被所有的相应这个寻址命令的从设备接收到。但是,一个通用的都命令是没有意义的,因为有可能不同的从设备会向总线传送不同的数据(电平),从而引起总线冲突。从设备地址11111xxx需要留给将来的应用。有的从设备进一步规定了寻址的格式。比如ATMEL公司24CXX系列的EEPROM就规定寻址的开始四位必须是1010。这是根据相应器件的说明书设置相应的地址就行了。读写控制位是1的时候执行读操作,是0的时候执行写操作。往总线传输时最高位(MSB)最先送出,最后是读写指令,当相应器件被寻址的时候,它会拉低SDA线,作为回应。如果没有器件被正确寻址,或者要寻址的器件忙,则SDA会保持高。这是主设备就会知道寻址没有成功,可以发送一个停止命令,或者重新开始命令。4. 的数据发送过程寻址以后就是数据发送过程。这时主设备负责产生时钟,发送开始和停止指令,接收设备需要接收到数据要发出回应。时钟的第九个周期如果SDA被拉低,表示接收回应,如果还是保持高,则表示没有回应。数据有八位,高位先传输。二、AVR单片机的TWI接口AVR单片机的提供了硬件实现总线时序的TWI接口,通过控制与此相关的特殊功能寄存器就能按照字节通过总线传输数据。接口功能的详细介绍可以参考相应型号单片机数据手册,下面我们就Atmega16做一下简要介绍。1. 1. SCL和SDA引脚两个管脚功能是和普通I/O复用的,当开始使用TWI接口传输数据的时候,硬件会覆盖原来对这两个和I/O的设置,自己控制输入输出的方向。由于总线是需要上拉电阻的,AVR单片机这时允许内部上拉电阻有效,从而可以省去两个外部电阻。同时引脚的输入部分有毛刺去除电路,输出有斜率限制。2. 2. 波特率设置当TWI工作在主模式下的时候,AVR单片机产生时钟信号驱动时钟线SCL。时钟的周期由TWI的状态寄存器TWSR的预分频位和TWI的波特率寄存器TWBR决定。当TWI工作于从模式下时,不需要对波特率进行设置,不过系统的时钟必须大于TWI时钟线SCL频率的16倍。下面是SCL频率和寄存器相应设置的关系的式子:其中, 就是SCL的频率,是系统的时钟,TWBR为TWI接口波特率寄存器的值(八位二进制数表示的数值),TWPS表示TWI接口状态寄存器预分频为的值。需要注意的是,在AVR单片机工作于主模式时,TWPS的值要大于10,否则有可能产生不正确的输出。3. 3. 单片机的从设备地址AVR单片机作为从设备的时候,需要一个从设备地址。这个地址设置在从设备地址寄存器TWAR即可。TWAR的最低位TWGCE,是选择是否识别通用寻址地址的,如果置为1,则在收到通用寻址指令时也会作出回应。4. 4. TWI接口相关中断在TWI接口完成了当前任务,需要软件响应的时候会把TWTNT置为1。如果单片机中断允许,并且TWCR的TWIE为1,就会产生相应中断。需要注意的是,中断服务程序执行后硬件不会自动把TWINT位置0,必须通过软件向该位写1来清零。每次清零TWINT位意味着一次新的总线操作开始,所以在清零以前要保证访问TWAR和TWSR,以及TWDR的操作已经完成。三、AVR单片机TWI接口的使用由于有了硬件的接口电路,我们不需要关系线上的时序了,不过使用中还要遵循总线规范。有一些要注意的问题。这一部分,介绍使用TWI接口发送总线信号的方法,给出简单的程序。1. 1. 发送开始信号主设备对总线的合法操作都从发送开始命令开始。下面给出发送开始命令的程序:TWCR = _BV(TWINT) | _BV(TWSTA) | _BV(TWEN); /* 发送开始命令0 */while (TWCR & _BV(TWINT) = 0) ; /* 等待传送完毕*/首先将TWINT清零,接着程序向TWI控制寄存器的TWSTA位写1,如果总线空闲TWI就会往总线发送一个开始命令。否则,会等到总线上有一个停止信号的时候发送开始信号。TWEN是接口允许控制位,置1表示接口允许,这是TWI接口控制SCL和SDA管脚。传送开始信号以后要等待传送完毕才进行后面的操作。2. 2. 发送停止信号下面是发送停止信号的语句:TWCR = _BV(TWINT) | _BV(TWSTO) | _BV(TWEN); /* 发送停止信号 */TWINT和TWEN的设置和前面一样。在AVR单片机工作于主模式下,TWCR中的TWSTO位置1的时候,会在总线上产生一个停止信号。在从模式下,TWSTO置1,会使总线从错误状态恢复。3. 3. 发送数据这里所说的数据,可以是寻址命令,也可以是要发送的数据。下面是发送一个字节数据的代码:TWDR = data;/* 数据写入TWI接口数据寄存器TWDR */TWCR = _BV(TWINT) | _BV(TWEN); /* 清零中断标志,开始传输 */while (TWCR & _BV(TWINT) = 0) ; /* 等待传输完毕*/TWDR就是TWI接口的数据寄存器,TWI接口要发送的数据先写入这个寄存器,接收到的数据从这个寄存器读出。4. 4. 检查传输状态TWI对总线进行操作以后,可以返回这次操作完成的状态。比如发送了开始信号,TWI接口就会返回,总线是否正确进入开始状态。程序中可以检查这些状态,以确保每次操作正确进行,并对异常状态进行处理。TWSR的高五位就是TWI的状态位。相应的状态在AVR单片机的数据手册中都有详细的说明。在AVR-GCC编译器的包含文件中有一个twi.h对这些状态定义了相应的宏。这里我们不再详细列出所有状态,给出一个带状态检查的程序:begin: TWCR = _BV(TWINT) | _BV(TWSTA) | _BV(TWEN); /* 发送开始信号 */ while (TWCR & _BV(TWINT) = 0) ; /* 等待发送完成 */ switch (twst = TW_STATUS) case TW_START: break;case TW_MT_ARB_LOST: goto begin; default: return -1;/接着是下一步操作的代码程序中的TW_START就是一个宏表示开始状态,TW_MT_ARB_LOST表示主模式总线仲裁失败。这些定义参考头文件twi.h。程序的功能就是如果总线处于开始状态继续下一步操作,如果是总线仲裁失败,重新发送开始信号,如果出现错误,返回错误标志。以上分别介绍了TWI接口基本操作的使用,但是在操作实际器件的时候必须是这些操作组合起来进行,所以我们下面给出一个通过AVR单片机读写总线接口的EEPROM的例子,通过这个例子说明整个使用过程并给出相应示例程序。四、用AVR单片机的TWI接口读写EEPROM这是一个用TWI接口读写AT24C64的例子。通过这个例子我们会说明TWI接口使用的整个过程。1. 1. EEPROM芯片简单介绍AT24C64是ATMEL公司生产的EEPROM。它共有64K位,按照字节寻址。下面是它的管脚图和管脚功能的列表。A2A1A0是用来设置从设备地址的,这就意味着,可以有八个这样的器件共享一条总线。外部不连接的地址位缺省为0。2. 2. 器件寻址和读写时序a. a. 器件寻址操作EEPROM的时候先要寻址希望访问的器件。寻址命令的结构和前面描述的是一样的不过,前四个字节必须是1010后面三个才是有效的器件地址。如果器件被正确寻址会输出0作为响应,否则进入空闲状态。下面是一个说明寻址命令结构的图:当然器件寻址的操作一般不会单独进行,前面要有开始信号,后面将是读写操作。b. b. 读时序上面的图说明了,从EEPROM中读一个字节的时序。先是开始信号,然后是器件寻址操作,接着是两个字节要读的字节的地址。这些发送完毕以后,主设备要重新发送开始信号,再进行器件寻址操作,随后就会读出指定地址的数据。需要注意的是,在发送地址时的器件寻址操作,读写控制位置为写状态,在后一个器件寻址操作时,读写控制位置为读。读出一个字节后如果不发送停止信号,可以继续读出下一个字节,依此类推,知道读到对后一个地址,又会从零地址开始读出数据。c. c. 写时序下图是写操作的示意图.可以看出写操作比读简单一些。发送开始信号后,只需要一次器件寻址,读写控制置为写状态,接着发送要写入数据的地址,然后就是要写入的数据。如果只需要写入一个字节,传输完一个字节数据后发送停止信号就完成了一次写操作。不过24C64具有按页写的功能,每页64个字节,所以写完一个字节后还可以最多写入63个字节的数据。地址的高位保持不变。低五位会自动加1。如果总数超过了一页的地址,会把多写入的字节写入这一页的开头去。3. 3. 示例程序下面我们就给出使用TWI接口读写EEPROM的示例程序。通过这个程序大家应该比较清楚TWI的使用了。程序中做了相应注释,不再详细解释每一行代码。(是否给出流程图?)a. a. 从EEPROM中读取数据的程序程序的功能是从地址eeaddr 读取len字节到buf指向的数组,完成后返回读出的实际字节数。int ee2464_read_bytes(uint16_t eeaddr, int len, uint8_t *buf) uint8_t sla, twcr, n = 0; int rv = 0; /假设设备地址为000 sla = TWI_SLA_24C64 ; restart: if (n+ = MAX_ITER)/*最大尝试次数,错过则认为错误*/ return -1; begin: TWCR = _BV(TWINT) | _BV(TWSTA) | _BV(TWEN); /* 发送开始信号 */ while (TWCR & _BV(TWINT) = 0) ; /* 等待发送完毕*/ switch (twst = TW_STATUS) case TW_REP_START:/* 判断状态,如果正确继续下面的操作 */ case TW_START: break;case TW_MT_ARB_LOST: goto begin; default:return -1; /* 发送 SLA+W */ TWDR = sla | TW_WRITE; TWCR = _BV(TWINT) | _BV(TWEN); /* 清零TWINT,开始传输 */ while (TWCR & _BV(TWINT) = 0) ; /* 等待传输完毕 */ switch (twst = TW_STATUS) case TW_MT_SLA_ACK: break; case TW_MT_SLA_NACK:/*器件忙,有可能处于内部写周期 */ goto restart;case TW_MT_ARB_LOST: goto begin; default:goto error; TWDR = eeaddr8;/* 传输地址高八位 */ TWCR = _BV(TWINT) | _BV(TWEN); /* 清零TWINT位,开始传输 */ while (TWCR & _BV(TWINT) = 0) ; /*等待传输完毕*/ switch (twst = TW_STATUS) case TW_MT_DATA_ACK: break; case TW_MT_DATA_NACK: goto quit; case TW_MT_ARB_LOST: goto begin; default:goto error; TWDR = eeaddr;/* 发送地址低八位 */ TWCR = _BV(TWINT) | _BV(TWEN); /*清零TWINT位,开始传输*/ while (TWCR & _BV(TWINT) = 0) ; /*等待传输完毕*/ switch (twst = TW_STATUS) case TW_MT_DATA_ACK: break; case TW_MT_DATA_NACK: goto quit; case TW_MT_ARB_LOST: goto begin; default:goto error; TWCR = _BV(TWINT) | _BV(TWSTA) | _BV(TWEN); /* 发送(重新)开始信号*/ while (TWCR & _BV(TWINT) = 0) ; /*等待传输完毕 */ switch (twst = TW_STATUS) case TW_START:/*也允许,不过不可能出现*/case TW_REP_START:/*正确的状态*/ break; case TW_MT_ARB_LOST: goto begin; default: goto error; /* 发送 SLA+R */ TWDR = sla | TW_READ; TWCR = _BV(TWINT) | _BV(TWEN); /* 清中断开始发送 */ while (TWCR & _BV(TWINT) = 0) ; /* 等待发送完毕*/ switch (twst = TW_STATUS) case TW_MR_SLA_ACK: break; case TW_MR_SLA_NACK: goto quit; case TW_MR_ARB_LOST: goto begin; default: goto error; for (twcr = _BV(TWINT) | _BV(TWEN) | _BV(TWEA) ;/*收到数据发送应答信号*/ len 0; len-) if (len = 1)twcr = _BV(TWINT) | _BV(TWEN); /* 这次发送 NAK */ TWCR = twcr;/* 清中断开始传输 */ while (TWCR & _BV(TWINT) = 0) ; /*等待发送完成 */ switch (twst = TW_STATUS)case TW_MR_DATA_NACK: len = 0;/* 结束循环 */case TW_MR_DATA_ACK: *buf+ = TWDR; rv+; break;default: goto error; quit: TWCR = _BV(TWINT) | _BV(TWSTO) | _BV(TWEN); /* 发送停止信号 */ return rv; error: rv = -1; goto quit;b. b. 按页写若干字节到EEPROM的程序程序的功能是把buf指向的len字节数据写入EEPROM的eeaddr地址。完成后返回实际写入的字节数。int ee2464_write_page(uint16_t eeaddr, int len, uint8_t *buf) uint8_t sla, n = 0; int rv = 0; uint16_t endaddr; if (eeaddr + len = MAX_ITER) return -1; begin: TWCR = _BV(TWINT) | _BV(TWSTA) | _BV(TWEN); /* 发送开始信号 */ while (TWCR & _BV(TWINT) = 0) ; /* 等待传输完成 */ switch (twst = TW_STATUS) case TW_REP_START: case TW_START: break; case TW_MT_ARB_LOST: goto begin; default:return -1; /* 发送SLA+W */ TWDR = sla | TW_WRITE; TWCR = _BV(TWINT) | _BV(TWEN); /* 清中断开始传输 */ while (TWCR & _BV(TWINT) = 0) ; /* 等待传输完成 */ switch (twst = TW_STATUS) case TW_MT_SLA_ACK: break; case TW_MT_SLA_NACK:/*器件忙,可能处于内部写周期 */ goto restart;case TW_MT_ARB_LOST: goto begin; defa

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论