找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

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

二個很菜的單片機中斷延時計數(shù)問題請高手指教修正

[復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
ID:280226 發(fā)表于 2020-4-8 20:21 | 只看該作者 回帖獎勵 |倒序瀏覽 |閱讀模式
在一段中斷計數(shù)延時的單片機程序設(shè)計中,被二個很菜的問題困擾著,請高手師傅指教改正。

1、 利用中斷計數(shù)設(shè)計一段8小時的長時間延時程序,計數(shù)滿8小時后繼電器自動接通工作5分鐘,然后重新進入8小時延時程序,如此循環(huán),直至外部打斷使flag_5計時標志為0止。測試時,每個計數(shù)節(jié)用(20*60)*2時(即2分鐘),9節(jié)共18分鐘,可以正常接通繼電器,然后5分鐘后斷開,程序正常執(zhí)行。但當每個計數(shù)節(jié)用(20*60)*54時(即54分鐘,最大也只能設(shè)定為54分鐘,因為最大計數(shù)為65536),按理應(yīng)該在8.1小時后繼電器接通,但實際卻執(zhí)行不了,繼電器始終不接通,不知問題出在哪?請高手指教改正。



if( flag_5==1 )                          //如果計時標志5為1,進入下面8小時延時

         {

                     temp_5++;                      //中斷計數(shù)變時5自+1

            if(temp_5>=(20*60)*54)         //(20*60)為延時1分鐘基數(shù),*54可延時54分鐘

                       {

                            temp_6++;                                                     

                           if(temp_6>=(20*60)*54)

                              {

                               temp_7++;

                                 if(temp_7>=(20*60)*54)

                                    {

                                     temp_8++;

                                      if(temp_8>=(20*60)*54)

                                          {

                                           temp_9++;

                                            if(temp_9>=(20*60)*54)

                                             {

                                                 temp_10++;

                                                  if(temp_10>=(20*60)*54)

                                                   {

                                                    temp_11++;

                                                        if(temp_11>=(20*60)*54)

                                                          {

                                                          temp_12++;

                                                           if(temp_12>=(20*60)*54)

                                                                {

                                                                 temp_13++;

                                                                 if(temp_13>=(20*60)*54)

          {

                                                                      Relay=1;              //上面計數(shù)延時滿山8小時,繼電器接通

                                                                      temp_4=0;

                                                                      temp_5=0;

                                                                      temp_6=0;

                                                                      temp_7=0;

                                                                      temp_8=0;

                                                                      temp_9=0;

                                                                      temp_10=0;

                                                                      temp_11=0;

                                                                      temp_12=0;

                                                                      temp_13=0;

                                                                      flag_5=0;

                                                                      flag_6=1;

                                                                }

                                                            }

                                                       }

                                                 }

                                          }

                                   }

                            }

                     }

              }

        }



       if(flag_6==1)                          //如果計時標位flag_6=1

          {

             temp_6++;                      //中斷變量temp_6+1

             if(temp_6>=(20*60)*54)          //(20*60)為延時1分鐘,*5可延時5分鐘

               {

                     Relay=0;              //繼電器斷開

                     temp_6=0;

                     flag_6=0;             //計時標志6清零

                     flag_5=1;             //計時標志5為1,重新進入上面的循環(huán)

                }

           }

    2、用一段do-while的循環(huán)程序替代上面的九節(jié)計數(shù)環(huán)節(jié),卻延時不了,錯在何處,也請高手師傅指教一下。



if( flag_5==1)                          //如果計數(shù)標志為1,進入下面的循環(huán)環(huán)節(jié)

                   {

                        temp_5=0;

                        temp_6=0;                                 

                        do

                         {                                                     

                             temp_5++;

                             if(temp_5>=(20*60)*54)

                                {

                                  temp_5=0;

                                 temp_6=temp_6+1;   

                                }                           

                          }

                         while(temp_6<=9);
                     }

                if(temp_6>=9)

                  {

                            Relay0=1;              //繼電器接通

flag_5=0;

                           flag_6=1;

                   }

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

使用道具 舉報

沙發(fā)
ID:116773 發(fā)表于 2020-4-8 22:29 | 只看該作者
既然項目最小的計時單位是5分鐘,為什么不設(shè)置一個5分鐘的變量,每隔5分鐘這個變量增1,這樣整個處理過程應(yīng)該會簡化很多。
回復(fù)

使用道具 舉報

板凳
ID:282850 發(fā)表于 2020-4-9 01:30 | 只看該作者
1、把主頻分頻降低,據(jù)各種MCU,有128分頻,設(shè)寄存器就行了
2、用一個變量計中斷次數(shù),不行設(shè)個unsigned long變量,幾個小時不成問題
回復(fù)

使用道具 舉報

地板
ID:213173 發(fā)表于 2020-4-9 08:12 | 只看該作者
給你一個示例,定時精度取決于晶振精度。未經(jīng)實物驗證,只是供參考。如果加上數(shù)碼管顯示和進一步優(yōu)化可以做成倒計時顯示并使計時誤差控制在1秒內(nèi)。
  1. #include <reg51.h>
  2. #define uint unsigned int
  3. #define uchar unsigned char

  4. sbit key=P1^0;
  5. sbit LED=P1^6;
  6. sbit OUT=P1^7;

  7. uchar Cnt50ms=0;sec=0;//50毫秒、秒變量
  8. uint min=0;//分變量
  9. bit flag_5=0;//計時標志

  10. void Timer0Init()        //50毫秒@12.000MHz
  11. {
  12.         TMOD= 0x01;                //設(shè)置定時器模式
  13.         TL0 = 0xB0;                //設(shè)置定時初值
  14.         TH0 = 0x3C;                //設(shè)置定時初值
  15.         TR0 = 1;                //定時器0開始計時
  16.         EA = 1;                //開總中斷
  17.         ET0= 1;                //開定時器0中斷
  18. }
  19. void keyscan()
  20. {
  21.         static bit key_sign=0;//按鍵自鎖標志變量
  22.         static uchar count=0;  //消抖計數(shù)變量               
  23.         if(!key)
  24.         {
  25.                 if(++count>=100 && key_sign==0)
  26.                 {
  27.                         key_sign=1;//自鎖
  28.                         flag_5=~flag_5;//取反
  29.                         if(flag_5==0)
  30.                                 LED=1;//燈熄 定時器停止工作
  31.                         else
  32.                                 LED=0;//燈亮 定時器工作中
  33.                         //清0 為重新計時準備
  34.                         Cnt50ms=0;
  35.                         sec=0;
  36.                         min=0;
  37.                 }
  38.         }
  39.         else//松手
  40.         {
  41.                 count=0;//消抖計數(shù)變量清0
  42.                 key_sign=0;//自鎖標志清0
  43.         }
  44. }

  45. void main()
  46. {
  47.         OUT=0;                 //初始化輸出端口
  48.         Timer0Init();//初始化定時器
  49.         while(1)
  50.         {
  51.                 keyscan();//按鍵掃描
  52.         }
  53. }
  54. /**************中斷服務(wù)程序*****************/
  55. void timer0() interrupt        1
  56. {
  57.         TL0 = 0xB0;                //重裝定時初值
  58.         TH0 = 0x3C;                //重裝定時初值

  59.         if(flag_5==1)
  60.         {
  61.                 Cnt50ms++;                                        //中斷變量Cnt50ms自+1
  62.                 if(Cnt50ms>=20)                                //1秒
  63.                 {
  64.                         Cnt50ms=0;
  65.                         sec++;
  66.                         if(sec>=60)                                //1分
  67.                         {
  68.                                 sec=0;                                //秒計數(shù)
  69.                                 min++;
  70.                         }
  71.                 }
  72.                 if(min<480)                                        //8小時
  73.                         OUT=0;       
  74.                 if(min>=480||min<485)        //8小時與8小時零5分之間
  75.                         OUT=1;       
  76.                 if(min>=485)                                //8小時零5分時間到
  77.                 {//全部清0
  78.                         OUT=0;       
  79.                         Cnt50ms=0;
  80.                         sec=0;
  81.                         min=0;
  82. //                        flag_5=0;//不重復(fù)循環(huán)
  83.                 }
  84.         }
  85. }
復(fù)制代碼
回復(fù)

使用道具 舉報

5#
ID:592807 發(fā)表于 2020-4-9 08:46 | 只看該作者
看著代碼好費勁啊,你就不能將你的temp_5++   temp_6++封裝個函數(shù)調(diào)用一下嗎
回復(fù)

使用道具 舉報

6#
ID:280226 發(fā)表于 2020-4-9 12:15 | 只看該作者
wulin 發(fā)表于 2020-4-9 08:12
給你一個示例,定時精度取決于晶振精度。未經(jīng)實物驗證,只是供參考。如果加上數(shù)碼管顯示和進一步優(yōu)化可以做 ...

非常感謝wulin師傅的無私指導(dǎo),您已多次指導(dǎo),受您啟發(fā),多次受益,均已成功,謝謝您。
回復(fù)

使用道具 舉報

7#
ID:367369 發(fā)表于 2020-4-9 13:14 | 只看該作者
你的測試5分鐘可行對吧;然后在5分鐘的基礎(chǔ)上再定義1個變量    分鐘m;
假設(shè)你的5分鐘技數(shù)count=50時為5分鐘
8小時60*8=480分鐘480/5=96
m=96時;繼電器使能;m=97時;繼電器關(guān)閉使能;
if (count==50)
{
m++;
if(m==96)
使能flag=1;
if(m==97)
{
  使能flag=0;
  m=0;
}
count=0;

}

回復(fù)

使用道具 舉報

8#
ID:280226 發(fā)表于 2020-4-9 21:38 | 只看該作者
game灬boy 發(fā)表于 2020-4-9 13:14
你的測試5分鐘可行對吧;然后在5分鐘的基礎(chǔ)上再定義1個變量    分鐘m;
假設(shè)你的5分鐘技數(shù)count=50時為5分 ...

謝謝指導(dǎo)!
回復(fù)

使用道具 舉報

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

本版積分規(guī)則

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

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

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