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

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 4444|回復: 7
收起左側

STC15單片機EEPROM-掉電計數程序-TM1637數碼管

  [復制鏈接]
ID:507486 發表于 2020-4-4 16:55 | 顯示全部樓層 |閱讀模式
51hei.png
  1. #include "reg52.h"
  2. #include "intrins.h"
  3. #include "TM1637.h"
  4. #define uchar unsigned char //宏定義字符型變量
  5. #define uint unsigned int//宏定義整型變量
  6. /********************************************************************
  7. ************************ 寄存器設置
  8. *********************************************************************/
  9. sfr IAP_DATA =0xc2;//數據寄存器
  10. sfr IAP_ADDRH =0xc3;//地址寄存器
  11. sfr IAP_ADDRL =0xc4;//地址寄存器
  12. sfr IAP_CMD =0xc5; //命令寄存器
  13. sfr IAP_TRIG =0xc6;//觸發寄存器
  14. sfr IAP_CONTR =0xc7;//擦除寄存器

  15. sbit P33=P3^3;  //定義繼電器控制輸出腳
  16. sbit k1=P3^2;  //按鍵
  17. uchar tmp[4]=0,yw=0,mode=0;
  18. uint i,num=0,num_diaodian=100; //定義整型變量i
  19. uchar g1=0,s1=0,b1=0,q1=0;
  20. uchar g=0,s=0,b=0,q=0;
  21. bit ReadTimeFlag=0,Flag=0;//定義讀時間標志
  22. unsigned char keydate=0xff;
  23. /********************************************************************
  24. ************************ 命令定義
  25. *********************************************************************/
  26. #define CMD_IDLE 0 //EEPROM無操作
  27. #define CMD_READ 1 //讀取字節
  28. #define CMD_PROGRAM 2//寫入字節
  29. #define CMD_ERASE 3 //擦除字節

  30. /********************************************************************
  31. ************************ 編程周期由晶振決定
  32. *********************************************************************/
  33. //#define ENABLE_IAP 0X80 //編程周期由晶振決定(如果<30MHZ選用此項)
  34. //#define ENABLE_IAP 0X81 //編程周期由晶振決定(如果<24MHZ選用此項)
  35. //#define ENABLE_IAP 0X82 //編程周期由晶振決定(如果<20MHZ選用此項)
  36. #define ENABLE_IAP 0X83 //編程周期由晶振決定(如果<12MHZ選用此項)
  37. //#define ENABLE_IAP 0X84 //編程周期由晶振決定(如果<6MHZ選用此項)
  38. //#define ENABLE_IAP 0X85 //編程周期由晶振決定(如果<3MHZ選用此項)
  39. //#define ENABLE_IAP 0X86 //編程周期由晶振決定(如果<2MHZ選用此項)
  40. //#define ENABLE_IAP 0X87 //編程周期由晶振決定(如果<1MHZ選用此項)

  41. #define IAP_ADDRESS 0X0000 //內部EEPROM地址
  42. /********************************************************************
  43. ************************ 函數初始化
  44. *********************************************************************/
  45. void Delay(uchar n); //延時函數
  46. void IapIdle();//操作函數
  47. uchar IapReadByte(uint addr); //讀取函數
  48. void IapProgramByte(uint addr,uchar dat); //寫入函數
  49. void IapEraseSector(uint addr);//擦除函數

  50. void Delay5ms()                //@11.0592MHz
  51. {
  52.         unsigned char i, j;

  53.         i = 54;
  54.         j = 199;
  55.         do
  56.         {
  57.                 while (--j);
  58.         } while (--i);
  59. }

  60. void key(void) // //讀按鍵值 并做處理
  61. {
  62.   keydate=0XFF;
  63.   if(ReadTimeFlag==1)  //100ms讀取
  64.         {
  65.                 ReadTimeFlag=0;
  66.                 keydate=ScanKey();  //讀按鍵值

  67.         }
  68.          switch(keydate)
  69.          {
  70.          case 0xf7:   //K1      
  71.          if(mode++>=1)
  72.          {mode=0;}
  73.          if(mode==0)
  74.          {
  75.         tmp[0]=num%256;
  76.         tmp[1]=num/256;
  77.         tmp[2]=num_diaodian%256;
  78.         tmp[3]=num_diaodian/256;
  79.         Delay(8);//延時
  80.         IapEraseSector(IAP_ADDRESS);  //擦除扇區
  81.         for(i=0;i<4;i++)//對4個字節進行數據寫入
  82.         {
  83.         IapProgramByte(IAP_ADDRESS+i,(uchar)tmp[i]);//寫入數據
  84.         }
  85.         Delay(8);
  86.          }
  87.          break;         

  88.          case 0xf6:     //K2   
  89.          if(yw++>=3)yw=0;
  90.          break;         

  91.          case 0xf5:   //K3      
  92.    switch(mode)
  93.          {
  94.           case 0:
  95.                   break;        
  96.           case 1:
  97.            if(yw==0){ if(q1++>=9)q1=0;}
  98.             else if(yw==1){ if(b1++>=9)b1=0;}
  99.                  else if(yw==2){ if(s1++>=9)s1=0;}
  100.                   else if(yw==3){ if(g1++>=9)g1=0;}
  101.                      num_diaodian=q1*1000+b1*100+s1*10+g1;
  102.                   break;
  103.           }
  104.          
  105.          break;        
  106.            case 0xf4:   //K4     
  107.    switch(mode)
  108.          {
  109.           case 0:
  110.                   break;        
  111.           case 1:
  112.            if(yw==0){ if(q1--<=0)q1=9;}
  113.             else if(yw==1){ if(b1--<=0)b1=9;}
  114.                  else if(yw==2){ if(s1--<=0)s1=9;}
  115.                   else if(yw==3){ if(s1--<=0)s1=9;}
  116.                      num_diaodian=q1*1000+b1*100+s1*10+g1;
  117.                   break;
  118.           }
  119.          
  120.          break;                 
  121. }

  122. }

  123. /*------------------------------------------------
  124.                     定時器初始化子程序
  125. ------------------------------------------------*/
  126. void Init_Timer0(void)
  127. {
  128. TMOD |= 0x01;          //使用模式1,16位定時器,使用"|"符號可以在使用多個定時器時不受影響                     
  129. EA=1;            //總中斷打開
  130. ET0=1;           //定時器中斷打開
  131. TR0=1;           //定時器開關打開
  132. }
  133. /*------------------------------------------------
  134.                  定時器中斷子程序
  135. ------------------------------------------------*/
  136. void Timer0_isr(void) interrupt 1
  137. {
  138. static unsigned int num=0,cnt=0;
  139. TH0=(65536-50000)/256;                  //重新賦值 50ms
  140. TL0=(65536-50000)%256;

  141. num++;
  142. if(num==3)        //大致100ms
  143.    {
  144.     num=0;
  145.     ReadTimeFlag=1; //讀標志位置1
  146.         }
  147.   if(cnt++>=8)
  148.   {
  149.   cnt = 0;
  150.   Flag= ~ Flag;
  151.   
  152.   }
  153.         }
  154. /********************************************************************
  155. ************************  主函數
  156. *********************************************************************/

  157. void main()
  158. {

  159. P5M0=0;  P5M1=0;
  160. for(i=0;i<4;i++)//對4個字節數據讀出
  161. {
  162. tmp[i]=IapReadByte(IAP_ADDRESS+i);//讀eeprom數據
  163. }
  164. num=(uint)(tmp[0]+tmp[1]*256);
  165. num_diaodian =(uint)(tmp[2]+tmp[3]*256);
  166. if(num++>=num_diaodian)//到達預定掉電次數后
  167. {

  168. P33 = 0;//輸出低電平

  169. }
  170. q=num/1000%10;
  171. b=num/100%10;
  172. s=num/10%10;
  173. g=num%10;
  174. TM1637_display(q,b,s,g,0);
  175. tmp[0]=num%256;
  176. tmp[1]=num/256;
  177. tmp[2]=num_diaodian%256;
  178. tmp[3]=num_diaodian/256;
  179. Delay(8);//延時
  180. IapEraseSector(IAP_ADDRESS);  //擦除扇區
  181. for(i=0;i<4;i++)//對4個字節進行數據寫入
  182. {
  183. IapProgramByte(IAP_ADDRESS+i,(uchar)tmp[i]);//寫入數據
  184. }
  185. Delay(8);//延時
  186. Init_Timer0();
  187. while(1)
  188. {

  189. key();
  190. if(k1==0)
  191. { Delay5ms();
  192.    if(k1==0)
  193.    {
  194.         P33 = 1;//輸出G電平
  195.         /**********上電次數清零*********/
  196.         num=0;
  197.         tmp[0]=0;
  198.         tmp[1]=0;
  199.         tmp[2]=num_diaodian%256;
  200.         tmp[3]=num_diaodian/256;
  201.         Delay(1);//延時
  202.         IapEraseSector(IAP_ADDRESS);  //擦除扇區
  203.         for(i=0;i<4;i++)//對2個字節進行數據寫入
  204.         {
  205.         IapProgramByte(IAP_ADDRESS+i,(uchar)tmp[i]);//寫入數據
  206.         }
  207.         Delay(1);//延時
  208.         
  209.         }
  210.         Delay5ms();        
  211.         while(!k1) ;
  212. }
  213. q=num/1000%10;
  214. b=num/100%10;
  215. s=num/10%10;
  216. g=num%10;
  217. q1=num_diaodian/1000%10;
  218. b1=num_diaodian/100%10;
  219. s1=num_diaodian/10%10;
  220. g1=num_diaodian%10;

  221. if(mode==0)
  222. {
  223. TM1637_display(q,b,s,g,0);
  224. }
  225. else if(mode==1)
  226. {
  227. if(Flag == 0)
  228. {
  229. TM1637_display(q1,b1,s1,g1,0);
  230. }
  231. else if(Flag == 1)
  232. {
  233. if(yw==0) TM1637_display(21,b1,s1,g1,0);
  234. else if(yw==1) TM1637_display(q1,21,s1,g1,0);
  235. else if(yw==2)        TM1637_display(q1,b1,21,g1,0);
  236. else if(yw==3)         TM1637_display(q1,b1,s1,21,0);
  237. }
  238. }

  239. }

  240. }
  241. /********************************************************************
  242. ************************  延時函數
  243. *********************************************************************/
  244. void Delay(uchar n)
  245. {
  246. uint x;
  247. while(n--)
  248. {
  249. x=0;
  250. while(++x);
  251. }
  252. }
  253. /********************************************************************
  254. ************************  操作函數
  255. *********************************************************************/
  256. void IapIdle()
  257. {
  258. IAP_CONTR=0;
  259. IAP_CMD=0;
  260. IAP_TRIG=0;
  261. IAP_ADDRH=0X80;
  262. IAP_ADDRL=0;
  263. }

  264. /********************************************************************
  265. ************************  讀取一個字節函數
  266. *********************************************************************/
  267. uchar IapReadByte(uint addr)
  268. {
  269. uchar dat;
  270. IAP_CONTR=ENABLE_IAP;
  271. IAP_CMD=CMD_READ;
  272. IAP_ADDRL=addr;
  273. IAP_ADDRH=addr>>8;
  274. IAP_TRIG=0X5A;
  275. IAP_TRIG=0XA5;
  276. _nop_();
  277. _nop_();
  278. _nop_();
  279. dat=IAP_DATA;
  280. IapIdle();
  281. return dat;
  282. }

  283. /********************************************************************
  284. ************************  寫入一個字節函數
  285. *********************************************************************/
  286. void IapProgramByte(uint addr,uchar dat)
  287. {

  288. IAP_CONTR=ENABLE_IAP;
  289. IAP_CMD=CMD_PROGRAM;
  290. IAP_ADDRL=addr;
  291. IAP_ADDRH=addr>>8;
  292. IAP_DATA=dat;
  293. IAP_TRIG=0X5A;
  294. IAP_TRIG=0XA5;
  295. _nop_();
  296. _nop_();
  297. _nop_();
  298. IapIdle();
  299. }
  300. /********************************************************************
  301. ************************  擦除一個字節函數
  302. *********************************************************************/
  303. void IapEraseSector(uint addr)
  304. {
  305. IAP_CONTR=ENABLE_IAP;
  306. IAP_CMD=CMD_ERASE;
  307. IAP_ADDRL=addr;
  308. IAP_ADDRH=addr>>8;
  309. IAP_TRIG=0X5A;
  310. IAP_TRIG=0XA5;
  311. _nop_();
  312. _nop_();
  313. _nop_();
  314. IapIdle();
  315. }
