作為基礎(chǔ)入門級(jí)的TX-1C開發(fā)板,里面有AT24C02芯片,在編寫程序時(shí)很多童鞋無法順利使用該芯片。
我作為初學(xué)者也是搗鼓了兩天,在詳細(xì)閱讀了datasheet之后,終于明白癥結(jié)所在,在這里和大家分享一下。
TX-1C的開發(fā)板,都已經(jīng)焊接好電路,需要我們做的只是寫一下驅(qū)動(dòng)程序。
該芯片可以采用IIC總線進(jìn)行操作。時(shí)序圖請(qǐng)大家參照datasheet(附件),之前很多童鞋遇到時(shí)序圖寫對(duì)但是數(shù)據(jù)讀寫錯(cuò)誤的問題。
我也遇到了,這里應(yīng)該注意芯片每次字節(jié)寫操作(byte write opeartion)完成后,需要10ms的延時(shí),用于芯片內(nèi)部把數(shù)據(jù)轉(zhuǎn)化為不可擦除的。這段期間芯片對(duì)讀寫信號(hào)是不響應(yīng)的。如果這段時(shí)間進(jìn)行讀數(shù)據(jù)操作,就會(huì)出現(xiàn)錯(cuò)誤。
另外,對(duì)于AT24C02芯片,2Kbit的EEPROM,也就是256Byte的大小,數(shù)據(jù)地址從0x00-0xff。需要注意的是,這個(gè)芯片是每8byte是一頁,一共32頁,這個(gè)在字節(jié)寫操作(byte write opeartion)里面沒影響,但是如果你想連續(xù)進(jìn)字節(jié),就需要注意了(AT24C04及以上型號(hào)都是16byte一頁)。在頁寫操作里面(page write opeartion),一次連續(xù)寫只能寫一頁(8byte),只是因?yàn)樾酒瑑?nèi)部每寫完一個(gè)字節(jié),數(shù)據(jù)地址就自加1,但是寫到這一頁的結(jié)尾,指針就會(huì)調(diào)到這一頁的開頭,而不是跳到下一頁的開頭,如果繼續(xù)寫,就會(huì)覆蓋前面的數(shù)據(jù)。寫完這一頁就要stop,在延時(shí)10ms,轉(zhuǎn)化為不可擦除數(shù)據(jù)。之后,重新開始start,寫下一頁。這是非常需要注意的。
讀操作沒有這個(gè)問題,字節(jié)讀取不需要延時(shí)10ms(讀不需要不可擦除的轉(zhuǎn)化),如果連續(xù)讀也不存在頁的問題,因?yàn)樽x完一個(gè)字節(jié),地址指針會(huì)跳到下一個(gè)字節(jié),從0x00一直到0xff(我想是因?yàn)樵趯懖僮鞯臅r(shí)候芯片需要轉(zhuǎn)化為不可擦除的過程限制,芯片可能沒有辦法把0x00-0xff這么多字節(jié)一次性都轉(zhuǎn)化為不可擦除的,所以才需要分頁寫)。
好了,要點(diǎn)已經(jīng)講完(以上都是在datasheet,write/read operation上看到的,如果沒看明白可以參考原文),上代碼了。
代碼有點(diǎn)長(zhǎng),但是非常robust!!里面把ByteWrite,PageWrite,RandRead,SeqRead的代碼都寫進(jìn)去,而且返回值是表示操作狀態(tài)
0表示操作錯(cuò)誤,1表示操作正確,Read出來的數(shù)據(jù)都存在了外部變量AT24C02_data[]數(shù)組里面,我定義的最大容量是30,大家可以根據(jù)需要自己更改。
經(jīng)過封裝以后可以直接作為AT24C02的驅(qū)動(dòng)函數(shù)。
main函數(shù)是我寫的測(cè)試函數(shù),如果讀寫過程有錯(cuò)誤會(huì)有很長(zhǎng)的蜂鳴器,如果正確,每個(gè)周期后會(huì)有短促的蜂鳴。希望對(duì)大家有啊幫助。
單片機(jī)源碼:
- #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;
- }
- }
復(fù)制代碼
資料下載:
00_AT24C02A.pdf
(184.52 KB, 下載次數(shù): 11)
2018-5-6 12:45 上傳
點(diǎn)擊文件名下載附件
下載積分: 黑幣 -5
|