單片機+AT24C256的讀寫程式1

來源:互聯網
上載者:User

     一個通用的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 <intrins.h>#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 <REG52.H>#include "24c256_1.h"#include<string.h>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 Uartvoid printu(char * str){    char *ct = str;while (*ct != '\0'){if (*ct == '\n'){SBUF = 13;while (!TI);TI = 0;}SBUF=*ct;while (!TI);TI = 0;ct++;}}//UART初始化void initUart(void){TMOD &=0x0f; TMOD |=0x20; SCON=0x50; IP = 0x10;//PCON|=0x80;TH1=0xf7; TL1=0xf7; //115200,normal//TH1=0xfa; TL1=0xfa; //倍速 TR1=1; ET1=0; RI=0; //AUXR = 0xA0;//TE=0; //允許接收 僅485時用。}void main(void){  unsigned char Control,*p1,*p2;  unsigned char Length;  unsigned int addr ,i; /* 24Cxx片內地址 */    P4SW|= 0x10; initUart();ES =1;ET1=0;EA =1;senddd('O');senddd('N');     printu(" starting...\r\n");  p1=buf1;p2=buf2;  printu(p1);      printu("\r\n");   addr=0; ////片內地址 AT24C256為0~32767/////  Length=10; ////// 讀寫長度 //////  enumer=AT24256; /// 讀寫AT24C256////  Control=0xa0; /// 寫操作///  RW24xx(p1,Length,addr,Control,enumer); // 寫 //  Control=0xa1; ///讀操作///  for(i=0;i<10000;i++);   //要加入延時···才可正確的讀取資料!    // Delay(1000);//1:6.18us; 2:8.36us 3:10.55us △=2.18us  RW24xx(p2,Length,addr,Control,enumer);// 讀   printu(p2);  printu("\r\n");}

下面是運行結果:


聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.