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

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

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

基于STC單片機的繼電器1~9999秒定時斷電器程序 2按鍵+4位共陰數碼管+有源蜂鳴器

[復制鏈接]
跳轉到指定樓層
樓主
ID:57657 發表于 2021-11-6 17:06 | 只看該作者 回帖獎勵 |倒序瀏覽 |閱讀模式
上電后點亮數碼管的所有段碼,且蜂鳴器響,持續1秒。
設定定時時間,按S2加1(長按連加),按S1輸入下一位(長按退回千位)。
時間設定完成后開始倒計時,按下S2暫停(長按3秒復位),再按恢復,按S1無動作。
倒計時結束后顯示 End 蜂鳴器響6下,短按任意鍵返回,如有問題請跟帖回復。
單片機型號:STC任意 (STC89/90除外) 晶振頻率:12Mhz

數碼管掃描/按鍵消抖/長按連加/毫秒延時全部使用定時器中斷實現。
更改不同STC系列的型號,只需更改頭文件,不需要改動程序任何部分。

硬件連接:
按鍵S1                -> P3.0 (低電平按下)
按鍵S2                -> P3.1
有源蜂鳴器        -> P3.2 (低電平鳴叫)
繼電器或MOS管        -> P3.3        (低電平吸合或導通)

0.28~0.56英寸4位共陰數碼管:
段碼        -> P2.0~P2.7
位碼        -> P1.0~P1.3
單片機源程序如下:
  1. #include "STC15.h"
  2. #include "intrins.h"
  3. #define u8 unsigned char
  4. #define u16 unsigned int
  5. #define u32 unsigned long
  6. #define s8 signed char
  7. #define s16 signed int
  8. #define s32 signed long
  9. #define KEY_TIME 25                        //按鍵消抖時間 (毫秒)
  10. #define reset()        IAP_CONTR |= 0x20                //芯片復位
  11. #define feed_dog()  WDT_CONTR |= 0x10   //看門狗喂狗
  12. u8 code nbr[16] = {                //共陰數碼管段碼16進制
  13.     0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71
  14. };
  15. u8 show[4];                //4位數碼管當前顯示的段碼 更改數碼管顯示的段碼 只需更改此數組
  16. u8 wink;                //閃爍的數碼管段碼        0x01: 第一位閃爍 0x02:第二位閃爍 0x04: 第三位閃爍 0x0F:全閃爍 0x00:全不閃爍

  17. sbit P3_0 = P3 ^ 0;                //按鍵S1 (I/O口定義的按鍵未經消抖,請勿在中斷外直接使用)
  18. sbit P3_1 = P3 ^ 1;                //按鍵S2
  19. sbit P3_2 = P3 ^ 2;     //有源蜂鳴器 低電平鳴叫
  20. sbit P3_3 = P3 ^ 3;     //繼電器或MOS管 低電平吸合(導通)
  21. u16 S1_ms, S2_ms;                //按鍵0、按鍵1連續按下的時間 定時器中斷計數此變量 最長65535毫秒 松開清零

  22. u16 delay_ms;  //定時器中斷延時 (毫秒)
  23. u16 time;      //定時時間 (秒)
  24. u16 beep_ms;   //蜂鳴器鳴叫時間 (毫秒)

  25. u16 bdata Bit16 = 0;    //定義16位可位尋址變量
  26. sbit delay = Bit16 ^ 0;      //定時器中斷延時毫秒開關 中斷外置1 延時完中斷內清0
  27. sbit test = Bit16 ^ 1;       //此值為1數碼管全亮 蜂鳴器響 所有按鍵無效 否則正常
  28. sbit S1 = Bit16 ^ 2;         //按鍵0 連續按下N毫秒清0, 松開置1(定時器0中斷消抖)
  29. sbit S2 = Bit16 ^ 3;         //按鍵1 (處理方式與按鍵0相同)
  30. sbit hz10 = Bit16 ^ 4;      //10Hz信號源 (定時器0中斷產生,用于控制數碼管閃爍)
  31. sbit bak = Bit16 ^ 5;       //按鍵長按識別處理用
  32. sbit Beep = Bit16 ^ 6;      //有源蜂鳴器 低電平響
  33. sbit start = Bit16 ^ 7;     //倒計時開關 置1倒計時開始 清0則結束
  34. sbit pause = Bit16 ^ 8;     //1暫停倒計時 0正常
  35. sbit relay = Bit16 ^ 9;     //繼電器或MOS管 低電平吸合(導通) 1秒只能吸合或釋放1次

  36. void InitTimer0() {        //初始化定時器0中斷
  37.     TMOD = 0x01;
  38.     TH0 = 0xFC;
  39.     TL0 = 0x18;
  40.     EA = 1;
  41.     ET0 = 1;
  42.     TR0 = 1;
  43. }

  44. void beep(u16 ms) {     //蜂鳴器鳴叫 參數:鳴叫毫秒
  45.     beep_ms = ms;
  46.     Beep = 0;
  47. }

  48. u16 set_time() {        //設定定時時間
  49.     u8 n = 0;       //0:編輯千位 1:百位 2:十位 3:個位
  50.     u8 o[4];
  51.     o[0] = 0; o[1] = 0; o[2] = 0; o[3] = 0;
  52.     while (1) {
  53.         feed_dog();
  54.         wink = 8 >> n;
  55.         show[0] = nbr[o[0]];
  56.         show[1] = nbr[o[1]];
  57.         show[2] = nbr[o[2]];
  58.         show[3] = nbr[o[3]];
  59.         if (S2 == 0) {                        //S2按下 短按加1
  60.             beep(50);
  61.             if (o[n]++ >= 9) o[n] = 0;
  62.             show[n] = nbr[o[n]];
  63.             delay_ms = 500; delay = 1;
  64.             while (delay && S2 == 0);        //長按延時等待
  65.             while (S2_ms >= 500) {                //按鍵長按,開始連加
  66.                 feed_dog();
  67.                 delay_ms = 125; delay = 1;                //0.125秒連加一次
  68.                 while (delay && S2 == 0);
  69.                 beep(50);
  70.                 if (o[n]++ >= 9) o[n] = 0;
  71.                 show[n] = nbr[o[n]];
  72.             }
  73.             delay = 0;
  74.             delay_ms = 0;
  75.         }

  76.         if (S1 == 0) {                //S1按下
  77.             beep(50);
  78.             n++;                //輸入下一位
  79.             while (S1 == 0) {
  80.                 feed_dog();
  81.                 if (S1_ms >= 1000 && !bak) {                //長按退回編輯
  82.                     beep(50);
  83.                     n = 0;
  84.                     wink = 8 >> n;
  85.                     show[0] = nbr[o[0]];
  86.                     show[1] = nbr[o[1]];
  87.                     show[2] = nbr[o[2]];
  88.                     show[3] = nbr[o[3]];
  89.                     bak = 1;
  90.                 }
  91.             }

  92.             if (bak) {
  93.                 bak = 0;
  94.                 continue;
  95.             }

  96.             if (n >= 4) {                //個位輸入完成
  97.                 wink = 0;
  98.                 return o[0] * 1000 + o[1] * 100 + o[2] * 10 + o[3];

  99.             }
  100.         }
  101.     }
  102.     return 0;
  103. }

  104. void main() {
  105.     u8 i = 0;
  106.     Beep = 1;
  107.     WDT_CONTR = 0x27;           //初始化看門狗
  108.     P1M0 = 0x0F; P1M1 = 0x00;   //P1.0~P1.3強推挽
  109.     P2M0 = 0xFF; P2M1 = 0x00;   //P2.0~P2.7強推挽
  110.     //上電1秒數碼管全亮 蜂鳴器響
  111.     test = 1;
  112.     InitTimer0();
  113.     delay_ms = 1000; delay = 1;
  114.     while (delay);
  115.     test = 0;

  116.     show[0] = nbr[0];
  117.     show[1] = nbr[0];
  118.     show[2] = nbr[0];
  119.     show[3] = nbr[0];

  120.     while (1) {
  121.         relay = 1;
  122.         pause = 0;
  123.         do {        //時間設定
  124.             time = set_time();
  125.         } while (!time);
  126.         time -= 1;
  127.         start = 1;
  128.         relay = 0;
  129.         while (start) {
  130.             feed_dog();
  131.             if (S1 == 0) {      //S1按下蜂鳴器響1下
  132.                 beep(50);
  133.                 while (S1 == 0) {
  134.                     feed_dog();
  135.                 }
  136.             }

  137.             if (S2 == 0) {      //S2按下暫停倒計時
  138.                 beep(50);
  139.                 pause = !pause;
  140.                 relay = pause;
  141.                 while (S2 == 0) {
  142.                     feed_dog();
  143.                     if (pause && S2_ms >= 3000) {       //長按3秒復位
  144.                         _nop_(); _nop_(); _nop_(); _nop_();
  145.                         reset();
  146.                         _nop_(); _nop_(); _nop_(); _nop_();
  147.                     }
  148.                 }
  149.             }

  150.         }
  151.         //倒計時結束
  152.         show[0] = 0x79;     //E
  153.         show[1] = 0x54;     //n
  154.         show[2] = 0x5E;     //d
  155.         show[3] = 0x00;
  156.         for (i = 0; i < 6; i++) {       //蜂鳴器響6下
  157.             delay_ms = 500; delay = 1; while (delay);
  158.             beep(500);
  159.             while (!Beep);
  160.             feed_dog();
  161.         }

  162.         while (1) {
  163.             feed_dog();
  164.             if (S1 == 0 || S2 == 0) {
  165.                 beep(50);
  166.                 while (S1 == 0 || S2 == 0) {
  167.                     feed_dog();
  168.                 }
  169.                 break;
  170.             }
  171.         }
  172.     }
  173. }

  174. void Timer0Interrupt() interrupt 1{         //12Mhz 1mS定時器中斷
  175.     static u8 seg = 0;  //當前正在掃描的數碼管段碼 4位數碼管 范圍:0~3
  176.     static u8 ms1 = 0;
  177.     static u16 ms = 0, ms2 = 0;
  178.     TH0 = 0xFC;
  179.     TL0 = 0x18;
  180.     if (delay && !--delay_ms) {    //延時任意毫秒
  181.         delay = 0;
  182.     }
  183.     //數碼管動態掃描處理
  184.     P1 |= 0xF;          //消影
  185.     P2 = test ? 0xFF : (wink & (1 << (3 ^ seg)) && !hz10 ? 0 : show[seg]);      //段碼
  186.     P1 &= ~(1 << seg);   //位碼
  187.     if (++seg >= 4) seg = 0;

  188.     if (test) {     //測試模式
  189.         S1 = 1; S2 = 1;
  190.         P3_2 = 0;
  191.         return;
  192.     }

  193.     //蜂鳴器處理
  194.     P3_2 = Beep;
  195.     if (!Beep && !--beep_ms) {
  196.         Beep = 1;
  197.     }
  198.     if (++ms1 >= 50) {
  199.         ms1 = 0;
  200.         hz10 = !hz10;
  201.     }

  202.     //按鍵處理
  203.     if (P3_0 == 0) {
  204.         if (S1_ms != 0xFFFF) S1_ms++;
  205.     }
  206.     else {
  207.         S1_ms = 0;
  208.     }

  209.     if (P3_1 == 0) {
  210.         if (S2_ms != 0xFFFF) S2_ms++;
  211.     }
  212.     else {
  213.         S2_ms = 0;
  214.     }

  215.     S1 = !(S1_ms >= KEY_TIME);
  216.     S2 = !(S2_ms >= KEY_TIME);
  217.     //繼電器處理
  218.     if (++ms2 >= 1000) {    //繼電器1秒只能進行1次吸合或釋放,防止頻繁開關導致設備損壞
  219.         ms2 = 0;
  220.         P3_3 = relay;
  221.     }
  222.     //時間倒計時處理
  223.     if (start) {
  224.         if (pause) {
  225.             wink = 0xF;
  226.         }
  227.         else {
  228.             wink = 0;
  229.             if (++ms >= 1000) {
  230.                 ms = 0;
  231.                 show[0] = nbr[time / 1000 % 10];
  232.                 show[1] = nbr[time / 100 % 10];
  233.                 show[2] = nbr[time / 10 % 10];
  234.                 show[3] = nbr[time % 10];

  235.                 if (!time--) {      //倒計時結束
  236.                     start = 0;
  237.                     relay = 1;
  238.                 }
  239.             }
  240.         }

  241.     }


  242. }
