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

 找回密碼
 立即注冊(cè)

QQ登錄

只需一步,快速開始

搜索
查看: 12532|回復(fù): 3
打印 上一主題 下一主題
收起左側(cè)

51單片機(jī)學(xué)習(xí):模擬iic總線連續(xù)讀寫24c02存儲(chǔ)器

[復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
AT24C02A, 2K SERIAL EEPROM:
Internally organized with 32 pages of 8 bytes each,
the 2K requires an 8-bit data word address for random word addressing.

24c02有32個(gè)頁(yè),每頁(yè)8字節(jié),本帖中不討論頁(yè)寫的方式
-------------------------------------------------------------------






AT24C02內(nèi)部設(shè)有一個(gè)8位控制寄存器,其每一位的含義如下:
Bit7 Bit6 Bit5 Bit4 Bit3 Bit2 Bit1 Bit0
1      0     1    0    A2   A1   A0  R/W
其中前4位數(shù)據(jù)是芯片固定的標(biāo)識(shí),
A2/A1/A0用于選擇總線上待訪問(wèn)的I2C器件,R/W=1讀操作,R/W=0寫操作;
I2C總線上最多可以擴(kuò)展8片同樣的2K容量EEPROM存儲(chǔ)器,
或者是4片4Kb的EEPROM,
或者是2片容量為8Kb的EEPROM存儲(chǔ)器。
或者是1片容量為16Kb的EEPROM存儲(chǔ)器(此時(shí)硬件就固定了,因?yàn)锳2/A1/A0已經(jīng)被P2P1P0占用),
如果擴(kuò)展8片2K以內(nèi)容量的EEPROM存儲(chǔ)器,每片存儲(chǔ)器將對(duì)應(yīng)一個(gè)地址,
我們的實(shí)驗(yàn)板上的AT24C02的A2/A1/A0引腳全部接地,
所以在實(shí)驗(yàn)中讀寫控制字分別為:0xa1/0xa0


