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

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 10828|回復(fù): 12
收起左側(cè)

利用AT24C02來保存,精華都在程序中。。。。。

  [復(fù)制鏈接]
ID:69862 發(fā)表于 2015-1-10 23:57 | 顯示全部樓層 |閱讀模式
本帖最后由 xiao_yp2014 于 2016-1-21 14:33 編輯

功能需求:
            開機后兩位數(shù)碼管顯示0到99之間的某一個數(shù)值,用一個按鍵可以不斷的遞增,用另外一個按鍵可以不斷的遞減。斷電后此數(shù)據(jù)可保存,下次通電               開機的時候還是從那個保存的數(shù)據(jù)開始顯示。

程序如下:
main.c
  1. /*EEPROM篇--利用AT24C02存儲數(shù)據(jù)
  2. 功能需求:
  3.         開機后兩位數(shù)碼管顯示0到99之間的某一個數(shù)值,用一個按鍵可以不斷的遞增,
  4.             用另外一個按鍵可以不斷的遞減。斷電后此數(shù)據(jù)可保存,下次通電開機的時候
  5.             還是從那個保存的數(shù)據(jù)開始顯示。
  6. */

  7. #include<reg52.h>             //頭文件
  8. #include"AT24C02.h"          //IIC自定義頭文件
  9. #include"Key_Scan.h"         //按鍵自定義頭文件
  10. #include"display.h"             //數(shù)碼管顯示自定義頭文件

  11. sbit beep_dr = P3^6;         //蜂鳴器

  12. unsigned int uiVoiceCnt = 0;   //蜂鳴器時間變量
  13. unsigned char ucSetNumber = 0; //設(shè)定值變量
  14.         
  15. void Init_All();                           //初始化全部程序
  16. void Timer_T0();                      //TO定時器中斷

  17. void main()
  18. {
  19.     Init_All();                               //初始化全部

  20.         while(1)
  21.         {
  22.                  display();                   //調(diào)用數(shù)碼管顯示函數(shù)
  23.                  Key_Service();          //調(diào)用按鍵服務(wù)函數(shù),放在主函數(shù)里
  24.         }
  25. }

  26. void Init_All()
  27. {
  28.         TH0=0xf8;   //重裝初始值(65535-2000)=63535=0xf82f
  29.         TL0=0x2f;
  30.         EA = 1;
  31.         ET0 = 1;
  32.         TR0=1;  //開中斷

  33.         ucSetNumber = read_eeprom(128);        //上電開機讀取EEPROM數(shù)據(jù),128是一個我任意選的一個存儲地址

  34.         if(ucSetNumber > 99)
  35.         {
  36.             write_eeprom(128,0); //往一個地址存入一個字節(jié)數(shù)據(jù),128是一個我任意選的一個存儲地址
  37.         }
  38. }

  39. void Timer_T0() interrupt 1
  40. {
  41.         TF0=0;  //清除中斷標志
  42.         TR0=0; //關(guān)中斷

  43.         Key_Scan();         //按鍵掃描放在中斷里

  44.         if(uiVoiceCnt!=0)   //蜂鳴器
  45.         {
  46.            uiVoiceCnt--;     //每次進入定時中斷都自減1,直到等于零為止。才停止鳴叫
  47.            beep_dr = 0;    //蜂鳴器是PNP三極管控制,低電平就開始鳴叫
  48.         }
  49.         else
  50.         {
  51.            beep_dr = 1;   //蜂鳴器是PNP三極管控制,高電平就停止鳴叫。
  52.         }

  53.         TH0=0xf8;        //重裝初始值(65535-2000)=63535=0xf82f
  54.         TL0=0x2f;
  55.         TR0=1;             //開中斷
  56. }
復(fù)制代碼