復制代碼

評分

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

查看全部評分

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

使用道具 舉報

沙發
ID:849826 發表于 2021-11-6 20:10 | 只看該作者
在這基礎上,有999天倒計時程序嗎?
回復

使用道具 舉報

板凳
ID:57657 發表于 2021-11-29 22:27 | 只看該作者
6313 發表于 2021-11-6 20:10
在這基礎上,有999天倒計時程序嗎?

999天用晶振誤差太大,需要網絡授時以及時間戳計算。
回復

使用道具 舉報

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

本版積分規則

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

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 国产小视频精品 | 日韩欧美中文 | 暖暖成人免费视频 | 国产一区二区影院 | 久久久久国产精品一区 | 黄色免费av | 九九热最新地址 | 久久久久久九九九九九九 | 91亚洲国产成人久久精品网站 | 久久国产精品-久久精品 | 欧美理论在线观看 | 欧美成人免费在线视频 | 精品国产一区二区国模嫣然 | 伊人久久麻豆 | 日韩伦理电影免费在线观看 | 国产亚洲一区在线 | 一级做a | 精品国产一区二区三区性色av | 2020国产在线 | 欧美女优在线观看 | 一级欧美 | 成人网av | av官网在线 | 国产在线精品一区二区三区 | 久草.com | 欧美黄色片 | 日韩精品视频在线播放 | 国产精品久久久久久久久久久久午夜片 | 久久综合狠狠综合久久综合88 | 精品九九九 | 精品国产不卡一区二区三区 | a级大毛片| 91视频网址 | 午夜影视在线观看 | wwwsihu| 久久精品久久久久久 | 久久亚洲国产精品 | 中文字幕国产日韩 | 日本福利在线观看 | 欧美一区二区三区日韩 | 在线观看免费高清av |