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

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

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

單片機(jī)+AT24C02為啥讀寫錯誤?

[復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
ID:611626 發(fā)表于 2023-8-1 12:59 | 只看該作者 |只看大圖 回帖獎勵 |倒序瀏覽 |閱讀模式
  1. /****************************************************************
  2. AT24C前四位固定為1010 A1-A2由管腳電平默認(rèn)接地,最后一位表示讀寫操作所以AT24C讀地址0xa1 寫地址0xa0
  3. 寫AT24C02的時候從器件地址為10100 0000,(0xa0),讀AT24C02的時候從器件地址為10100 0001,(0xa1)
  4. ***************************************************************/
  5. #include<reg51.h>
  6. #include <intrins.h>
  7. #define uint unsigned int
  8. #define uchar unsigned char
  9.         #define AT24C02_ADDRESS  0xA0 //0xA0 1010 00000寫地址
  10. uint Count;
  11. uint Set_Count;
  12. //        unsigned  int Count;
  13. //      unsigned  int Set_Count;
  14. uint Num_L;
  15. uint Num_H;

  16. uint num1;
  17. uint  num2;

  18. char yiwei_Count;//移位計數(shù)

  19. sbit I2C_SCL= P1^6;
  20. sbit I2C_SDA= P1^7;

  21. sbit Start_Dianji=P3^0; //電機(jī)啟動_dianji
  22. sbit  forward=P3^1; //正轉(zhuǎn)檢測
  23. //sbit  back=P3^1;    //反轉(zhuǎn)檢測
  24. sbit  run=P3^7;      //運行信號
  25. sbit  jia_up=P1^0;// 增加鍵
  26. sbit  jian_down=P1^1;//減少鍵
  27. sbit  yiwei_up=P1^2; //移位鍵
  28. sbit  qingling=P1^3; //清零鍵
  29. uchar code ledcode[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F};         //共陰數(shù)碼管編碼0-9
  30. uchar data Ledbuff[8]={1};//顯示緩沖區(qū)

  31. #define I2CDelay_us(){_nop_();_nop_();_nop_();_nop_();}//voidI2CDelay_us
  32. /***********************
  33. AT24C初始化
  34. *************************/
  35. void I2C_init()
  36. {
  37.         I2C_SCL=1;
  38.   //    I2CDelay_us(4);
  39.         I2C_SDA=1;//首先確保SCL SDA都是高電平
  40.   // I2CDelay_us(4);
  41.         
  42. }

  43. /***********************
  44. 產(chǎn)生總線起始信號
  45. *************************/
  46. void I2C_Start(void )
  47. {
  48.   I2C_SDA=1;//首先確保SCL SDA都是高電平
  49. //  I2CDelay_us(5);
  50.         I2C_SCL=1; //確保SCL高電平
  51.   //   I2CDelay_us(5);
  52.         I2C_SDA=0;//先在SCL為高時拉低SDA,即為起始信號
  53. //    I2CDelay_us(5);
  54.         I2C_SCL=0; //在拉低 SCL,鉗住I2C總線準(zhǔn)備發(fā)送或接收數(shù)據(jù)
  55. }
  56. /***********************
  57. 產(chǎn)生總線停止信號:先拉低SDA在拉低SCL
  58. *************************/

  59.   void I2C_Stop(void )
  60. {
  61.         I2C_SDA=0;//首先確保SCL SDA都是低電平
  62.         I2C_SCL=1; //先拉高 SCL
  63.         I2C_SDA=1;//在拉高 SDA
  64.    /*
  65. I2C_SCL=0;
  66. I2C_SDA=0;
  67. //    I2CDelay_us(4);
  68.    I2C_SCL=1;
  69. I2C_SDA=1;
  70. //   I2CDelay_us(4);
  71.    */
  72. }
  73. /*******************************************************************************
  74. *@brief I2C發(fā)送一個字節(jié)數(shù)據(jù)
  75. *@param Byte要發(fā)送的字節(jié)
  76. *@retval 無
  77. 起始信號后必須送一個從機(jī)地址(7)位,1-7位為要接收器件的地址,第八位讀寫位0發(fā)送1接收,第9位ACK應(yīng)答位,
  78. 緊接著為第一個數(shù)據(jù)字節(jié),然后一位應(yīng)答位ACK后面繼續(xù)第二個數(shù)據(jù)字節(jié)
  79. **********************************************************************************/
  80. void  I2C_SendByte(unsigned char Byte)
  81. {
  82. unsigned char i;
  83.         for(i=0;i<8;i++)
  84.            {
  85.                 I2C_SDA=Byte&(0x80>>i);
  86.                 I2C_SCL=1; //先拉高 SCL
  87.                   I2C_SCL=0; //SCL        
  88.              }
  89. }
  90. /***********************************************************************************************
  91. *@brief I2C讀取 接收一個字節(jié)
  92. *@param 無
  93. *@retval  讀取 接收到的一個字節(jié)數(shù)據(jù)
  94. ********************************************************************************************/
  95. unsigned char I2C_ReceiveByte(void)
  96. {
  97. unsigned char i,Byte=0x00;//
  98.         I2C_SDA=1; //
  99.         for(i=0;i<8;i++)
  100.         {
  101.         I2C_SCL=1; //先拉高 SCL
  102.         if(I2C_SDA){Byte |= (0x80>>i); }
  103.         I2C_SCL=0; //SCL        
  104.         }
  105. return Byte;
  106. }
  107. /*********************
  108. *@brief I2C發(fā)送應(yīng)答Ack
  109. *@param AckBit應(yīng)答位 0為應(yīng)答(成功) 1為非應(yīng)答(失敗)
  110. *@retval 無
  111. ************************/
  112. void I2C_SendAck(unsigned char AckBit)
  113. {

  114.         I2C_SDA=AckBit;
  115.         I2C_SCL=1; //先拉高 SCL
  116.         I2C_SCL=0; //SCL        
  117. }
  118. /*********************
  119. *@brief I2C接收應(yīng)答位
  120. *@param 無
  121. *@retval AckBit應(yīng)答位 0為應(yīng)答(成功) 1為非應(yīng)答(失敗)
  122. ************************/
  123. unsigned char I2C_ReceiveAck(void)
  124. {
  125. unsigned char AckBit;
  126.         I2C_SDA=1;
  127.         I2C_SCL=1; //先拉高 SCL
  128.   AckBit=I2C_SDA;
  129.         I2C_SCL=0; //SCL
  130. return AckBit; //返回值
  131. }
  132. /**********向AT24C寫數(shù)據(jù)***********
  133. *@brief AT24C寫入一個字節(jié)
  134. *@param WordAddress要寫入字節(jié)的地址
  135. *@param Data要寫入的數(shù)據(jù)
  136. *@retval無
  137. 寫多字節(jié)時,寫入一個字節(jié)。在寫一個字節(jié)前,必須延時5ms
  138. ************************/
  139. void AT24C_WriteByte(unsigned char WordAddress,Data)
  140. {
  141.   I2C_Start();//啟動總線
  142.   I2C_SendByte(AT24C02_ADDRESS);//發(fā)送寫操作地址+寫數(shù)據(jù)(0xa0)
  143.         I2C_ReceiveAck();                      //等待應(yīng)答
  144.         I2C_SendByte(WordAddress);//要寫入的地址
  145.         I2C_ReceiveAck();       //等待應(yīng)答完成
  146.    I2C_SendByte(Data);  //要寫入的數(shù)據(jù),第一字節(jié) ,第二字節(jié)注意:每個字節(jié)都回應(yīng)一個應(yīng)答位0,如果沒有回應(yīng)說明寫入不成功
  147.         I2C_ReceiveAck();       //等待完成  注意:每個字節(jié)都回應(yīng)一個應(yīng)答位0,如果沒有回應(yīng)說明寫入不成功
  148.         I2C_Stop(); //發(fā)送結(jié)束信號:停止總線
  149. }
  150. /************從AT24C中讀出數(shù)據(jù)*********
  151. *@brief AT24C讀取一個字節(jié)
  152. *@param WordAddress要讀出字節(jié)的地址
  153. *@param 無
  154. *@retval要讀出的數(shù)據(jù)
  155. ************************/
  156. unsigned char AT24C_ReadByte(unsigned char WordAddress) //void
  157. {
  158.         unsigned char Data;
  159.   I2C_Start();                    //發(fā)送起始信號:啟動總線
  160.    I2C_SendByte(AT24C02_ADDRESS);  //接上首字節(jié),發(fā)送器件寫操作地址+寫數(shù)據(jù)(0xa0)這里寫操作時維綸把所要讀的數(shù)據(jù)地址AT24C02_ADDRESS通知讀取哪個地址信息
  161.         I2C_ReceiveAck(); //等待完成應(yīng)答
  162.         I2C_SendByte(WordAddress);//發(fā)送要讀取內(nèi)存的地址(WORD ADDRESS)
  163.         I2C_ReceiveAck();       //等待應(yīng)答完成
  164.          I2C_Start();//在次啟動總線
  165.         I2C_SendByte(AT24C02_ADDRESS| 0x01);  //對E2PROM進(jìn)行讀操作(0XA1)E2PROM會自動向主機(jī)發(fā)回數(shù)據(jù),讀取一個字節(jié)后回應(yīng)一個應(yīng)答位,后會繼續(xù)傳送下一個地址的數(shù)據(jù)0xa1
  166.         I2C_ReceiveAck();       //等待完成
  167.         Data= I2C_ReceiveByte();  //要讀出的數(shù)據(jù)到Data
  168.    I2C_SendAck(1);       //等待完成::如果不想讀了,就發(fā)送一個非應(yīng)答位NAK(1),發(fā)送結(jié)束,停止總線
  169.         I2C_Stop(); //停止總線
  170.         return Data ;//返回值
  171. }

  172. /***********************************/
  173. void delayms(uint ms)

  174. {
  175. uchar k;
  176. while(ms--)
  177. {
  178.   for(k = 0; k < 120; k++);
  179. }
  180. }
  181. void display()                        //顯示程序display(uchar a,b,c,d,e)        char i;
  182. {
  183.         static unsigned char i = 0;         
  184.         switch(i)//使用多分支選擇語句 i=count display 0x代表16進(jìn)制
  185.         {
  186.                 case(0):Ledbuff[7]=Set_Count/1000;break;   //取設(shè)定千位字符送緩存
  187.                 case(1):Ledbuff[6]=Set_Count/100%10;break; //取設(shè)定百位字符送緩沖
  188.                 case(2):Ledbuff[5]=Set_Count/10%10;break;   //取設(shè)定十位字符送緩沖
  189.                 case(3):Ledbuff[4]=Set_Count%10;break;     //取設(shè)定個位字符送緩存
  190.                   
  191.                 case(4):Ledbuff[3]=Count/1000;break;         //取計數(shù)千位字符送緩存
  192.                 case(5):Ledbuff[2]=Count/100%10;break;
  193.                 case(6):Ledbuff[1]=Count/10%10;break;
  194.                 case(7):Ledbuff[0]=Count%10;break;
  195.         }
  196.         P0=0x00;   //消陰:段碼全部低電平關(guān)閉
  197.         P2=~(0x01<<i); //P2位選,左移i位取反
  198.         P0=ledcode[Ledbuff[i]];  //P0字符刷新顯示
  199.         delayms(1); //顯示2MS
  200.         i=++i%8;   //自加1
  201. }
  202. /*
  203. void  Adjust(void)        //按鍵設(shè)定匝數(shù),用P2.4個位-P2.7(千位)前四位數(shù)碼管顯示
  204.   {        
  205.            
  206.                 if(yiwei_up==0) //移位按鍵按下
  207.                   {
  208.                          while(!yiwei_up); //等待移位按鍵松開
  209.                          if(yiwei_Count<3) //移位
  210.                            {
  211.                             yiwei_Count +=1;
  212.                            }
  213.                    else       //如果>3
  214.           {                 
  215.             yiwei_Count=0;       //設(shè)定位在個位
  216.           }                                
  217.                    }
  218.                
  219.                 if(Set_Count>=0 && Set_Count<9999)//最大9999yiwei_Count=0; //設(shè)定加 jia_up==0
  220.                   {
  221.                                   if (jia_up==0)   //增加按鍵按下                                                     
  222.                                          {        
  223.                                            while(!jia_up);//等待加按鍵松開
  224.                                                   {
  225.                              if (yiwei_Count==0)        //               
  226.                              {
  227.                                      Set_Count += 1;         //設(shè)定+1
  228.                              }
  229.                                                           if (yiwei_Count==1&&Set_Count<9990)
  230.                                                                  {
  231.                                      Set_Count += 10;         //設(shè)定+1
  232.                               }
  233.                                                           if (yiwei_Count==2&&Set_Count<9900)
  234.                                                                  {
  235.                                      Set_Count += 100;         //設(shè)定+1
  236.                              }        
  237.                                                                 if (yiwei_Count==3 && Set_Count<9000)
  238.                                                                  {
  239.                                      Set_Count += 1000;         //設(shè)定+1
  240.                              }
  241.                                                   }        
  242.                                          }        
  243.                  if (jian_down==0)   //減少按鍵按下                                                     
  244.                                 {        
  245.                                            while(!jian_down);//等待按鍵松開
  246.                                                  {
  247.                              if (yiwei_Count==0&&Set_Count>1)        //        移位在個位        
  248.                               {
  249.                                       Set_Count -= 1;         //設(shè)定+1
  250.                               }
  251.                                                           if (yiwei_Count==1&&Set_Count>9)
  252.                                                                    {
  253.                                       Set_Count -= 10;         //設(shè)定+1
  254.                                }
  255.                                                           if (yiwei_Count==2 && Set_Count>99)
  256.                                                                    {
  257.                                       Set_Count -= 100;         //設(shè)定+1
  258.                                }        
  259.                                                                  if (yiwei_Count==3 && Set_Count>999)
  260.                                                                    {
  261.                                        Set_Count -= 1000;         //設(shè)定+1
  262.                                }
  263.                                                  }        
  264.                                                  //寫入數(shù)據(jù)
  265. /*        AT24C_WriteByte(0,Set_Count%256);
  266.         delayms(5) ; //顯示2MS
  267.         AT24C_WriteByte(1,Set_Count/256);
  268.         delayms(5); //顯示2MS
  269.                                         }        
  270.                 */        
  271. /**********************************************************
  272. 主函數(shù)
  273. **********************************************************/               
  274. void main()
  275. {
  276.         I2C_init();
  277. //        init();        //初始化24C02
  278.         //        num=5678;          //num為小于等于65535的整數(shù)。   */
  279.         Set_Count=1234;

  280.        Num_H  =Set_Count/256;  //1234/256就簡單了,高位:取的是整數(shù)倍,不被整除的部分自然就被剔除了1234/256=4
  281.         Num_L =Set_Count%256;  //%256是取余,低位:也就是你把前面的數(shù)值除以256取余,商跟除數(shù)則是256的整數(shù)倍部分1234%256=210  ;4*256=1024  %256=1234-1024=210
  282.         AT24C_WriteByte(0,Num_L);
  283.    delayms(10); //顯示2MS
  284.         AT24C_WriteByte(1,Num_H  );
  285.    delayms(10); //顯示2MS

  286.         num1=AT24C_ReadByte(0);        //用地址0單元存儲num十六進(jìn)制表示時的低兩位
  287.         num2=AT24C_ReadByte(1);        //用地址0單元存儲num十六進(jìn)制表示時的高兩位
  288.         Count=num2*256+num1;
  289.    //寫入24C02
  290.               //       AT24C_WriteByte(0,Set_Count%256); //低8位寫入0x00
  291.    /*
  292.     AT24C_WriteByte(0,120); //低8位寫入0x00
  293.                        delayms(5); //顯示2MS

  294.         //              AT24C_WriteByte(1,Set_Count/256); //高8位寫入0x01
  295.       AT24C_WriteByte(1,0); //高8位寫入0x01
  296.                       delayms(5); //顯示2MS

  297.         //讀取數(shù)據(jù)  /*

  298.         Num_L = AT24C_ReadByte(0);
  299.         Num_H  |=AT24C_ReadByte(1)<<8;
  300.        Count= Num_H+Num_L;
  301. */
  302. while(1)
  303.         {
  304. /* Adjust();        
  305.           if (jia_up==0)   //增加按鍵按下                                                     
  306.                  {        
  307.                  while(!jia_up);//等待加按鍵松開
  308.                   {   
  309.                      Set_Count += 1;         //設(shè)定+1
  310.                   }
  311.                }
  312.          if (jian_down==0)   //減少按鍵按下                                                     
  313.                 {        
  314.                          while(!jian_down);//等待按鍵松開
  315.                                  {         
  316.                                    Set_Count -= 1;         //設(shè)定+1
  317.                                  }
  318.                   }
  319.                   if(yiwei_up==0) //保存按鍵按下,向AT24C寫入數(shù)據(jù)
  320.                   {
  321.                          while(!yiwei_up); //等待移位按鍵松開                        
  322.                            {
  323.                            AT24C_WriteByte(0,Set_Count%256);
  324.                        delayms(6) ; //顯示2MS
  325.                       AT24C_WriteByte(1,Set_Count/256);
  326.                       delayms(6); //顯示2MS
  327.                            }
  328.                 }           
  329.                
  330.                 if( qingling==0) //讀取按鍵按下
  331.                   {
  332.                          while(! qingling); //等待移位按鍵松開                        
  333.                            {
  334.                              Count=AT24C_ReadByte(0);
  335.                              Count |=AT24C_ReadByte(1)<<8;
  336.                           // Count  = Num_H+Num_L;
  337.                            }
  338.                 }        */   
  339.         display();               
  340.      }
  341. }
復(fù)制代碼

gongyang.rar

19.96 KB, 下載次數(shù): 2

仿真文件

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

使用道具 舉報

沙發(fā)
ID:161164 發(fā)表于 2023-8-1 14:37 | 只看該作者

回復(fù)

使用道具 舉報

板凳
ID:1064915 發(fā)表于 2023-8-31 09:52 | 只看該作者
AT24C02程序沒問題
回復(fù)

使用道具 舉報

地板
ID:313517 發(fā)表于 2023-9-3 15:22 | 只看該作者
你自己看看是不是符號IIC協(xié)議規(guī)范,用示波器看看電平的高低情況,有無過充超標(biāo),看看開始結(jié)束時序,讀寫時序?qū)Σ粚?/td>
回復(fù)