AT24C02.c
  1. #include<intrins.h>
  2. #include"AT24C02.h"

  3. sbit eeprom_scl_dr  = P3^4;      //時鐘線
  4. sbit eeprom_sda_dr = P3^5;      //數(shù)據(jù)輸出線


  5. //AT24C02驅(qū)動程序
  6. void start24()  //開始位
  7. {
  8.     eeprom_sda_dr=1;
  9.     eeprom_scl_dr=1;
  10.     Delay_time(15);
  11.     eeprom_sda_dr=0;
  12.     Delay_time(15);
  13.     eeprom_scl_dr=0;   
  14. }


  15. void ack24()  //確認位
  16. {
  17.     eeprom_scl_dr=1;
  18.     Delay_time(15);
  19.     eeprom_scl_dr=0;
  20.     Delay_time(15);
  21. }

  22. void stop24()  //停止位
  23. {
  24.     eeprom_sda_dr=0;
  25.     eeprom_scl_dr=1;
  26.     Delay_time(15);
  27.     eeprom_sda_dr=1;
  28. }

  29. unsigned char read24()  //讀取一個字節(jié)的時序
  30. {
  31.         unsigned char outdata,tempdata;

  32.         outdata=0;
  33.         _nop_();         //空指令,相當于一個機器周期
  34.             _nop_();     //空指令,相當于一個機器周期

  35.         for(tempdata=0;tempdata<8;tempdata++)
  36.         {
  37.                         eeprom_scl_dr=0;
  38.                         _nop_();         //空指令,相當于一個機器周期
  39.                         _nop_() ;         //空指令,相當于一個機器周期
  40.                         eeprom_scl_dr=1;
  41.                         _nop_() ;         //空指令,相當于一個機器周期
  42.                         _nop_() ;         //空指令,相當于一個機器周期
  43.                         outdata<<=1;
  44.                         if(eeprom_sda_dr==1)
  45.                         {
  46.                                 outdata++;
  47.                         }        
  48.                         _nop_() ;  //空指令,相當于一個機器周期
  49.                         _nop_() ;  //空指令,相當于一個機器周期
  50.         }
  51.     return(outdata);
  52.      
  53. }

  54. void write24(unsigned char dd) //發(fā)送一個字節(jié)的時序
  55. {
  56.         unsigned char tempdata;

  57.         for(tempdata=0;tempdata<8;tempdata++)
  58.         {
  59.                 if(dd>=0x80)
  60.                                 {
  61.                                      eeprom_sda_dr=1;
  62.                                 }
  63.                 else
  64.                                 {
  65.                                          eeprom_sda_dr=0;
  66.                                 }
  67.                 dd<<=1;
  68.                 _nop_() ;                 //空指令,相當于一個機器周期
  69.                 eeprom_scl_dr=1;
  70.                 _nop_() ;                 //空指令,相當于一個機器周期
  71.                                 _nop_() ; //空指令,相當于一個機器周期
  72.                                 _nop_() ; //空指令,相當于一個機器周期
  73.                                 _nop_() ; //空指令,相當于一個機器周期
  74.                 eeprom_scl_dr=0;
  75.         }
  76. }


  77. unsigned char read_eeprom(unsigned int address)   //從一個地址讀取出一個字節(jié)數(shù)據(jù)
  78. {
  79.         unsigned char dd,cAddress;  
  80.         
  81.         cAddress=address; //把低字節(jié)地址傳遞給一個字節(jié)變量。
  82.         start24();          //開始
  83.         write24(0xA0);  //此字節(jié)包含讀寫指令和芯片地址兩方面的內(nèi)容。
  84.                                  //指令為寫指令。地址為"000"的信息,此信息由A0,A1,A2的引腳決定
  85.         ack24();            //發(fā)送應(yīng)答信號
  86.         write24(cAddress); //發(fā)送讀取的存儲地址(范圍是0至255)
  87.         ack24();           //發(fā)送應(yīng)答信號
  88.         start24();         //開始
  89.         write24(0xA1); //此字節(jié)包含讀寫指令和芯片地址兩方面的內(nèi)容。
  90.                                //指令為讀指令。地址為"000"的信息,此信息由A0,A1,A2的引腳決定
  91.         ack24();          //發(fā)送應(yīng)答信號
  92.         dd=read24(); //讀取一個字節(jié)
  93.         ack24();         //發(fā)送應(yīng)答信號
  94.         stop24();       //停止
  95.         Delay_time(800);  //此處最關(guān)鍵,此處的延時時間一定要,而且要足夠長
  96.         return(dd);
  97. }

  98. void write_eeprom(unsigned int address,unsigned char dd) //往一個地址存入一個字節(jié)數(shù)據(jù)
  99. {
  100.         unsigned char cAddress;   
  101.         
  102.         cAddress=address; //把低字節(jié)地址傳遞給一個字節(jié)變量。
  103.         start24();             //開始
  104.         write24(0xA0); //此字節(jié)包含讀寫指令和芯片地址兩方面的內(nèi)容。
  105.                                 //指令為寫指令。地址為"000"的信息,此信息由A0,A1,A2的引腳決定
  106.         ack24();           //發(fā)送應(yīng)答信號
  107.         write24(cAddress);   //發(fā)送寫入的存儲地址(范圍是0至255)
  108.         ack24();           //發(fā)送應(yīng)答信號
  109.         write24(dd);     //寫入存儲的數(shù)據(jù)
  110.         ack24();           //發(fā)送應(yīng)答信號
  111.         stop24();         //停止
  112.         Delay_time(2000);  //此處最關(guān)鍵,此處的延時時間一定要,而且要足夠長
  113. }

  114. void Delay_time(unsigned int Delay11_MS)  
  115. {
  116.      unsigned int Delay11_us;

  117.      for(Delay11_us=0;Delay11_us<Delay11_MS;Delay11_us++)
  118.      {
  119.                 _nop_();     
  120.      }
  121. }
