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

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

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

怎樣使單片機程序斷電保留上次的數據?

  [復制鏈接]
回帖獎勵 20 黑幣 回復本帖可獲得 5 黑幣獎勵! 每人限 1 次
跳轉到指定樓層
樓主
ID:263911 發表于 2018-4-20 22:42 | 只看該作者 回帖獎勵 |倒序瀏覽 |閱讀模式
設計一個車速里程的程序,每次斷電后沒能留下上次走的路程 請問怎么在程序里加個斷電保留數據的程序代碼?知道用at24c02,但不會編,求幫助sbit sda = P2^0;
sbit scl = P2^1;
  1. #include <reg52.h>                 //調用單片機頭文件
  2. #define uchar unsigned char  //無符號字符型 宏定義        變量范圍0~255
  3. #define uint  unsigned int         //無符號整型 宏定義        變量范圍0~65535

  4. uchar t1_num,t2_num;   //計時間中斷的次數
  5. unsigned long speed1,juli,time2;
  6. float f_hz        ,speed_km,speed_m;  //dlaout time1        ,speed_km,speed_m;
  7. uchar TH11,TL11;
  8. uchar flag_en;         //開始計算速度使能
  9. uchar flag_stop_en;    //要確定車子是否停下了
  10. uint juli_s;               //每秒走的距離
  11. uint juli_z;           //總路程
  12. float zhijing = 0.55;  //直徑 0.55M
  13. bit flag_1s = 1;           //1s
  14. long zong_lc;          //總量程
  15. uchar flag_200ms;
  16. uint sudu;            //定義速度的變量
  17. uint bj_sudu = 20;           //報警速度


  18. //這三個引腳參考資料
  19. sbit rs=P2^6;               //寄存器選擇信號 H:數據寄存器          L:指令寄存器
  20. sbit rw=P2^5;               //寄存器選擇信號 H:數據寄存器          L:指令寄存器
  21. sbit e =P2^7;               //片選信號   下降沿觸發

  22. uchar code table_num[]="0123456789abcdefg";
  23. uchar i;

  24. sbit beep = P1^5;   //蜂鳴器IO口定義

  25. /******************1ms 延時函數*******************/
  26. void delay_1ms(uint q)
  27. {
  28.         uint i,j;
  29.         for(i=0;i<q;i++)
  30.                 for(j=0;j<120;j++);
  31. }


  32. /********************************************************************
  33. * 名稱 : delay_uint()
  34. * 功能 : 小延時。
  35. * 輸入 : 無
  36. * 輸出 : 無
  37. ***********************************************************************/
  38. void delay_uint(uint q)
  39. {
  40.         while(q--);
  41. }

  42. /********************************************************************
  43. * 名稱 : write_com(uchar com)
  44. * 功能 : 1602命令函數
  45. * 輸入 : 輸入的命令值
  46. * 輸出 : 無
  47. ***********************************************************************/
  48. void write_com(uchar com)
  49. {
  50.         i=0;
  51.         e=0;
  52.         rs=0;
  53.         rw=0;
  54.         P0=com;
  55.         delay_uint(25);
  56.         e=1;
  57.         delay_uint(50);
  58.         e=0;
  59. }

  60. /********************************************************************
  61. * 名稱 : write_data(uchar dat)
  62. * 功能 : 1602寫數據函數
  63. * 輸入 : 需要寫入1602的數據
  64. * 輸出 : 無
  65. ***********************************************************************/
  66. void write_data(uchar dat)
  67. {
  68.         i=0;
  69.         e=0;
  70.         rs=1;
  71.         rw=0;
  72.         P0=dat;
  73.         delay_uint(25);
  74.         e=1;
  75.         delay_uint(50);
  76.         e=0;        
  77. }

  78. /********************************************************************
  79. * 名稱 : write_sfm2(uchar hang,uchar add,uchar date)
  80. * 功能 : 顯示2位十進制數,如果要讓第一行,第五個字符開始顯示"23" ,調用該函數如下
  81.                   write_sfm1(1,5,23)
  82. * 輸入 : 行,列,需要輸入1602的數據
  83. * 輸出 : 無
  84. ***********************************************************************/
  85. void write_sfm2(uchar hang,uchar add,uint date)
  86. {
  87.         if(hang==1)   
  88.                 write_com(0x80+add);
  89.         else
  90.                 write_com(0x80+0x40+add);
  91.            write_data(0x30+date/10%10);
  92.            write_data(0x30+date%10);        
  93. }

  94. /********************************************************************
  95. * 名稱 : write_sfm4(uchar hang,uchar add,uchar date)
  96. * 功能 : 顯示2位十進制數,如果要讓第一行,第五個字符開始顯示"23" ,調用該函數如下
  97.                   write_sfm1(1,5,23)
  98. * 輸入 : 行,列,需要輸入1602的數據
  99. * 輸出 : 無
  100. ***********************************************************************/
  101. void write_sfm4(uchar hang,uchar add,uint date)
  102. {
  103.         if(hang==1)   
  104.                 write_com(0x80+add);
  105.         else
  106.         write_com(0x80+0x40+add);
  107.    write_data(0x31+date/100000%10);
  108.         write_data(0x33+date/10000%10);
  109.         write_data(0x36+date/1000%10);
  110.         write_data('.');        
  111.         write_data(0x35+date/100%10);        
  112.         write_data(0x33+date/10%10);
  113.         write_data(0x32+date%10);        
  114.         write_data('k');        
  115.         write_data('m');        
  116. }

  117. /********************************************************************
  118. * 名稱 : write_string(uchar hang,uchar add,uchar *p)
  119. * 功能 : 改變液晶中某位的值,如果要讓第一行,第五個字符開始顯示"ab cd ef" ,調用該函數如下
  120.                   write_string(1,5,"ab cd ef;")
  121. * 輸入 : 行,列,需要輸入1602的數據
  122. * 輸出 : 無
  123. ***********************************************************************/
  124. void write_string(uchar hang,uchar add,uchar *p)
  125. {
  126.         if(hang==1)   
  127.                 write_com(0x80+add);
  128.         else
  129.                 write_com(0x80+0x40+add);
  130.                 while(1)
  131.                 {
  132.                         if(*p == '\0')  break;
  133.                         write_data(*p);
  134.                         p++;
  135.                 }        
  136. }

  137. /********************************************************************
  138. * 名稱 : init_1602()
  139. * 功能 : 初始化1602液晶
  140. * 輸入 : 無
  141. * 輸出 : 無
  142. ***********************************************************************/
  143. void init_1602()      //1602初始化
  144. {
  145.         write_com(0x38);
  146.         write_com(0x0c);
  147.         write_com(0x06);
  148.         delay_uint(1000);
  149.         write_string(1,0,"sd:00km/h       ");               
  150.         write_string(2,0,"lc:00.00km      ");        
  151. }

  152. /***********外部中斷0初始化程序****************/
  153. void init_int0()
  154. {
  155.         EX0=1;                          //允許外部中斷0中斷
  156.         EA=1;                           //開總中斷
  157.         IT0 = 1;                   //外部中斷0負跳變中斷
  158. }


  159. /*************定時器0初始化程序***************/
  160. void time_init()          //定時器0初始化程序
  161. {
  162.         EA   = 1;                   //開總中斷
  163.         TMOD = 0X11;          //定時器0、工作方式1
  164.         ET0  = 1;                  //開定時器0中斷
  165.         TR0  = 1;                  //允許定時器0定時
  166.         ET1  = 1;                  //開定時器1中斷
  167.         TR1  = 1;                  //允許定時器1定時
  168. }

  169. /***********計算速度函數**************/
  170. void menu_speed()          //計算速度函數
  171. {
  172.         static uchar value,value1;
  173.         if(flag_1s == 1)   
  174.                 {        
  175.                         flag_1s = 0;                 
  176.                         if(flag_en == 0)
  177.                         {
  178.                                 value ++;
  179.                                 if(value >= 3)        //2秒
  180.                                 {        
  181.                                         speed_km = 0;  //速度為0
  182.                                         sudu = (uint)speed_km;        
  183.                                         value = 0;                                
  184.                                 }
  185.                         }
  186.                         if((flag_en == 1))
  187.                         {        
  188.                                 value = 0;               
  189.                                 flag_en = 0;         
  190.                                  //1s = 1 / 1000000us;          // 1m/s=0.001km除以1/3600h=3.6km/h                        
  191.                                 f_hz = 1000000 / (t2_num * 65536.0 + TH11 * 256 + TL11);  //算出來就是秒
  192.                                 t2_num = 0;        //把變量清零
  193.                                 TH11 = 0;
  194.                                 TL11 = 0;                                          
  195.                                 speed_m = f_hz * zhijing * 3.14  ;        //算出來的是m/s
  196.                                 juli_z = (juli_z + (uint)speed_m) ;        //總路程m        
  197.                                 speed_km = speed_m * 3.6 ;        //(帶個小數點) km/s               
  198.                            sudu = (uint)speed_km;
  199.                                 if(sudu >= 99)
  200.                                         sudu = 99;
  201.                                 zong_lc += speed_m;
  202.                                 value1++;
  203.                                 if(value1 >= 20)
  204.                                 {
  205.                                         value1 = 0;
  206.                                 }
  207.                         }               

  208.                         write_sfm2(1,3,sudu);               
  209.                         write_sfm4(2,3,juli_z);               
  210.         }
  211. }


  212. /****************報警函數***************/
  213. void clock_h_l()
  214. {
  215.         static uchar value;           
  216.         if((sudu >= bj_sudu))
  217.         {
  218.                 value ++;  //消除實際距離在設定距離左右變化時的干擾
  219.                 if(value > 5)
  220.                 {
  221.                         beep = ~beep;           //蜂鳴器報警                        
  222.                 }        
  223.         }
  224.         else
  225.         {
  226.                 beep = 1;        
  227.         }                        
  228. }


  229. /******************主程序**********************/           
  230. void main()
  231. {
  232.         beep = 0;
  233.         delay_1ms(200) ;
  234.         P0 = P1 = P2 = P3 = 0xff;  //IO口初始為電平        
  235.         init_1602();      //1602初始化
  236.         init_int0();
  237.         time_init();          //定時器0初始化程序
  238.         while(1)
  239.         {         
  240.                 if(flag_200ms == 1)
  241.                 {
  242.                         flag_200ms = 0;
  243.                         menu_speed();          //計算速度函數
  244.                         clock_h_l();        //報警函數
  245.                 }
  246.         }
  247. }


  248. /*********************外部中斷0中斷服務程序************************/
  249. void int0() interrupt 0
  250. {
  251.         static uchar value;
  252.         switch(value)
  253.         {
  254.                 case 0:
  255.                         t1_num = 0;                 //第一次就把變量清零
  256.                         TH1 = 0;
  257.                         TL1 = 0;
  258.                         break;
  259.                 case 1:
  260.                                 t2_num = t1_num;  //保存
  261.                                 TH11 = TH1;
  262.                                 TL11 = TL1;
  263.                                 flag_en = 1;
  264.                         break;
  265.         }               
  266.         value ++;
  267.         if(value >= 2)
  268.                 value =0;
  269.         /************
  270.                 2.1   16.6
  271.                 2          15.8
  272.                 1.9   15.0
  273.         ************/
  274. }

  275. /*************定時器0中斷服務程序***************/
  276. void time0_int() interrupt 1
  277. {        
  278.         static uchar value;
  279.         TH0 = 0x3c;
  280.         TL0 = 0xb0;     // 50ms
  281.         value++;
  282.         if(value % 4 == 0)
  283.                 flag_200ms = 1;

  284.         if(value >= 20)  //1秒   才是一秒鐘的速度
  285.         {
  286.                 value = 0;
  287.                 flag_1s = 1;
  288.         }
  289. }

  290. /*************定時器1中斷服務程序***************/
  291. void time1_int() interrupt 3
  292. {
  293.         t1_num++;
  294. }
