找回密碼
 立即注冊(cè)

QQ登錄

只需一步,快速開(kāi)始

搜索
查看: 3706|回復(fù): 2
打印 上一主題 下一主題
收起左側(cè)

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

[復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
ID:57657 發(fā)表于 2021-11-6 17:06 | 只看該作者 回帖獎(jiǎng)勵(lì) |倒序?yàn)g覽 |閱讀模式
上電后點(diǎn)亮數(shù)碼管的所有段碼,且蜂鳴器響,持續(xù)1秒。
設(shè)定定時(shí)時(shí)間,按S2加1(長(zhǎng)按連加),按S1輸入下一位(長(zhǎng)按退回千位)。
時(shí)間設(shè)定完成后開(kāi)始倒計(jì)時(shí),按下S2暫停(長(zhǎng)按3秒復(fù)位),再按恢復(fù),按S1無(wú)動(dòng)作。
倒計(jì)時(shí)結(jié)束后顯示 End 蜂鳴器響6下,短按任意鍵返回,如有問(wèn)題請(qǐng)跟帖回復(fù)。
單片機(jī)型號(hào):STC任意 (STC89/90除外) 晶振頻率:12Mhz

數(shù)碼管掃描/按鍵消抖/長(zhǎng)按連加/毫秒延時(shí)全部使用定時(shí)器中斷實(shí)現(xiàn)。
更改不同STC系列的型號(hào),只需更改頭文件,不需要改動(dòng)程序任何部分。

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

0.28~0.56英寸4位共陰數(shù)碼管:
段碼        -> P2.0~P2.7
位碼        -> P1.0~P1.3
單片機(jī)源程序如下:
  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                        //按鍵消抖時(shí)間 (毫秒)
  10. #define reset()        IAP_CONTR |= 0x20                //芯片復(fù)位
  11. #define feed_dog()  WDT_CONTR |= 0x10   //看門(mén)狗喂狗
  12. u8 code nbr[16] = {                //共陰數(shù)碼管段碼16進(jìn)制
  13.     0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71
  14. };
  15. u8 show[4];                //4位數(shù)碼管當(dāng)前顯示的段碼 更改數(shù)碼管顯示的段碼 只需更改此數(shù)組
  16. u8 wink;                //閃爍的數(shù)碼管段碼        0x01: 第一位閃爍 0x02:第二位閃爍 0x04: 第三位閃爍 0x0F:全閃爍 0x00:全不閃爍

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

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

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

  36. void InitTimer0() {        //初始化定時(shí)器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) {     //蜂鳴器鳴叫 參數(shù):鳴叫毫秒
  45.     beep_ms = ms;
  46.     Beep = 0;
  47. }

  48. u16 set_time() {        //設(shè)定定時(shí)時(shí)間
  49.     u8 n = 0;       //0:編輯千位 1:百位 2:十位 3:個(gè)位
  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);        //長(zhǎng)按延時(shí)等待
  65.             while (S2_ms >= 500) {                //按鍵長(zhǎng)按,開(kāi)始連加
  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) {                //長(zhǎng)按退回編輯
  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) {                //個(gè)位輸入完成
  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;           //初始化看門(mén)狗
  108.     P1M0 = 0x0F; P1M1 = 0x00;   //P1.0~P1.3強(qiáng)推挽
  109.     P2M0 = 0xFF; P2M1 = 0x00;   //P2.0~P2.7強(qiáng)推挽
  110.     //上電1秒數(shù)碼管全亮 蜂鳴器響
  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 {        //時(shí)間設(shè)定
  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按下暫停倒計(jì)時(shí)
  138.                 beep(50);
  139.                 pause = !pause;
  140.                 relay = pause;
  141.                 while (S2 == 0) {
  142.                     feed_dog();
  143.                     if (pause && S2_ms >= 3000) {       //長(zhǎng)按3秒復(fù)位
  144.                         _nop_(); _nop_(); _nop_(); _nop_();
  145.                         reset();
  146.                         _nop_(); _nop_(); _nop_(); _nop_();
  147.                     }
  148.                 }
  149.             }

  150.         }
  151.         //倒計(jì)時(shí)結(jié)束
  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定時(shí)器中斷
  175.     static u8 seg = 0;  //當(dāng)前正在掃描的數(shù)碼管段碼 4位數(shù)碼管 范圍: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) {    //延時(shí)任意毫秒
  181.         delay = 0;
  182.     }
  183.     //數(shù)碼管動(dòng)態(tài)掃描處理
  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) {     //測(cè)試模式
  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秒只能進(jìn)行1次吸合或釋放,防止頻繁開(kāi)關(guān)導(dǎo)致設(shè)備損壞
  219.         ms2 = 0;
  220.         P3_3 = relay;
  221.     }
  222.     //時(shí)間倒計(jì)時(shí)處理
  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--) {      //倒計(jì)時(shí)結(jié)束
  236.                     start = 0;
  237.                     relay = 1;
  238.                 }
  239.             }
  240.         }

  241.     }


  242. }
復(fù)制代碼

評(píng)分

參與人數(shù) 1黑幣 +50 收起 理由
admin + 50 共享資料的黑幣獎(jiǎng)勵(lì)!

查看全部評(píng)分

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

相關(guān)帖子

回復(fù)

使用道具 舉報(bào)

沙發(fā)
ID:849826 發(fā)表于 2021-11-6 20:10 | 只看該作者
在這基礎(chǔ)上,有999天倒計(jì)時(shí)程序嗎?
回復(fù)

使用道具 舉報(bào)

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

999天用晶振誤差太大,需要網(wǎng)絡(luò)授時(shí)以及時(shí)間戳計(jì)算。
回復(fù)

使用道具 舉報(bào)

本版積分規(guī)則

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

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

快速回復(fù) 返回頂部 返回列表