復(fù)制代碼


AT24C02.h
  1. #ifndef __AT24C02_H__
  2. #define __AT24C02_H__

  3. #include<reg52.h>

  4. unsigned char read_eeprom(unsigned int address);   //從一個地址讀取出一個字節(jié)數(shù)據(jù)
  5. void start24(); //開始位
  6. void ack24();   //確認位
  7. void stop24();  //停止位
  8. unsigned char read24();  //讀取一個字節(jié)的時序
  9. void write24(unsigned char dd); //發(fā)送一個字節(jié)的時序
  10. void write_eeprom(unsigned int address,unsigned char dd); //往一個地址存入一個字節(jié)數(shù)據(jù)
  11. void Delay_time(unsigned int Delay11_MS); //延時程序  

  12. #endif
復(fù)制代碼

Key_Scan.c
  1. #include"Key_Scan.h"                     //按鍵自定義頭文件
  2. #include"AT24C02.h"                      //IIC自定義頭文件

  3. #define const_KeyTimeLevel  100   //按鍵消抖的時間,可以修改
  4. #define const_VoiceCntLevel  150  //蜂鳴器鳴叫的時間

  5. sbit Key_s1 = P1^6;        //數(shù)據(jù)加
  6. sbit Key_s2 = P1^7;        //數(shù)據(jù)減

  7. unsigned int uiKeyTimeCnt1 = 0;          //按鍵延時計數(shù)器
  8. unsigned int uiKeyTimeCnt2 = 0;          //按鍵延時計數(shù)器
  9. unsigned char ucKeyLock1 = 0;           //按鍵自鎖標志位,防止按鍵一直觸發(fā)
  10. unsigned char ucKeyLock2 = 0;           //按鍵自鎖標志位,防止按鍵一直觸發(fā)
  11. unsigned char KeySec = 0;                  //按鍵編號

  12. void Key_Scan()                                  //按鍵掃描程序
  13. {
  14.     if(Key_s1 == 1)
  15.         {
  16.            uiKeyTimeCnt1 = 0;             //延時計數(shù)器清零
  17.            ucKeyLock1 = 0;                 //自鎖標志位清零
  18.         }
  19.         else if(ucKeyLock1 == 0)         //當有按鍵按下
  20.         {
  21.                    uiKeyTimeCnt1++;       //延時計數(shù)器加1

  22.                  if(uiKeyTimeCnt1 >= const_KeyTimeLevel)  //去抖動時間到
  23.                  {
  24.                           uiKeyTimeCnt1 = 0;      //延時計數(shù)器清零
  25.                          ucKeyLock1 = 1;            //按鍵自鎖
  26.                          KeySec = 1;                    //觸發(fā)1號鍵
  27.                  }
  28.         }

  29.         if(Key_s2 == 1)
  30.         {
  31.            uiKeyTimeCnt2 = 0;                //延時計數(shù)器清零
  32.            ucKeyLock2 = 0;                    //自鎖標志位清零
  33.         }
  34.         else if(ucKeyLock2 == 0)           //當有按鍵按下
  35.         {
  36.                    uiKeyTimeCnt2++;         //延時計數(shù)器加1

  37.                  if(uiKeyTimeCnt2 >= const_KeyTimeLevel)  //去抖動時間到
  38.                  {
  39.                           uiKeyTimeCnt2 = 0;     //延時計數(shù)器清零
  40.                          ucKeyLock2 = 1;          //按鍵自鎖
  41.                          KeySec = 2;                 //觸發(fā)2號鍵
  42.                  }
  43.         }

  44. }

  45. void Key_Service()                                //按鍵服務(wù)函數(shù)
  46. {
  47.     switch(KeySec)
  48.         {
  49.             case 0:break;
  50.                 case 1:
  51.                       ucSetNumber++;           //設(shè)定值自加1

  52.                        if(ucSetNumber >= 99)  //當加到99,就賦值成0
  53.                            {
  54.                                ucSetNumber = 0;  //賦值
  55.                            }
  56.                           write_eeprom(128,ucSetNumber); //往一個地址存入一個字節(jié)數(shù)據(jù)

  57.                       uiVoiceCnt = const_VoiceCntLevel;//蜂鳴器
  58.                           KeySec = 0;   //清零按鍵標志
  59.                 break;                      //跳出
  60.                      
  61.                 case 2:
  62.                       ucSetNumber--;              //設(shè)定值自減1
  63.                           if(ucSetNumber>=99) //減到大于99,賦值成99
  64.                           {
  65.                                     ucSetNumber = 99;
  66.                           }
  67.                           write_eeprom(128,ucSetNumber); //往一個地址存入一個字節(jié)數(shù)據(jù)

  68.                       uiVoiceCnt = const_VoiceCntLevel;       //蜂鳴器
  69.                           KeySec = 0;                                     //清零按鍵標志位
  70.                        break;

  71.                 default : break;
  72.         }
  73. }