復制代碼


STC15_EEPROM_掉電計數.rar

449.08 KB, 下載次數: 75, 下載積分: 黑幣 -5

程序

原理圖.pdf

130.86 KB, 下載次數: 32, 下載積分: 黑幣 -5

原理圖

評分

參與人數 1黑幣 +50 收起 理由
admin + 50 共享資料的黑幣獎勵!

查看全部評分

回復

使用道具 舉報

ID:90212 發表于 2020-11-5 23:07 | 顯示全部樓層
stc15用#include "reg52.h" 頭文件?
編譯一堆問題,不知道有沒有用心。
回復

使用道具 舉報

ID:828160 發表于 2020-11-5 23:44 | 顯示全部樓層
沒幾天FLASH就寫壞了
回復

使用道具 舉報

ID:95375 發表于 2021-8-28 00:24 | 顯示全部樓層
這個程序有錯誤,不能編譯通過
最近用了STC的下載軟件,上面有字庫生成/圖片取模,還有視頻教程,使用的工具越來越多了。
回復

使用道具 舉報

ID:89072 發表于 2024-3-31 09:43 | 顯示全部樓層
樓主程序有問題,修改了參考

STC15_EEPROM_掉電計數.rar

456.07 KB, 下載次數: 5, 下載積分: 黑幣 -5

