作为基础入门级的TX-1C开发板,里面有AT24C02芯片,在编写程序时很多童鞋无法顺利使用该芯片。
我作为初学者也是捣鼓了两天,在详细阅读了datasheet之后,终于明白症结所在,在这里和大家分享一下。
TX-1C的开发板,都已经焊接好电路,需要我们做的只是写一下驱动程序。
该芯片可以采用IIC总线进行操作。时序图请大家参照datasheet(附件),之前很多童鞋遇到时序图写对但是数据读写错误的问题。
我也遇到了,这里应该注意芯片每次字节写操作(byte write opeartion)完成后,需要10ms的延时,用于芯片内部把数据转化为不可擦除的。这段期间芯片对读写信号是不响应的。如果这段时间进行读数据操作,就会出现错误。
另外,对于AT24C02芯片,2Kbit的EEPROM,也就是256Byte的大小,数据地址从0x00-0xff。需要注意的是,这个芯片是每8byte是一页,一共32页,这个在字节写操作(byte write opeartion)里面没影响,但是如果你想连续进字节,就需要注意了(AT24C04及以上型号都是16byte一页)。在页写操作里面(page write opeartion),一次连续写只能写一页(8byte),只是因为芯片内部每写完一个字节,数据地址就自加1,但是写到这一页的结尾,指针就会调到这一页的开头,而不是跳到下一页的开头,如果继续写,就会覆盖前面的数据。写完这一页就要stop,在延时10ms,转化为不可擦除数据。之后,重新开始start,写下一页。这是非常需要注意的。
读操作没有这个问题,字节读取不需要延时10ms(读不需要不可擦除的转化),如果连续读也不存在页的问题,因为读完一个字节,地址指针会跳到下一个字节,从0x00一直到0xff(我想是因为在写操作的时候芯片需要转化为不可擦除的过程限制,芯片可能没有办法把0x00-0xff这么多字节一次性都转化为不可擦除的,所以才需要分页写)。
好了,要点已经讲完(以上都是在datasheet,write/read operation上看到的,如果没看明白可以参考原文),上代码了。
代码有点长,但是非常robust!!里面把ByteWrite,PageWrite,RandRead,SeqRead的代码都写进去,而且返回值是表示操作状态
0表示操作错误,1表示操作正确,Read出来的数据都存在了外部变量AT24C02_data[]数组里面,我定义的最大容量是30,大家可以根据需要自己更改。
经过封装以后可以直接作为AT24C02的驱动函数。
main函数是我写的测试函数,如果读写过程有错误会有很长的蜂鸣器,如果正确,每个周期后会有短促的蜂鸣。希望对大家有啊帮助。
单片机源码:
- #include <reg52.h>
- #include <intrins.h>
- #define MAXIUM 30
- #define uint unsigned int
- #define uchar unsigned char
-
- sbit SDA=P2^0;
- sbit SCL=P2^1;
- sbit beep=P2^3;
- uchar AT24C02_data[MAXIUM];
- void delay(uint ms){
- uint j,k;
- for(j=ms;j>0;j--)
- for(k=110;k>0;k--);
- }
- void nop(){
- _nop_();
- _nop_();
- }
- void AT24C02_Start(){
- SDA=1;
- nop();
- SCL=1;
- nop();
- SDA=0;
- nop();
- SCL=0;
- nop();
- }
- void AT24C02_Stop(){
- SDA=0;
- nop();
- SCL=1;
- nop();
- SDA=1;
- nop();
- SCL=0;
- nop();
- }
- void AT24C02_SendAck(){
- SDA=0;
- nop();
- SCL=1;
- nop();
- SCL=0;
- nop();
- SDA=1;
- nop();
- }
- uchar AT24C02_RecAck(){
- uchar i,flag;
- flag=0;
- i=0;
- SCL=1;
- nop();
- while((SDA==1)&&(i<255)) i++;
- if(i==255) flag=1;
- SCL=0;
- nop();
- return flag;
- }
- void AT24C02_Write(uchar dat){
- uchar i,temp;
- temp=dat;
- for(i=0;i<8;i++){
- temp=temp<<1;
- SDA=CY;
- nop();
- SCL=1;
- nop();
- SCL=0;
- nop();
- }
- SDA=1; nop();
- }
- uchar AT24C02_Read(){
- uchar i,temp;
- for(i=0;i<8;i++){
- SCL=1;
- nop();
- temp=(temp<<1)|SDA;
- SCL=0;
- nop();
- }
- return temp;
- }
- //Return data is the state(0 means fault, 1 means success);
- uchar AT24C02_ByteWrite(uchar add, uchar dat){
- uchar flag;
- flag=0;
- AT24C02_Start();
- AT24C02_Write(0xa0);
- if(!AT24C02_RecAck()){
- AT24C02_Write(add);
- if(!AT24C02_RecAck()){
- AT24C02_Write(dat);
- if(!AT24C02_RecAck()) flag=1;
- }
- }
- AT24C02_Stop();
- delay(10);
- return flag;
- }
- //data word add(0x00-0xff) must be divided by 8(32 in total);
- //*p points to 8 uchar array;
- //Return data is the state(0 means fault, 1 means success);
- uchar AT24C02_PageWrite(uchar add, uchar *dat){
- uchar flag;
- uchar i, *p;
- flag=0;
- p=dat;
- AT24C02_Start();
- AT24C02_Write(0xa0);
- if(!AT24C02_RecAck()){
- AT24C02_Write(add);
- if(!AT24C02_RecAck()){
- for(i=0;i<8;i++){
- AT24C02_Write(*(p+i));
- if(AT24C02_RecAck()) break;
- }
- if(i==8) flag=1;
- }
- }
- AT24C02_Stop();
- delay(10);
- return flag;
- }
- //Data is saved in external variable AT24C02_data[0];
- //Return data is the state(0 means fault, 1 means success);
- uchar AT24C02_RandRead(uchar add){
- uchar flag;
- flag=0;
- AT24C02_Start();
- AT24C02_Write(0xa0);
- if(!AT24C02_RecAck()){
- AT24C02_Write(add);
- if(!AT24C02_RecAck()){
- AT24C02_Start();
- AT24C02_Write(0xa1);
- if(!AT24C02_RecAck()){
- AT24C02_data[0]=AT24C02_Read();
- AT24C02_Stop();
- flag=1;
- }
- }
- }
- return flag;
- }
- //Data is saved in external variable AT24C02_data[0],maxium num is 30;
- //Return data is the state(0 means fault, 1 means success;
- uchar AT24C02_SeqRead(uchar add,uchar num){
- uchar i,flag;
- flag=0;
- AT24C02_Start();
- AT24C02_Write(0xa0);
- if(!AT24C02_RecAck()){
- AT24C02_Write(add);
- if(!AT24C02_RecAck()){
- AT24C02_Start();
- AT24C02_Write(0xa1);
- if(!AT24C02_RecAck()){
- for(i=0;i<num-1;i++){
- AT24C02_data[ i]=AT24C02_Read();
- AT24C02_SendAck();
- }
- AT24C02_data[ i]=AT24C02_Read();
- AT24C02_Stop();
- flag=1;
- }
- }
- }
- return flag;
- }
- void main(){
- uchar i;
- uchar array[8]={1,2,3,4,5,6,7,8};
-
- for(i=0;i<MAXIUM;i++) AT24C02_data[ i]=0;
- P1=0x00;
- delay(1000);
-
- if(AT24C02_ByteWrite(0x00,0xff)){
- if(!AT24C02_RandRead(0x00)){
- beep=0;
- delay(2000);
- beep=1;
- }
- }
- else{
- beep=0;
- delay(1000);
- beep=1;
- }
- P1=AT24C02_data[0];
- delay(1000);
-
- if(AT24C02_PageWrite(0x00,array)){
- if(!AT24C02_SeqRead(0x00,8)){
- beep=0;
- delay(2000);
- beep=1;
- }
- }
- else{
- beep=0;
- delay(1000);
- beep=1;
- }
- while(1){
- for(i=0;i<8;i++){
- P1=AT24C02_data[ i];
- delay(1000);
- }
- beep=0;
- delay(100);
- beep=1;
- }
- }
复制代码
|