使用道具 舉報

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

本版積分規(guī)則

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

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

快速回復(fù) 返回頂部 返回列表
主站蜘蛛池模板: 久久久噜噜噜www成人网 | 精品国产乱码久久久久久久久 | av手机免费在线观看 | 国产欧美一区二区三区久久手机版 | 伊人伊成久久人综合网站 | 亚洲免费在线观看 | 一区二区精品在线 | 日韩视频在线观看一区二区 | 国产一区二区三区四区hd | 欧美在线综合 | a级网站 | 日韩av啪啪网站大全免费观看 | 日韩免费视频 | 97超碰免费 | 日韩三区 | 亚洲一二三区在线观看 | a a毛片 | 久久最新| 伊人久久精品一区二区三区 | 在线一区 | 国产午夜一级 | 日本久久久影视 | 精品国产乱码一区二区三区 | 免费激情| 91一区 | 青春草91| 亚洲精品视频免费观看 | 成人小视频在线免费观看 | 日日干干夜夜 | av手机在线 | 97日日碰人人模人人澡分享吧 | 丝袜美腿一区二区三区 | 国产精品www| 亚洲国产黄 | 欧美成人精品一区二区男人看 | 91精品一区二区 | 欧美xxxx在线 | 国产精品av久久久久久毛片 | 综合国产| 在线精品国产 | 欧美性受xxxx |