MICROCHIP公司的PIC16系列
单片机以其精简的指令和较强的端口驱动能力在各个领域得到广泛的应用。在需要储存较大数量数据的控制领域,24C02可以解决PIC16C8×系列单片机片内EEPROM不足的问题,用以保存诸如用户设置参数、采集到的数据等。
由于部分PIC单片机不具备I2C总线接口,在应用时必须用软件法加以解决。
在软件编制时应当严格遵循I2C总线规则,并注意24C02的片内读写周期时间,调整好程序流程,以避免写不进、读不出的问题。
下面将笔者在实际工作中遇到的问题和解决的方法进行简单的介绍,希望可以给同行一些帮助。
首先约定,数据由微处理器发送到24C02称“写”、“发”,反之称“读”、“收”。24C02支持顺序读写和随机读写,文中以随机读写方式为例进行介绍。
一、硬件电路(如图1所示)。
使用微处理的任意两个通用I/O端口(图中用RA2、RA3)作为与24C02的连接,其中一个作为时钟SCL线,另外一个作为数据SAD线。两个端口均接22kΩ上拉电阻。
二、软件设计
首先简要介绍一下用EEPROM的I2C总线的规则。
初始状态时,SCL、SDA两线都为高。
当SCL为高电平时,如果SDA线跌落,认为是“起始位”。
当SCL为高电平时,如果SDA线上升,认为是“停止位”。
除此之外,在发送数据的过程中当SCL为高电平时,SDA应保持稳定。
ACK应答位指在此时钟周期内由从器件(EEPROM)把SDA拉低,表示回应。这时主器件(PIC16微处理器)的SDA口的属性应该变为输入以便检测。
1.在写数据周期应该依次执行以下过程:
1)发“起始位”。2)发“写入代码”(8bit),1010(A1A2A3)0,其中的A1、A2、A3三位是片地址,由24C02的硬件决定,文中采用000。3)收“ACK”应答(1bit)。4)发EEPROM片内地址(即要写入EEPROM的什么位置)(8bit)。从00到FF中的任意一个,对应EEPROM中的相应位。5)收“ACK”应答(1bit)。6)发要发送的数据(8bit),即要存储到EEPROM中的数据。7)发“停止位”。
接下来,如图2所示,进入轮询程序以便检验24C02片内写周期是否完成。如果已经完成则进入下一个字节的写操作过程。如果没有完成则继续等待,直到完成。
2.在读数据周期,依次执行以下过程:
1)发“起始位”。2)发“写入代码”(8bit),1010(A1A2A3)0,其中A1、A2、A3三位是片地址,由24C02的硬件决定,文中采用000。3)收“ACK”应答(1bit)。4)发“EEPROM”片内地址(即要读出EEPROM的位置)(8bit)。从00到FF中的任意一个,对应EEPROM中的相应位。5)收“ACK”应答(1bit)。6)发“起始位”(1bit)。7)发“读出代码”(8bit),1010(A1A2A3)1,其中A1、A2、A3三位是片地址,由24C02的硬件接线决定,文中采用000。8)接收。9)发ACK应答。10)发“停止位”。
要特别注意的两个问题是:1)24C02有一个约10ms的片内写周期。在这个周期内,24C02是不对外界的操作作出反应的。2)在发送数据的过程中,要确保当SCL为高电平时,SDA保持稳定。
解决第一个问题的常见方法有两个,其一为采用延时等待,确保在写过程中,在一个字节完成发送了停止位之后,微处理器等待足够的时间,通常应该超过10ms,再送下一个字节,这段时间用来等待EEPROM完成片内写周期。另一个是采用轮询的方式,判断EEPROM是否完成了片内写周期。这种方式的主导思想是,当向EEPROM发送写标志后,正常情况下,EEPROM应该有ACK应答。但是当EEPROM在进行片内写周期的时候,则不会产生这样的应答。程序据此判断,EEPROM是否完成了片内的写周期程序。如果完成,则可以继续写入下一个要写的内容,否则继续等待。
第一种方法编程较为简单,但是会浪费大量的机器时间,并且程序的延时时间不好确定。第二种方法的优点在于,虽然编程较为复杂,但是较为快速,对其余的程序模块影响较少,便于完成程序的模块化设计。
对于在发送数据的过程中,要确保当SCK为高电平时,SDA必须保持稳定,应该在程序中利用软件给予保证。
如果可以很好的解决以上两个问题,数据的写入和读出是方便快捷和可靠的。