復制代碼




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

使用道具 舉報

沙發
ID:123289 發表于 2018-4-21 06:09 | 只看該作者

回帖獎勵 +5 黑幣

在電源電路上做文章:
要點:整流電路分兩節,用整流二極隔開。
最前級濾波電容要小,如1uF就好了,并做一個檢測電壓的電路,檢測它是否掉電,掉電時產生INT中斷,提醒你保存需要保存的數據。
后一級濾波電容要大,如1000uF,這樣當前級失電時,后級會保持有電一段時間,二極管能保證最前級無電時,后級的電不會向前放電。這樣你就有充分的時間來做數據保存了。
我做的產品都是這樣做的,而且還做了數據是否寫錯的檢驗,這是另一個課題了,不在此描述了。如果驅動電路耗電大,要做處理。
明白這個道理后,相信你也會想出招數了。要點:讓CPU及存儲器部分,在失電后,能保持有電一段時間,并能檢測到失電!!

評分

參與人數 1黑幣 +5 收起 理由
帥到爆炸 + 5 贊一個!

查看全部評分

回復

使用道具 舉報

板凳
ID:312823 發表于 2018-4-21 08:02 | 只看該作者
一般常用的方法是采用eeprom實時保存你剛刷新的數據,這樣任何時候一斷電都能再找回來
回復

