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

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 1596|回復: 9
收起左側

ADC掉電檢測的算法怎么寫,哪個大佬發一個,謝謝

[復制鏈接]
ID:302293 發表于 2024-4-18 16:59 | 顯示全部樓層 |閱讀模式
謝謝大家
回復

使用道具 舉報

ID:1110945 發表于 2024-4-18 20:07 | 顯示全部樓層
不就是掉電檢測嗎,用端口中斷就檢測了的,比adc測量簡單容易多了。
回復

使用道具 舉報

ID:1109793 發表于 2024-4-18 20:37 | 顯示全部樓層
對啊,電容大的話用掃描IO狀態都可以
回復

使用道具 舉報

ID:302293 發表于 2024-4-19 09:45 | 顯示全部樓層
明日之星8 發表于 2024-4-18 20:07
不就是掉電檢測嗎,用端口中斷就檢測了的,比adc測量簡單容易多了。

掉電是有電壓變化的,mcu也是接在電源上的,當電源電壓低于12V時,mcu是可以檢測到ADC電壓值的,但是我用定時器去掃不穩定
回復

使用道具 舉報

ID:302293 發表于 2024-4-19 09:46 | 顯示全部樓層
xiaobendan001 發表于 2024-4-18 20:37
對啊,電容大的話用掃描IO狀態都可以

IO口的電壓是線性變化的,怎么去掃,怎么判斷
回復

使用道具 舉報

ID:1109793 發表于 2024-4-19 10:33 | 顯示全部樓層
sr861126 發表于 2024-4-19 09:46
IO口的電壓是線性變化的,怎么去掃,怎么判斷

我是變壓器供電,在電容前邊加二極管,二極管前的脈動信號經過電阻引入IO,每當IO的低電平時間超過10ms算掉電。或者其他方式也可以,或者二極管前邊加一個小電容濾波一下,就不是脈動信號了,總之都可以,只要在二極管后面的電容放電完成之前檢測到就可以完美保存幾十個字節的數據
回復

使用道具 舉報

ID:302293 發表于 2024-11-28 16:56 | 顯示全部樓層
sr861126 發表于 2024-4-19 09:45
掉電是有電壓變化的,mcu也是接在電源上的,當電源電壓低于12V時,mcu是可以檢測到ADC電壓值的,但是我用 ...

用定時器掃比較穩定,我試過了
回復

使用道具 舉報

ID:427868 發表于 2024-11-28 17:53 | 顯示全部樓層
STC的單片機有低壓中斷,也很好用。
回復

使用道具 舉報

ID:624769 發表于 2024-11-28 20:16 | 顯示全部樓層
單片機檢測掉電的方式往少了說,也有十幾種,其中唯獨定時去用ADC掃描方式是最糟糕的。不說大多數單片機有掉電中斷了,哪怕沒有掉電中斷,隨便用個外部中斷檢測上游供電電平,都比ADC方式強。
回復

使用道具 舉報