復(fù)制代碼


Key_Scan.h
  1. #ifndef __Key_Scan_H__
  2. #define __Key_Scan_H__

  3. #include<reg52.h>

  4. void Key_Scan();                               //按鍵掃描程序
  5. void Key_Service();                            //按鍵服務(wù)程序
  6. extern unsigned int uiVoiceCnt;          //變量全局聲名
  7. extern unsigned char ucSetNumber;  //變量全局聲名
  8. extern unsigned char ucSetNumber;  //變量全局聲名extern可置于變量或者函數(shù)前,以表示變量或者函數(shù)的定義在別的文件中,
  9.                                    //提示編譯器遇到此變量和函數(shù)時在其他模塊中尋找其定義
  10. #endif
復(fù)制代碼


Display.c
  1. #include"display.h"             //顯示頭文件
  2. #include"delay.h"                //延時頭文件

  3. unsigned char code array[]= {0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xff};

  4. void display()
  5. {
  6.            static unsigned char ucNumber_left = 0;  //左邊數(shù)碼管顯示的實際內(nèi)容
  7.         static unsigned char ucNumber_right = 0;  //右邊數(shù)碼管顯示的實際內(nèi)容
  8.         static unsigned char ucDisplayStep = 1;     //顯示步驟切換變量

  9.         if(ucSetNumber >= 10)                              //在顯示的數(shù)值小于10時,左邊數(shù)碼管不顯示
  10.         {
  11.             ucNumber_left = ucSetNumber/10;        //得到左邊顯示的值
  12.         }
  13.         else
  14.         {
  15.                 ucNumber_left = 10;                          //小于10就不顯示
  16.         }

  17.         ucNumber_right = ucSetNumber%10;       //右邊數(shù)碼管顯示的值

  18.         switch(ucDisplayStep)
  19.         {
  20.                 case 1:                                                //左邊數(shù)碼管顯示驅(qū)動
  21.                        P0 = array[ucNumber_left];
  22.                            P2 = 0xfe;
  23.                            ucDisplayStep = 2;
  24.                            delay_10ms();
  25.                            P2 = 0xff;
  26.                        break;

  27.                 case 2:
  28.                            P0 = array[ucNumber_right];    //右邊數(shù)碼管顯示驅(qū)動
  29.                    P2 = 0xfd;
  30.                            ucDisplayStep = 1;
  31.                            delay_10ms();
  32.                            P2 = 0xff;
  33.                        break;
  34.         }
  35. }
復(fù)制代碼


Display.h

  1. #ifndef __display_h__
  2. #define __display_h__

  3. #include<reg52.h>
  4. void display();
  5. extern unsigned char ucIICDataTemp;       //聲名全局變量
  6. extern unsigned char ucSetNumber;          //聲名全局變量
  7. #endif
復(fù)制代碼

delay.c
  1. #include"delay.h"

  2. void delay_10ms()           //延時函數(shù)
  3. {
  4.    unsigned int x,y;
  5.     for(x = 0;x<10;x++)
  6.           for(y = 0;y<10;y++);
  7.       
  8. }
復(fù)制代碼


delay.h
  1. #ifndef __delay_h__
  2. #define __delay_h__

  3. void delay_10ms();           //函數(shù)聲名

  4. #endif