使用道具 舉報

地板
ID:311504 發表于 2018-5-5 15:25 | 只看該作者
請問計算速度的函數怎么理解?
回復

使用道具 舉報

5#
ID:316332 發表于 2018-5-5 16:52 | 只看該作者
不一定非用at24c02,單片機片內的EEPROM存儲器也可以
回復

使用道具 舉報

6#
ID:307391 發表于 2018-5-6 08:52 | 只看該作者
EEPROM,即可
回復

使用道具 舉報

7#
ID:323199 發表于 2018-5-6 09:15 | 只看該作者
eeprom
回復

使用道具 舉報

8#
ID:343102 發表于 2018-7-5 22:05 | 只看該作者
現在的單片機芯片大多自帶EEPROM,還有低壓檢測功能,可以利用此功能在斷電時保存數據。
EEPROM有可擦除最大次數,雖然這個數字看著不小,但對于程序來說并不大,比如EEPROM為100萬次,如果我們以0.1秒的間隔寫入數據,則只能維持1000000*0.1/3600=27.78小時,也就是一天多就可以超出其最大壽命次數,所以不能采用即時刷新的方法。

評分

參與人數 1黑幣 +50 收起 理由
admin + 50 回帖助人的獎勵!

查看全部評分

回復

使用道具 舉報