ID:1133081 發表于 2024-11-29 06:30 | 顯示全部樓層
sr861126 發表于 2024-11-28 16:56
用定時器掃比較穩定,我試過了


  1. //測試條件:TX-1C實驗板,MCU型號IAP15W4K58S4
  2. //注意:測試本示例時,需在ISP下載時將【低壓復位】功能和【低壓時禁止EEPROM操作】關閉
  3. //說明:本示例采用一個扇區寫滿再擦除的方式是嘗試延長EEPROM使用壽命,如需要頻繁寫
  4. //EEPROM,可改為所有扇區寫滿再擦除的方式。
  5. #include "STC15Fxxxx.H"
  6. #include <intrins.h>                                //庫頭文件
  7. #define uint unsigned int                         //宏定義數據類型uint
  8. #define uchar unsigned char                 //宏定義數據類型uchar
  9. //宏定義ISP的操作命令
  10. #define CMD_IDLE    0               //空閑模式
  11. #define CMD_READ    1               //IAP字節讀命令
  12. #define CMD_PROGRAM 2               //IAP字節編程命令
  13. #define CMD_ERASE   3               //IAP扇區擦除命令
  14. #define ENABLE_IAP  0x82            //CPU的等待時間
  15. #define IAP_ADDRESS 0x0800                        //測試地址
  16. sbit duan=P2^6;
  17. sbit wein=P2^7;
  18. sbit buzzer=P2^3;
  19. //順序共陰極數碼管段碼表,段碼a-h順序接PX0-PX7
  20. uchar code table[]={//共陰數碼管段碼"0~f-."
  21.                 0x3f,0x06,0x5b,0x4f,
  22.                 0x66,0x6d,0x7d,0x07,
  23.                 0x7f,0x6f,0x77,0x7c,
  24.                 0x39,0x5e,0x79,0x71,0x40,0x80};
  25. uchar data dis_buf[8];                //緩存數組
  26. uint num,sec;
  27. uchar i;
  28. uint sign;
  29. void Timer0Init();                                        //定時器初始化聲明
  30. void IapIdle();                                                //關閉IAP/EEPROM
  31. uchar IapReadByte(uint addr);                //讀取EEPROM數據
  32. void IapProgramByte(uint addr, uchar dat);//寫入EEPROM數據
  33. void IapEraseSector(uint addr);                //擦除EEPROM數據

  34. void main()                                                       
  35. {
  36.         P0M0 = 0x00;
  37.         P0M1 = 0x00;
  38.         P1M0 = 0x00;
  39.         P1M1 = 0x00;
  40.         P2M0 = 0x00;
  41.         P2M1 = 0x00;
  42.         P3M0 = 0x00;
  43.         P3M1 = 0x00;
  44.         P4M0 = 0x00;
  45.         P4M1 = 0x00;
  46.         P5M0 = 0x00;
  47.         P5M1 = 0x00;
  48.         P6M0 = 0x00;
  49.         P6M1 = 0x00;
  50.         P7M0 = 0x00;
  51.         P7M1 = 0x00;
  52.         if(IapReadByte(IAP_ADDRESS)==0xff)//如果沒有保存過數據存儲器初始值=0xff
  53.         {
  54.                 IapProgramByte(IAP_ADDRESS, 0);//扇區首地址寫0
  55.                 sec=0;
  56.                 sign=1;
  57.         }
  58.         else
  59.         {
  60. //                for(i=1;i<12;i++)//測試寫10次
  61.                 for(i=1;i<511;i++)//測試寫滿510個字節
  62.                 {
  63.                         if(IapReadByte(IAP_ADDRESS+i)==0xff)//如果遇到沒有保存數據的單元
  64.                         {
  65.                                 sec=IapReadByte(IAP_ADDRESS+i-1);//讀取前一個字節保存的數據
  66.                                 sign=i;//地址緩存
  67.                                 break;//跳出循環
  68.                         }
  69.                 }
  70.         }
  71. //        if(sign==11)//測試寫10次
  72.         if(sign==510)//如果寫滿510
  73.         {
  74.                 IapEraseSector(IAP_ADDRESS);//擦除扇區
  75.                 IapProgramByte(IAP_ADDRESS, 0);//首地址寫0
  76.                 sign=1;
  77.                 buzzer=0;
  78.         }
  79.         PCON &= 0xDF;//清0掉電標志
  80.         ELVD = 1;//開低壓中斷
  81.         EA   = 1;//開總中斷

  82.         Timer0Init();//初始化定時器

  83.         while(1)
  84.         {
  85.                 if(TF0)//查詢T0中斷請求標志
  86.                 {               
  87.                         TF0=0;//T0中斷請求標志清0
  88.                         if(++num>=1000)//1秒
  89.                         {
  90.                                 buzzer=1;
  91.                                 num=0;                               
  92.                                 sec=++sec%250;
  93.                         }
  94.                         dis_buf[0]=table[sec/100%10];
  95.                         dis_buf[1]=table[sec/10%10];
  96.                         dis_buf[2]=table[sec%10];
  97.                         P0=0x00;duan=1;duan=0;
  98.                         P0=~(0x01<<i);wein=1;wein=0;
  99.                         P0=dis_buf[i];duan=1;duan=0;
  100.                         i=++i%3;
  101.                 }//耗時569us
  102.         }
  103. }

  104. void Timer0Init(void)        //1毫秒@11.0592MHz
  105. {
  106.         AUXR |= 0x80;                //定時器時鐘1T模式
  107.         TMOD &= 0xF0;                //設置定時器模式
  108.         TL0 = 0xCD;                        //設置定時初始值
  109.         TH0 = 0xD4;                        //設置定時初始值
  110.         TF0 = 0;                        //清除TF0標志
  111.         TR0 = 1;                        //定時器0開始計時
  112. }
  113. /*----------------------------
  114.         關閉IAP功能
  115. ----------------------------*/
  116. void IapIdle()
  117. {
  118.     IAP_CONTR = 0;                  //關閉IAP功能
  119.     IAP_CMD = 0;                    //清除命令寄存器
  120.     IAP_TRIG = 0;                   //清除觸發寄存器
  121.     IAP_ADDRH = 0x80;               //將地址設置到非IAP區域
  122.     IAP_ADDRL = 0;
  123. }
  124. /*----------------------------
  125. 從ISP/IAP/EEPROM區域讀取一字節
  126. ----------------------------*/
  127. uchar IapReadByte(uint addr)
  128. {
  129.     uchar dat;                       //數據緩沖區

  130.     IAP_CONTR = ENABLE_IAP;         //使能IAP
  131.     IAP_CMD = CMD_READ;             //設置IAP命令
  132.     IAP_ADDRL = addr;               //設置IAP低地址
  133.     IAP_ADDRH = addr >> 8;          //設置IAP高地址
  134.     IAP_TRIG = 0x5a;                //寫觸發命令(0x5a)
  135.     IAP_TRIG = 0xa5;                //寫觸發命令(0xa5)
  136.     _nop_();                        //等待ISP/IAP/EEPROM操作完成
  137.     dat = IAP_DATA;                 //讀ISP/IAP/EEPROM數據
  138.     IapIdle();                      //關閉IAP功能
  139.     return dat;                     //返回
  140. }
  141. /*-------------------------------
  142. 寫一字節數據到ISP/IAP/EEPROM區域
  143. --------------------------------*/
  144. void IapProgramByte(uint addr, uchar dat)
  145. {
  146.     IAP_CONTR = ENABLE_IAP;         //使能IAP
  147.     IAP_CMD = CMD_PROGRAM;          //設置IAP命令
  148.     IAP_ADDRL = addr;               //設置IAP低地址
  149.     IAP_ADDRH = addr >> 8;          //設置IAP高地址
  150.     IAP_DATA = dat;                 //寫ISP/IAP/EEPROM數據
  151.     IAP_TRIG = 0x5a;                //寫觸發命令(0x5a)
  152.     IAP_TRIG = 0xa5;                //寫觸發命令(0xa5)
  153.     _nop_();                        //等待ISP/IAP/EEPROM操作完成
  154.     IapIdle();                      //關閉IAP功能
  155. }
  156. /*----------------------------
  157. ISP/IAP/EEPROM扇區擦除
  158. ----------------------------*/
  159. void IapEraseSector(uint addr)
  160. {
  161.     IAP_CONTR = ENABLE_IAP;         //使能IAP
  162.     IAP_CMD = CMD_ERASE;            //設置IAP命令
  163.     IAP_ADDRL = addr;               //設置IAP低地址
  164.     IAP_ADDRH = addr >> 8;          //設置IAP高地址
  165.     IAP_TRIG = 0x5a;                //寫觸發命令(0x5a)
  166.     IAP_TRIG = 0xa5;                //寫觸發命令(0xa5)
  167.     _nop_();                        //等待ISP/IAP/EEPROM操作完成
  168.     IapIdle();                      //關閉IAP功能
  169. }
  170. void PowerLost() interrupt 6
  171. {

  172.         EA = 0;                                                //關閉總中斷
  173.         P0M1 = 0xff;                                //根據實際硬件環境,設置端口模式減少耗電
  174.         P1M1 = 0xff;
  175.         P2M1 = 0xff;
  176.         P3M1 = 0xff;
  177.         P4M1 = 0xff;
  178.         P5M1 = 0xff;
  179.         P6M1 = 0xff;
  180.         P7M1 = 0xff;
  181.         IapProgramByte(IAP_ADDRESS+sign,sec);//寫數據到EEPROM
  182.         while((PCON & 0x20) != 0)         //復查低壓標志
  183.         {
  184.                 PCON &= 0xDF;                  //清除低壓標志
  185.                 _nop_();               
  186.                 _nop_();                            //坐等掉電
  187.         }
  188.         IAP_CONTR = 0x20;                 //發現是誤報,重啟單片機,恢復正常工作
  189. }