回復

使用道具 舉報

ID:961114 發表于 2024-4-3 09:52 | 顯示全部樓層

上電后將 EEPROM中的數據讀到RAM中,平常是讀寫RAM,
掉電時及時將RAM中需要掉電保存的數據保存到EEPROM,
就無 EEPROM 擦寫壽命這種問題
回復

使用道具 舉報

ID:485350 發表于 2024-4-3 11:32 | 顯示全部樓層
添加數據讀寫校驗,再加上能在flash扇區內循環寫(例如寫數據8個字節,第一次寫入數據寫入扇區的0x00-0x07,第二次寫入扇區的0x08-0x0f,第三次寫入扇區的,0x10-0x17)就差不多了
回復

使用道具 舉報

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

本版積分規則

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

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 日本中文字幕在线视频 | 亚洲成av人片在线观看 | 欧美精品一区二区免费 | japanhdxxxx裸体| 免费h在线| 一级黄色av电影 | 日本一区精品 | 久久久不卡网国产精品一区 | 黄色在线免费观看 | 欧美不卡| 国产日韩精品一区 | 欧美久久一级特黄毛片 | 一二三四在线视频观看社区 | 亚洲女优在线播放 | 成人综合一区 | 亚洲高清中文字幕 | 岛国毛片 | 天天插日日操 | 久久亚洲精品国产精品紫薇 | 一区二区成人 | 国产剧情一区 | 日韩欧美一级片 | 欧美精品一区二区免费 | 中文字幕久久精品 | 国产精品亚洲综合 | 男女精品久久 | 成人三级视频 | 精品在线免费观看视频 | 欧美日韩成人影院 | 黑人精品欧美一区二区蜜桃 | 国产伦精品一区二区三区精品视频 | 日本天天操 | 欧美精品一区二区三区在线播放 | 亚洲精品一区二区在线 | 一区二区三区中文字幕 | 亚洲精品1 | 精品视频网| 国产99在线 | 欧美 | 日本成人午夜影院 | 亚洲黄色av | 亚洲一区精品在线 |