一個通用的24C01-24C256共9種EEPROM的字節讀寫操作程序,此程序有五個入口條件,分別為讀寫數據緩沖區指針,進行讀寫的字節數,EEPROM首址,EEPROM控制字節,以及EEPROM類型。此程序結構性良好,具有極好的容錯性,程序機器碼也不多:DataBuff為讀寫數據輸入/輸出緩沖區的首址Length 為要讀寫數據的字節數量Addr 為EEPROM的片內地址 AT24256為0~32767Control 為EEPROM的控制字節,具體形式為(1)(0)(1)(0)(A2)(A1)(A0)(R/W),其中R/W=1,表示讀操作,R/W=0為寫操作,A2,A1,A0為EEPROM的頁選或片選地址;enumer為枚舉變量,需為AT2401至AT24256中的一種,分別對應AT24C01至AT24C256;函數返回值為一個位變量,若返回1表示此次操作失效,0表示操作成功;ERROR為允許最大次數,若出現ERRORCOUNT次操作失效后,則函數中止操作,并返回1。SDA和SCL由用戶自定義,對于1K位,2K位,4K位,8K位,16K位芯片采用一個8位長的字節地址碼,對于32K位以上的采用2個8位長的字節地址碼直接尋址,而4K位,8K位,16K位配合頁面地址來尋址。
#include #define ERROR 10 //允許ERROR的最大次數 sbit SDA=P4^2; sbit SCL=P4^4; enum eepromtype {AT2401,AT2402,AT2404,AT2408,AT2416,AT2432,AT2464,AT24128,AT24256};/*器件的型號*/ enum eepromtype enumer; //定義一個枚舉變量 unsigned char buf1[]="aaaaaaaaaa"; /* 發送緩沖區 */ unsigned char buf2 [12]; /* 接收緩沖區 */ void senddd(unsigned d1); /* * * * * * * * 一個簡單延時程序 * * * * * * * * * * * * */ void Delay(unsigned char DelayCount) { while(DelayCount--); } /* * * * * 以下是對IIC總線的操作子程序 * * * * */ /* * * * * * 啟動總線 * * * * */ void Start(void) { SCL=0; /* SCL處于高電平時,SDA從高電平轉向低電平表示 */ SDA=1; /* 一個"開始"狀態,該狀態必須在其他命令之前執行 */ Delay(1); SCL=1; Delay(1); SDA=0; Delay(1); SCL=0; SDA=1; Delay(1); } /* * * * * 停止IIC總線 * * * * */ void Stop(void) { SCL=0; /*SCL處于高電平時,SDA從低電平轉向高電平 */ SDA=0; /*表示一個"停止"狀態,該狀態終止所有通訊 */ Delay(1); SCL=1; Delay(1); /* 空操作 */ SDA=1; Delay(1); SCL=0; Delay(1000); } /* * * * * 檢查應答位 * * * * */ bit RecAck(void) { SCL=0; SDA=1; Delay(20); SCL=1; Delay(1); Delay(1); CY=SDA; /* 因為返回值總是放在CY中的 */ SCL=0; Delay(20); return(CY); } /* * * * *對IIC總線產生應答 * * * * */ void Ack(void) { SDA=0; /* EEPROM通過在收到每個地址或數據之后, */ SCL=1; /* 置SDA低電平的方式確認表示收到讀SDA口狀態 */ Delay(1); SCL=0; Delay(1); SDA=1; } /* * * * * * * * * 不對IIC總線產生應答 * * * * */ void NoAck(void) { SDA=1; SCL=1; Delay(1); SCL=0; } /* * * * * * * * * 向IIC總線寫數據 * * * * */ void Send(unsigned char sendbyte) { unsigned char data j=8; for(;j>0;j--) { SCL=0; sendbyte <<= 1; /* 使CY=sendbyte^7; */ SDA=CY; /* CY 進位標志位 */ Delay(1); SCL=1; Delay(20); } SCL=0; Delay(1); } /* * * * * * * * * 從IIC總線上讀數據子程序 * * * * */ unsigned char Receive(void) { register receivebyte,i=8; SCL=0; while(i--) { SCL=1; receivebyte = (receivebyte <<1 ) | SDA; Delay(1); SCL=0; Delay(1); } return(receivebyte); } /* ----- AT24C01~AT24C256 的讀寫程序 ------ */ bit RW24xx(unsigned char *DataBuff,unsigned char Length,unsigned int Addr, unsigned char Control,enum eepromtype enumer) { unsigned char data j,i=ERROR; bit errorflag=1; /* 出錯標志 */ while(i--) { Start(); /* 啟動總線 */ Send(Control & 0xfe); /* 向IIC總線寫數據,器件地址 */ if(RecAck()) continue; /* 如寫不正確結束本次循環 */ if(enumer > AT2416) { Send((unsigned char)(Addr >> 8));//把整型數據轉換為字符型數據:棄高取低,只取低8位.如果容量大于32K位,使用16位地址尋址,寫入高八位地址 if(RecAck()) continue; } Send((unsigned char)Addr); /* 向IIC總線寫數據 */ if(RecAck()) continue; /* 如寫正確結束本次循環 */ if(!(Control & 0x01)) //判斷是讀器件還是寫器件 { j=Length; errorflag=0; /* 清錯誤特征位 */ while(j--) { Send(*DataBuff++); /* 向IIC總線寫數據 */ if(!RecAck()) continue; /* 如寫正確結束本次循環 */ errorflag=1; break; } if(errorflag==1) continue; break; } else { Start(); /* 啟動總線 */ Send(Control); /* 向IIC總線寫數據 */ if(RecAck()) continue;//器件沒應答結束本次本層循環 while(--Length) /* 字節長為0結束 */ { *DataBuff ++= Receive(); Ack(); /* 對IIC總線產生應答 */ } *DataBuff=Receive(); /* 讀最后一個字節 */ NoAck(); /* 不對IIC總線產生應答 */ errorflag=0; break; } } Stop(); /* 停止IIC總線 */ if(!(Control & 0x01)) { Delay(255); Delay(255); Delay(255); } return(errorflag); } 下面是主函數: #include #include "24c256_1.h" #include unsigned char temp[64]; unsigned char rxnum; unsigned char flag2; void senddd(unsigned d1); void uart(void) interrupt 4// 串口中斷 { unsigned char k = 0; if(RI) //接收 { } else //發送 { TI=0; } } //查詢方式發送單個字符 void senddd(unsigned d1) { ES=0; //TE=1; TI=0;SBUF=d1;while(!TI); //TE=0; TI=0; ES=1; } //Send String Tor Uart void printu(char * str) { char *ct = str; while (*ct != '
主站蜘蛛池模板:
临桂县|
新蔡县|
阿荣旗|
磐石市|
昔阳县|
抚州市|
班戈县|
汕尾市|
贵定县|
共和县|
灵璧县|
博爱县|
永州市|
博罗县|
德格县|
达日县|
华阴市|
合作市|
历史|
双辽市|
新昌县|
徐汇区|
光泽县|
新密市|
寿宁县|
乌兰察布市|
长宁区|
佛教|
措勤县|
大兴区|
大化|
时尚|
沙雅县|
宝鸡市|
黑水县|
张家界市|
霞浦县|
安新县|
柞水县|
昂仁县|
垫江县|