9#
ID:308437 發表于 2018-7-5 22:24 | 只看該作者

現在的單片機芯片大多自帶EEPROM,還有低壓檢測功能,可以利用此功能在斷電時保存數據。
EEPROM有可擦除最大次數,雖然這個數字看著不小,但對于程序來說并不大,比如EEPROM為100萬次,如果我們以0.1秒的間隔寫入數據,則只能維持1000000*0.1/3600=27.78小時,也就是一天多就可以超出其最大壽命次數,所以不能采用即時刷新的方法。”同意這個觀點。設置刷新時間,或者低壓檢測,要斷電的時候保存數據

評分

參與人數 1黑幣 +60 收起 理由
admin + 60 回帖助人的獎勵!

查看全部評分

回復

使用道具 舉報

10#
ID:365986 發表于 2018-7-6 00:01 | 只看該作者
STC單片機內部有EEPROM?梢远x一個在EEPROM中的變量,將此次設置的內容存入EEPROM,下次上電直接讀取就好。
回復

使用道具 舉報

11#
ID:365824 發表于 2018-7-6 01:20 | 只看該作者
用單片機的ROM區可以儲存,運用指針指定儲存位置
回復

使用道具 舉報

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

本版積分規則

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

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 二区中文 | 精品国产乱码 | 亚洲高清一区二区三区 | 夜夜操天天干 | 日本久久久一区二区三区 | 午夜成人免费视频 | 91精品国产91久久久久久最新 | 嫩草影院黄 | 日韩欧美亚洲 | 成人精品视频99在线观看免费 | 精品国产欧美一区二区 | 成人不卡一区二区 | 在线观看深夜视频 | 久久久国产一区二区三区 | 羞羞的视频免费在线观看 | 久久久久久国产精品三区 | 久久伊人精品一区二区三区 | 日本在线观看视频 | 欧美日韩亚洲一区 | 天天射天天干 | 狠狠综合久久av一区二区老牛 | 免费v片| 亚洲va国产日韩欧美精品色婷婷 | 天堂网av在线 | 99精品免费在线观看 | 精品日韩一区二区 | 成人av大全| 91婷婷韩国欧美一区二区 | 日韩精品a在线观看图片 | 日韩在线观看中文字幕 | 亚洲精品99久久久久久 | 精品国模一区二区三区欧美 | av中文在线播放 | 日韩精品久久久久 | 久久精品综合 | 羞羞的视频免费在线观看 | 久色一区 | 狠狠影院| 国产1区 | 国产分类视频 | 中文字幕不卡一区 |