主芯片stc89c52rc,晶振11.0592M

  1. #include<reg52.h>
  2. #include"MY51.H"

  3. sbit sda=P2^0;                //總線連接口定義
  4. sbit scl=P2^1;                //總線連接口定義

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

  9. void iic_start()  //啟動(dòng)信號(hào)
  10. {
  11.         sda=1;
  12.         scl=1;
  13.         delayus();                //sda和scl同為高電平保持4.7us以上
  14.         _nop_();                        //1.085us,共5.78us,下面sda=0是下降沿,不能計(jì)算在延時(shí)時(shí)間中
  15.         sda=0;                         //下降沿
  16.         delayus();                //sda低電平保持4us以上        ,這里是4.34us滿足要求
  17. }

  18. void iic_stop()        //停止信號(hào)
  19. {
  20.         sda=0;_nop_();        //準(zhǔn)備狀態(tài)
  21.         scl=1;
  22.         delayus();                //該狀態(tài)穩(wěn)定時(shí)間要求保持4us以上
  23.         sda=1;                        //scl高電平期間,sda來(lái)一個(gè)上升沿
  24.         delayus();                //sda保持4.7us以上,4.34加上函數(shù)返回時(shí)間大于4.7us
  25.                                                 //注:此時(shí)scl和sda都為1       
  26. }

  27. void iic_sendByte(uchar byteData) //mcu發(fā)送一個(gè)字節(jié)
  28. {
  29.         uchar i;
  30.         uchar temp=byteData;
  31.         for(i=0;i<8;i++)
  32.         {
  33.                 temp=temp<<1;   //移動(dòng)后最高位到了PSW寄存器的CY位中
  34.                 scl=0;                         //準(zhǔn)備
  35.                 _nop_();                    //穩(wěn)定一下
  36.                 sda=CY;                         //將待發(fā)送的數(shù)據(jù)一位位的放到sda上
  37.                 _nop_();
  38.                 scl=1;                     //每一個(gè)高電平期間,ic器件都會(huì)將數(shù)據(jù)取走
  39.                 _nop_();               
  40.         }

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

  46. uchar iic_readByte() //讀一個(gè)字節(jié)
  47. {
  48.         uchar i,temp;
  49.         scl=0;                                //準(zhǔn)備讀數(shù)據(jù)
  50.         _nop_();
  51.         sda=1;                                //釋放總線
  52.         _nop_();

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

  64. bool iic_checkACK()                //處理應(yīng)答信號(hào)
  65. {
  66.         uchar errCounts=255; //定義超時(shí)量為255次
  67.         scl=1;
  68.         _nop_();
  69.        
  70.         while(sda)
  71.         {        //在一段時(shí)間內(nèi)檢測(cè)到sda=0的話認(rèn)為是應(yīng)答信號(hào)
  72.                 if(0==errCounts)
  73.                 {
  74.                         scl=0;                  //鉗住總線
  75.                         _nop_();
  76.                         return false; //沒(méi)有應(yīng)答信號(hào)
  77.                 }
  78.                 errCounts--;
  79.         }

  80.         scl=0;                          //鉗住總線,為下1次通信做準(zhǔn)備
  81.         _nop_();
  82.         return true;          //成功處理應(yīng)答信號(hào)
  83. }

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

  90. void iic_sendACK(bool b_ACK)        //發(fā)送應(yīng)答或非應(yīng)答信號(hào)
  91. {
  92.         scl=0;                        //準(zhǔn)備
  93.         _nop_();

  94.         if(b_ACK)                //ACK
  95.         {
  96.                 sda=0;
  97.         }
  98.         else                           //unACK
  99.         {
  100.                 sda=1;
  101.         }

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


  108. void AT24C02_writeByte(uchar address,uchar dataByte)//向24c02寫一字節(jié)數(shù)據(jù)
  109. {
  110.         iic_start();
  111.         iic_sendByte(0xa0);//mcu寫控制字,前4位固定1010,后三位地址0,末位0是寫
  112.         iic_checkACK();                   //mcu處理應(yīng)答信號(hào)
  113.         iic_sendByte(address);  //準(zhǔn)備在指定地址處寫入       
  114.         iic_checkACK();
  115.         iic_sendByte(dataByte); //寫數(shù)據(jù)
  116.         iic_checkACK();
  117.         iic_stop();
  118.         delayms(2);       
  119.         //按字節(jié)寫入時(shí),24c02在接收到停止信號(hào)后將數(shù)據(jù)擦寫到內(nèi)部,這需要時(shí)間
  120.         //并且在這段時(shí)間內(nèi)不會(huì)響應(yīng)總線上的任何請(qǐng)求,故讓mcu有2毫秒以上的等待       
  121. }

  122. void AT24C02_writeData(uchar address,uchar numBytes,uchar* buf)//寫入任意長(zhǎng)度數(shù)據(jù)
  123. {
  124.         while(numBytes--)
  125.         {
  126.                 AT24C02_writeByte(address++,*buf++);
  127.         }
  128. }

  129. void AT24C02_readData(uchar beginAddr,uchar dataSize,uchar* buf)//讀取任意長(zhǎng)度字節(jié)
  130. {
  131.         iic_start();                                        //起始信號(hào)
  132.         iic_sendByte(0xa0);                        //控制字,寫
  133.         iic_checkACK();                                //處理應(yīng)答信號(hào)
  134.         iic_sendByte(beginAddr);        //發(fā)送地址
  135.         iic_checkACK();                                //處理應(yīng)答信號(hào)       
  136.         iic_start();                                   //發(fā)送起始信號(hào)
  137.         iic_sendByte(0xa1);                        //控制字,讀
  138.         iic_checkACK();                                //處理應(yīng)答信號(hào)
  139.         while(dataSize--)                                //讀取dataSize個(gè)字節(jié)
  140.         {
  141.                 *buf++=iic_readByte();        //讀取一個(gè)個(gè)字節(jié)并保存到緩沖區(qū)buf中
  142.                 iic_sendACK(dataSize);  //發(fā)送應(yīng)答,當(dāng)dataSize為0時(shí)發(fā)送非應(yīng)答
  143.         }
  144.         iic_stop();                                                //發(fā)送停止信號(hào)
  145. }

  146. void main()
  147. {
  148.         uchar buf[2];                                        //接受數(shù)據(jù)的緩沖區(qū)
  149.         uchar arr[34]={0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,                           //0x00-0x0f
  150.                                                 16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,//0x10-0x1f
  151.                                                 32,0x55};                                                                                                        //0x20-0x21
  152.         iic_init();                                                                                        //總線初始化
  153.         //AT24C02_writeByte(0x08,0x11);                          //向指定地址處寫入一個(gè)字節(jié)數(shù)據(jù),代碼測(cè)試
  154.         AT24C02_writeData(0x00,sizeof(arr),arr);        //向指定地址處開始寫入34字節(jié)的數(shù)據(jù)
  155.         AT24C02_readData(0x20,sizeof(buf),buf);   //從指定地址開始讀2個(gè)字節(jié)
  156.         P1=buf[1];        //buf中的第二個(gè)元素就是arr中的最后一個(gè)數(shù)據(jù)0x55
  157.                                                                                        
  158.         while(1){P1=~P1;delayms(500);} //將這個(gè)0x55用led燈顯示出來(lái)10101010變化
  159. }
復(fù)制代碼


  1. my51.h頭文件中主要用到
  2. #include<intrins.h>
  3. typedef unsigned char  uchar ;

  4. void delayms(uint16 ms)  //軟延時(shí)函數(shù)
  5. {
  6.         uint16 i,j;
  7.         for(i=ms;i>0;i--)
  8.         {
  9.         for(j=113;j>0;j--)
  10.         {}
  11.         }
  12. }
復(fù)制代碼



評(píng)分

參與人數(shù) 1黑幣 +12 收起 理由
YJGG + 12 很給力!

查看全部評(píng)分

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

相關(guān)帖子

回復(fù)

使用道具 舉報(bào)

沙發(fā)
ID:23606 發(fā)表于 2017-1-15 10:39 | 只看該作者
講的很詳細(xì),很到位
回復(fù)

使用道具 舉報(bào)

板凳
ID:58730 發(fā)表于 2018-3-24 17:10 | 只看該作者
謝謝分享
回復(fù)

使用道具 舉報(bào)

地板
ID:66862 發(fā)表于 2018-10-31 23:18 | 只看該作者
樓主可以分享一下工程文件嗎?我正需要學(xué)習(xí)這方面。謝謝!
回復(fù)

使用道具 舉報(bào)

本版積分規(guī)則

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

Powered by 單片機(jī)教程網(wǎng)

快速回復(fù) 返回頂部 返回列表
主站蜘蛛池模板: 日日碰碰 | 久久免费视频观看 | 国产小视频在线 | 一区二区三区免费在线观看 | 国产精品一区一区 | 99精品视频在线 | 国产成人综合一区二区三区 | 精品国产乱码一区二区三 | 成人精品一区亚洲午夜久久久 | 欧美视频成人 | 成人免费视频网站在线看 | 日本超碰 | 午夜一区二区三区视频 | 成人激情视频免费在线观看 | 亚洲精品一区二区三区蜜桃久 | 一级看片免费视频囗交动图 | 91精品久久久久久久 | 国产精品资源在线 | 365夜爽爽欧美性午夜免费视频 | 国产精品免费观看 | 91社区在线观看 | 中文字幕视频在线免费 | 欧美一区二区三区在线播放 | 日日夜夜av | 精品视频一区二区三区 | zzzwww在线看片免费 | 亚洲视频在线观看 | 国产香蕉视频在线播放 | 欧美成人一区二区 | 日韩一二区 | 亚洲欧美在线一区 | 国产一级免费在线观看 | 国产在线观看一区二区 | 成人a视频片观看免费 | 99福利| 国产精品美女www爽爽爽视频 | 色婷婷综合久久久中字幕精品久久 | 欧美精品1区2区 | av免费看在线 | 亚洲欧洲日本国产 | 中文字幕免费在线 |