久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 2464|回復: 0
打印 上一主題 下一主題
收起左側

硬件和軟件兼容i2c協議的24Cxx系列EEPROM存儲器

[復制鏈接]
跳轉到指定樓層
樓主
ID:161768 發表于 2017-1-14 23:45 | 只看該作者 回帖獎勵 |倒序瀏覽 |閱讀模式
硬件上由于24c01的A0A1A2管腳不允許懸空,故暫時的想法是兼容24c02 ---24c16
使用一個dip8封裝的芯片插座,A0 A1 A2管腳都懸空即可,換芯片方便
軟件上24c02地址只有8位,而其他型號是大于8位的,故地址參數使用16位
256個字節作為一個大頁,即largePage,測試芯片24c04空間有512字節

上代碼,求測試和討論
  1. #include "MY51.H"
  2. //轉載請注明:  求測試討論
  3. //stc89c52rc,11.0592MHz晶振
  4. sbit sda=P2^0;                //總線連接口定義
  5. sbit scl=P2^1;                //總線連接口定義

  6. void delayus()                 //需要4個機器周期,大概4.34us
  7. {
  8.         ;                                //晶振頻率11.0592M,機器周期為1.085微秒
  9. }

  10. void iic_start()          //啟動信號
  11. {
  12.         sda=1;
  13.         scl=1;
  14.         delayus();                //sda和scl同為高電平保持4.7us以上
  15.         _nop_();                //1.085us,共5.78us
  16.         sda=0;                         //下降沿
  17.         delayus();                //sda低電平保持4us以上        ,這里是4.34us滿足要求
  18. }

  19. void iic_stop()                //停止信號
  20. {
  21.         sda=0;_nop_();        //準備狀態
  22.         scl=1;
  23.         delayus();                //該狀態穩定時間要求保持4us以上
  24.         sda=1;                        //scl高電平期間,sda來一個上升沿
  25.         delayus();                //sda保持4.7us以上,4.34加上函數返回時間大于4.7us
  26.                                         //注:此時scl和sda都為1        
  27. }

  28. void iic_sendByte(u8 byteData) //mcu發送一個字節
  29. {
  30.         u8 i;
  31.         u8 temp=byteData;
  32.         for(i=0;i<8;i++)
  33.         {
  34.                 temp=temp<<1;    //移動后最高位到了PSW寄存器的CY位中
  35.                 scl=0;                         //準備
  36.                 _nop_();                 //穩定一下
  37.                 sda=CY;                         //將待發送的數據一位位的放到sda上
  38.                 _nop_();
  39.                 scl=1;                     //每一個高電平期間,ic器件都會將數據取走
  40.                 _nop_();               
  41.         }

  42.         scl=0;                                 //如果寫成scl=1;sda=1就是停止信號,不能這么寫
  43.         _nop_();                                
  44.         sda=1;                                 //釋放總線,數據總線不用時要釋放
  45.         _nop_();
  46. }

  47. u8 iic_readByte()                         //讀一個字節
  48. {
  49.         u8 i,temp;
  50.         scl=0;                                        //準備讀數據
  51.         _nop_();
  52.         sda=1;                                        //釋放總線
  53.         _nop_();

  54.         for(i=0;i<8;i++)
  55.         {
  56.                 scl=1;                                //mcu開始取數據
  57.                 delayus();                        //scl為高電平后,ic器件就會將1位數據送到sda上
  58.                                                         //總共用時不會大于4.34us,然后就可以讓mcu讀sda了
  59.                 temp=(temp<<1)|sda; //讀一位保存到temp中
  60.                 scl=0;
  61.                 delayus();               
  62.         }
  63.         return temp;
  64. }

  65. bool iic_checkACK()                  //處理應答信號
  66. {
  67.         u8 errCounts=255;           //定義超時量為255次
  68.         scl=1;
  69.         _nop_();
  70.         
  71.         while(sda)                          //在一段時間內檢測到sda=0的話認為是應答信號
  72.         {        
  73.                 if(0==errCounts)
  74.                 {
  75.                         scl=0;                  //鉗住總線
  76.                         _nop_();
  77.                         return FALSE; //沒有應答信號
  78.                 }
  79.                 errCounts--;
  80.         }

  81.         scl=0;                             //鉗住總線,為下1次通信做準備
  82.         _nop_();
  83.         return TRUE;             //成功處理應答信號
  84. }

  85. void iic_init()                     //總線初始化
  86. {
  87.         scl=1;
  88.         sda=1;
  89.         delayus();
  90. }

  91. void iic_sendACK(bool b_ACK)  //發送應答或非應答信號
  92. {
  93.         scl=0;                        //準備
  94.         _nop_();

  95.         if(b_ACK)                //ACK        發送應該信號
  96.         {
  97.                 sda=0;
  98.         }
  99.         else                        //unACK        發送非應答信號
  100.         {
  101.                 sda=1;
  102.         }

  103.         _nop_();
  104.         scl=1;
  105.         delayus();                 //大于4us的延時
  106.         scl=0;                    //鉗住scl,以便繼續接收數據        
  107.         _nop_();
  108. }

  109. void AT24Cxx_writeByte(u16 address,u8 dataByte)//向24cxx寫一字節數據
  110. {
  111.         u8 largePage     = address/256;          //24c04是512字節(尋址范圍0~511),largePage最大值是1
  112.         u8 addressOffset = address%256;   //largePage=0的話地址范圍是(0~255)
  113.         iic_start();
  114.         iic_sendByte(0xa0|(largePage<<1));//控制字,前4位固定1010,后三位是器件地址,末位0是寫
  115.         iic_checkACK();                                      //mcu處理應答信號
  116.         iic_sendByte(addressOffset);            //指定要寫入的器件內地址在        largePage塊中的偏移
  117.         iic_checkACK();
  118.         iic_sendByte(dataByte);                   //寫數據
  119.         iic_checkACK();
  120.         iic_stop();
  121.         delayms(2);        
  122.         //按字節寫入時,24cxx在接收到停止信號后將數據擦寫到內部,這需要時間
  123.         //并且在這段時間內不會響應總線上的任何請求,故讓mcu有2毫秒以上的等待        
  124. }

  125. void AT24Cxx_writeData(u16 address,u8 numBytes,u8* buf)//寫入任意長度數據(最大256字節)
  126. {
  127.         while(numBytes--)
  128.         {
  129.                 AT24Cxx_writeByte(address++,*buf++);
  130.         }
  131. }

  132. void AT24Cxx_readData(u16 beginAddr,u8 dataSize,u8* buf)//讀取任意長度字節到緩沖區buf中
  133. {
  134.         u8 largePage     = beginAddr/256;        //計算largePage,256字節為一大頁
  135.         u8 addressOffset = beginAddr%256;        //計算相對于largePage的偏移
  136.         iic_start();                                                  //起始信號
  137.         iic_sendByte(0xa0|(largePage<<1));        //控制字,寫
  138.         iic_checkACK();                                                //處理應答信號
  139.         iic_sendByte(addressOffset);                //要讀取的目標地址偏移
  140.         iic_checkACK();                                                //處理應答信號        
  141.         iic_start();                                                   //發送起始信號
  142.         iic_sendByte(0xa1|(largePage<<1));        //控制字,讀
  143.         iic_checkACK();                                                //處理應答信號
  144.         while(dataSize--)                                        //讀取dataSize個字節,最大256個字節
  145.         {                                                                        //dataSize用u16類型會暴掉ram的
  146.                 *buf++=iic_readByte();                        //讀取一個個字節并保存到緩沖區buf中
  147.                 iic_sendACK(dataSize);                  //發送應答,當dataSize為0時mcu發送非應答
  148.         }
  149.         iic_stop();                                                        //發送停止信號
  150. }



  151. void main()//測試
  152. {
  153.         u8 buf[3];                                                                                //接受數據的緩沖區
  154.         u8 arr[7]={0x06,1,2,3,4,0x55,0x33};                                //待寫入的數據
  155.                                                 
  156.         iic_init();                                                                                //總線初始化
  157.         AT24Cxx_writeData(0x00+256,sizeof(arr),arr);        //向指定地址處開始寫入7字節的數據

  158.         P1=0xff;                                                                                 //調試代碼,用P1口的led顯示
  159.         delayms(1000);                                                                         //調試代碼

  160.         AT24Cxx_readData(0x00+256,sizeof(buf),buf);           //從指定地址開始讀3個字節
  161.         P1=buf[2];        //也就是2                                                                        //led燈顯示數值
  162.                                                                                        
  163.         while(1)
  164.         {
  165.                 P1=~P1;
  166.                 delayms(500);               
  167.         }
  168. }