復(fù)制代碼





            打包程序下載——>   EEPROM篇—用AT24C02數(shù)據(jù)保存數(shù)據(jù).zip (108.42 KB, 下載次數(shù): 264)

評分

參與人數(shù) 4黑幣 +73 收起 理由
xiaomage + 10 非常棒的程序,規(guī)范,整潔,值得學(xué)習(xí)!
admin + 50 共享資料的積分獎勵!
liuyy + 5 贊一個!
liuyuxi + 8 很給力!

查看全部評分

回復(fù)

使用道具 舉報

ID:72008 發(fā)表于 2015-1-11 02:59 | 顯示全部樓層
謝謝版主提供 這么好的學(xué)習(xí)資料。先下了看看
回復(fù)

使用道具 舉報

ID:72008 發(fā)表于 2015-1-11 03:01 | 顯示全部樓層
樓主程序文件很多,但是注釋詳細非常好。有電路圖嗎?
回復(fù)

使用道具 舉報

ID:69862 發(fā)表于 2015-1-11 19:55 | 顯示全部樓層
liuyy 發(fā)表于 2015-1-11 02:59
謝謝版主提供 這么好的學(xué)習(xí)資料。先下了看看

資料還有,我會慢慢的奉獻的。。。。。
回復(fù)

使用道具 舉報

ID:69862 發(fā)表于 2015-1-11 19:58 | 顯示全部樓層
liuyy 發(fā)表于 2015-1-11 03:01
樓主程序文件很多,但是注釋詳細非常好。有電路圖嗎?

文件分得很細,是為了以后方便移植,我是用的開發(fā)板,原理圖就不上了,很簡單的。可以根據(jù)程序來畫原理圖。。。
回復(fù)

使用道具 舉報

ID:73539 發(fā)表于 2015-2-11 15:02 | 顯示全部樓層
頂一下!好東西!謝謝樓主,正找這個呢!
回復(fù)

使用道具 舉報

ID:95691 發(fā)表于 2016-7-25 09:20 | 顯示全部樓層
贊一個,很好的資料!
回復(fù)

使用道具 舉報

ID:104845 發(fā)表于 2016-8-17 23:13 | 顯示全部樓層
多謝無私分享
回復(fù)

使用道具 舉報

ID:214494 發(fā)表于 2018-1-22 13:45 | 顯示全部樓層
謝謝版主提供 這么好的學(xué)習(xí)資料
回復(fù)

使用道具 舉報

ID:614257 發(fā)表于 2019-12-6 17:11 | 顯示全部樓層
看一看
回復(fù)

使用道具 舉報

ID:689314 發(fā)表于 2020-4-26 22:50 | 顯示全部樓層
寫得太棒了!
回復(fù)

使用道具 舉報

ID:933601 發(fā)表于 2023-11-14 08:57 | 顯示全部樓層
這么詳細,講究
回復(fù)

使用道具 舉報

ID:1076665 發(fā)表于 2023-12-18 22:03 | 顯示全部樓層
很不錯,很詳細,值得研究
回復(fù)

使用道具 舉報

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

本版積分規(guī)則

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

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

快速回復(fù) 返回頂部 返回列表
主站蜘蛛池模板: 91视频中文 | 日日爱夜夜操 | 啪视频在线| 97精品国产 | 国产精品久久久久一区二区三区 | 亚洲欧美日韩中文在线 | 成人在线免费观看视频 | 日韩在线视频观看 | 日韩精品在线观看视频 | 国产99精品| 国产东北一级毛片 | 男人天堂av网| 一级毛片在线播放 | 午夜影院 | 农村黄性色生活片 | 蜜桃精品视频在线 | 国产粉嫩尤物极品99综合精品 | 草久久久 | 天堂av中文 | 亚洲九色 | 国产成年人视频 | 91成人在线| 国产欧美一区二区三区免费 | 九九九视频在线观看 | 精品一区二区三区电影 | 久久天堂 | 国产一区二区三区高清 | 99热在线播放 | 久久久久一区二区 | 国产精品1区2区 | 成人av在线大片 | 亚洲国产一区视频 | 一区二区三区免费 | 精品欧美乱码久久久久久 | 中文字幕爱爱视频 | 国产精品日日夜夜 | 亚洲人成在线观看 | 日韩国产欧美 | 国产一区中文字幕 | 成人久久18免费网站 | 久久av网站|