復制代碼



回復

使用道具 舉報

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

本版積分規則

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

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 99爱在线 | 国产视频不卡一区 | 99视频免费播放 | 天天操网| 欧美在线视频a | 国产三级 | 中文字幕91| 亚洲视频一区在线观看 | 免费国产一区二区 | 国产精品免费观看视频 | 久久久久久久久久久久久9999 | 久久精品一区二区 | 久久久高清 | 亚洲视频在线看 | 亚洲精品在线播放 | 久久久精品综合 | 自拍偷拍第一页 | 免费亚洲网站 | 在线一区二区三区 | 在线观看黄色电影 | 91色视频在线观看 | 成人在线视频一区 | 黄色一级在线播放 | 日韩成人在线免费视频 | 日韩精品一区二区三区中文在线 | 在线视频a | 精品欧美一区二区三区久久久小说 | 成人精品一区二区户外勾搭野战 | 精品美女久久久 | 久久久天堂 | 99久久精品免费看国产小宝寻花 | 亚洲国产aⅴ成人精品无吗 综合国产在线 | 久久久久久高潮国产精品视 | 日本在线免费看最新的电影 | 欧美一区二区综合 | 亚洲国产精品久久久 | 日韩一级二级片 | 久久精品久久久 | 成人午夜网 | 精品一区在线免费观看 | 成年免费大片黄在线观看岛国 |