復制代碼

  1. //my51.h中主要用到
  2. #include<reg52.h>

  3. #include"mytype.h"

  4. void delayms(u16 ms)     //軟延時函數
  5. {
  6.         u16 i,j;
  7.         for(i=ms;i>0;i--)
  8.         {
  9.         for(j=113;j>0;j--)
  10.         {}
  11.         }
  12. }
復制代碼
  1. 對代碼進行了改進
  2. 去掉了在寫數據時的
  3. delayms(2);
  4. 這句軟延時代碼低效 ,而且沒有保障

  5. 改成加一個檢測函數
  6. bool check_icWriteComplete()   //檢測eeprom是否對內部擦寫完成
  7. {
  8. iic_start();
  9. iic_sendByte(0xa0);
  10. return iic_checkACK();
  11. }
復制代碼


分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏1 分享淘帖 頂 踩
回復

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規則

手機版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術交流QQ群281945664

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 国产精品视频久久 | 亚洲电影一级片 | 国产人成精品一区二区三 | 日韩成人高清 | 国产精品视频一区二区三 | zzzwww在线看片免费 | 久久伊人在 | 欧美日韩亚洲一区 | 久久精品亚洲精品 | 中文字幕精品视频在线观看 | 免费黄色片在线观看 | 亚洲午夜av | 亚洲一二三区精品 | 自拍第1页| 久久久国产一区二区三区四区小说 | 亚洲国产精品久久久 | 亚洲成人免费网址 | 在线一区视频 | 亚洲天堂一区 | 欧美456 | 在线观看亚洲 | 久久国产精品视频 | 日本免费视频在线观看 | 成人性生交大片免费看r链接 | 国产免费一区二区三区 | 丝袜美腿一区二区三区动态图 | 国产区在线视频 | 日韩国产欧美一区 | 亚洲精选一区二区 | 黄色网址在线播放 | 青青久久av北条麻妃海外网 | 亚洲福利网 | 国产黄色一级片 | 草草视频在线观看 | 男女视频免费 | 色综合视频 | 免费成人av网站 | 免费a v网站 | 九色 在线 | 欧美成人a | 欧美激情在线播放 |