標(biāo)題: 單片機(jī)點(diǎn)燈程序,按鍵進(jìn)入中斷后,就一直反復(fù)執(zhí)行,跳不出來(lái)了 [打印本頁(yè)]

作者: 三極管一樣的人    時(shí)間: 2023-11-23 08:55
標(biāo)題: 單片機(jī)點(diǎn)燈程序,按鍵進(jìn)入中斷后,就一直反復(fù)執(zhí)行,跳不出來(lái)了
如下,邏輯上感覺(jué)沒(méi)錯(cuò)啊, 10ms ,中斷一次,0.5S燈閃一次, temp+1,累計(jì)到時(shí)間,判斷與設(shè)定的一樣補(bǔ),一樣執(zhí)行,不一樣,判斷下一個(gè),都不一樣,繼續(xù)等待 ,找不到問(wèn)題在哪了,求大佬來(lái)了

單片機(jī)源程序如下:
#include <STC15.H>  

sbit LED1 = P1^0;  
sbit LED2 = P1^1;  
sbit LED3 = P1^2;  
sbit LED4 = P1^3;  
sbit KEY1 = P3^2;  
sbit KEY2 = P3^3;
sbit Pin2out_H = P1^4;        
sbit Pin4out_H = P1^5;
sbit Pin3out_Delay5s_H = P3^6;        
sbit Beer =        P3^7;


unsigned char key_count = 0; //按鍵次數(shù),初始值為1  
unsigned char count_status = 0; //倒計(jì)時(shí)狀態(tài),初始值為1,表示倒計(jì)時(shí)未開(kāi)始  
unsigned char count_select = 0; //倒計(jì)時(shí)選擇,初始值為1,表示選擇1分鐘倒計(jì)時(shí)  
unsigned int count = 0; //計(jì)數(shù)器,初始值為0,表示倒計(jì)時(shí)未開(kāi)始   
unsigned int temp = 0; //計(jì)數(shù)器值暫存,初始值為0, COUNT計(jì)到1000,Ttemp 加1

void delay(unsigned int time) // 延時(shí)函數(shù)  
{  
    unsigned int i,j;  
    for(i=0;i<time;i++)  
        for(j=0;j<1275;j++);  
}  


void key1_ISR() interrupt 0 //按鍵1中斷服務(wù)程序,中斷號(hào)是0  
{  
    if(key_count < 3)
                { //如果按鍵次數(shù)小于3次  
                key_count++; //按鍵次數(shù)加1  
                if(key_count == 1)
                                { //如果按了一次按鍵
                                LED1 = 0; LED2 = 1; LED3 = 1;
                    count_select = 2; //選擇2分鐘倒計(jì)時(shí)  
                    //count = 120; //設(shè)置倒計(jì)時(shí)為2分鐘  
                        }   
                else if(key_count == 2)
                                { //如果按了兩次按鍵
                                LED1 = 1; LED2 = 0; LED3 = 1;
                    count_select = 3; //選擇3分鐘倒計(jì)時(shí)  
                    //count = 180; //設(shè)置倒計(jì)時(shí)為3分鐘  
                        }   
                else if(key_count == 3)
                                { //如果按了三次按鍵  
                                LED1 = 1; LED2 = 1; LED3 = 0;
                    count_select = 1; //重置倒計(jì)時(shí)選擇為1分鐘  
                    //count = 60; //設(shè)置倒計(jì)時(shí)為1分鐘  
                        }  
            }  
    else
                { //如果按鍵次數(shù)超過(guò)3次,重置為1次  
        key_count = 1; //重置按鍵次數(shù)為1次
        LED1 = 0; LED2 = 1; LED3 = 1;
            }  
    KEY1 = 1; //按鍵消抖,防止誤操作,這個(gè)可以在主循環(huán)里面加消抖邏輯或者使用硬件去抖動(dòng)。具體做法根據(jù)你的硬件實(shí)現(xiàn)進(jìn)行編寫。  
}  

// KEY2中斷服務(wù)程序,用于處理倒計(jì)時(shí)邏輯


void key2_ISR() interrupt 2  
{   
        AUXR |= 0x10;                        //定時(shí)器2開(kāi)始計(jì)時(shí)
        IE2 |= 0x04;                        //定時(shí)器2允許中斷
        count_status = 1;                //表示計(jì)時(shí)開(kāi)始

}
void Timer2_ISR() interrupt 12  
{        
        
        Pin2out_H = 1;        //先輸出低電平
        Pin4out_H = 0;
        
        count++;        //10ms加1次
        if (count == 50) //加到500ms,即0.5S時(shí)
                {
                        LED4= ~LED4; //閃燈
                        temp++;  //temp 加1
                        count =0;  // 5次清零一次,重新累計(jì)
                }

}
void main()   
{  
        //M1  M0
                //0   0             準(zhǔn)雙向口--51類型
                //0   1             推挽輸出--適合 輸出真正的高低電平
                //1   0             高阻輸入-- 只能作為  輸入:io口被懸空,沒(méi)有上拉也沒(méi)有下拉,完全由外部電平驅(qū)動(dòng)
                //1   1             開(kāi)漏輸出--適合線與


        //P1
        //P10,P11,P12,P13,P14,P15設(shè)置為推挽輸出  
        P1M1 = 0x00;   //0000 0000
        P1M0 = 0x1F;   //0001 1111

        LED1=1;                        //先關(guān)燈
        LED2=1;
        LED3=1;
        LED4=1;
        
        
        //P3
        //P30,P31,P32,P33,P36,P37設(shè)置為推挽輸出
        P3M1 = 0x00; //0000 0000
        P3M0 = 0xCF; //1100 1111

        KEY1 = 1;  //按鍵先拉高,
        KEY2 = 1;
        Pin2out_H = 0;        //先輸出低電平
        Pin4out_H = 1;
        Pin3out_Delay5s_H = 1; //先輸出低電平
        Beer = 0;                          //先輸出低電平
        
        //10毫秒@12MHz
        AUXR &= 0xFB;                        //定時(shí)器時(shí)鐘12T模式
        T2L = 0xF0;                                //設(shè)置定時(shí)初始值
        T2H = 0xD8;                                //設(shè)置定時(shí)初始值
        AUXR |= 0x00;
        //AUXR |= 0x10;                        //定時(shí)器2開(kāi)始計(jì)時(shí)
        
         
          EA = 1; //開(kāi)啟總中斷  
        //IE2 |= 0x04;                        //使能定時(shí)器2中斷
        IE2 |= 0x00;                        //關(guān)閉定時(shí)器2中斷
         
          IT0 = 1; //設(shè)置INT0的中斷類型 為下降沿觸發(fā)
          EX0 = 1; //開(kāi)啟外部中斷0 P3.2
         
          IT1 = 1; //設(shè)置INT1的中斷類型 為下降沿觸發(fā)
          EX1 = 1; //開(kāi)啟外部中斷1 P3.3

        LED1 = 0;
        count_select = 1;
        
       while (1)
                   { // 主循環(huán)
                        if (temp < 360 )  //如果時(shí)間小于三分鐘
                        {
                                //temp++;  //temp 加1
                                if ((temp ==120 ) && (count_select == 1))
                                                {
                                                        IE2 |= 0x00; //關(guān)定時(shí)器2中斷
                                                        AUXR |= 0x00; //定時(shí)器2關(guān)閉計(jì)時(shí)
                                                        temp = 0;
                                                        Pin2out_H = 0;        //先輸出低電平
                                                        Pin4out_H = 1;
                                                        count_status = 0; //倒計(jì)時(shí)結(jié)束
                                                }
                                
                                else if ((temp ==240 ) && (count_select == 2))
                                                {
                                                        IE2 |= 0x00; //關(guān)定時(shí)器2中斷
                                                        AUXR |= 0x00; //定時(shí)器2關(guān)閉計(jì)時(shí)
                                                        temp = 0;
                                                        Pin2out_H = 0;        //先輸出低電平
                                                        Pin4out_H = 1;
                                                        count_status = 0; //倒計(jì)時(shí)結(jié)束
                                                }
                                else if( (temp ==360 ) && (count_select == 3))
                                                {
                                                        IE2 |= 0x00; //關(guān)定時(shí)器2中斷
                                                        AUXR |= 0x00; //定時(shí)器2關(guān)閉計(jì)時(shí)
                                                        temp = 0;
                                                        Pin2out_H = 0;        //先輸出低電平
                                                        Pin4out_H = 1;
                                                        count_status = 0; //倒計(jì)時(shí)結(jié)束
                                                }
                        }
                else  //如果大于三分鐘
                        {
                                temp = 0;
                                Pin2out_H = 0;        //先輸出低電平
                                Pin4out_H = 1;
                                count_status = 0; //倒計(jì)時(shí)結(jié)束
                        }
               
                if(count_status == 0)
                        {
                                        delay(1);
                                Pin3out_Delay5s_H = 0;
                                }
                }

}

作者: lkc8210    時(shí)間: 2023-11-23 11:17
反復(fù)執(zhí)行啥?跳不出來(lái)啥?

IE2 |= 0x00; //關(guān)定時(shí)器2中斷
AUXR |= 0x00; //定時(shí)器2關(guān)閉計(jì)時(shí)
這兩句是沒(méi)作用的




作者: tyrl800    時(shí)間: 2023-11-23 11:56
if(key_count < 3)                 { //如果按鍵次數(shù)小于3次                   key_count++; //按鍵次數(shù)加1                   if(key_count == 1)                                 { //如果按了一次按鍵                                 LED1 = 0; LED2 = 1; LED3 = 1;                     count_select = 2; //選擇2分鐘倒計(jì)時(shí)                       //count = 120; //設(shè)置倒計(jì)時(shí)為2分鐘                           }                    else if(key_count == 2)                                 { //如果按了兩次按鍵                                 LED1 = 1; LED2 = 0; LED3 = 1;                     count_select = 3; //選擇3分鐘倒計(jì)時(shí)                       //count = 180; //設(shè)置倒計(jì)時(shí)為3分鐘                           }                    else if(key_count == 3)                                 { //如果按了三次按鍵                                   LED1 = 1; LED2 = 1; LED3 = 0;                     count_select = 1; //重置倒計(jì)時(shí)選擇為1分鐘                       //count = 60; //設(shè)置倒計(jì)時(shí)為1分鐘                           }               }
作者: tyrl800    時(shí)間: 2023-11-23 12:08
邏輯錯(cuò)誤
作者: 三極管一樣的人    時(shí)間: 2023-11-23 12:31
lkc8210 發(fā)表于 2023-11-23 11:17
反復(fù)執(zhí)行啥?跳不出來(lái)啥?

IE2 |= 0x00; //關(guān)定時(shí)器2中斷

就是反復(fù)執(zhí)行 LED4 0.5S閃一下 時(shí)間到了也 跳不出中斷,  就 不能執(zhí)行原先設(shè)定的倒計(jì)時(shí)時(shí)間,  比如,我上電默認(rèn)是一分鐘, 按KEY2后,定時(shí)器中斷打開(kāi),0.5S燈翻一下, 原本按照邏輯應(yīng)該是一分鐘后,關(guān)中斷,倒計(jì)時(shí)結(jié)束,對(duì)應(yīng)引腳輸出信號(hào),F(xiàn)在就卡在中斷里面,一直閃燈,時(shí)間到了也不停止。
作者: tyrl800    時(shí)間: 2023-11-23 12:51
else if ((temp ==240 ) && (count_select == 2))
                                                {
                                                        IE2 |= 0x00; //關(guān)定時(shí)器2中斷
                                                        AUXR |= 0x00; //定時(shí)器2關(guān)閉計(jì)時(shí)
                                                        temp = 0;
                                                        Pin2out_H = 0;        //先輸出低電平
                                                        Pin4out_H = 1;
                                                        count_status = 0; //倒計(jì)時(shí)結(jié)束
                                                }
                                else if( (temp ==360 ) && (count_select == 3))
                                                {
                                                        IE2 |= 0x00; //關(guān)定時(shí)器2中斷
                                                        AUXR |= 0x00; //定時(shí)器2關(guān)閉計(jì)時(shí)
                                                        temp = 0;
                                                        Pin2out_H = 0;        //先輸出低電平
                                                        Pin4out_H = 1;
                                                        count_status = 0; //倒計(jì)時(shí)結(jié)束
                                                } 這些語(yǔ)句都不會(huì)執(zhí)行的
作者: lkc8210    時(shí)間: 2023-11-23 14:09
三極管一樣的人 發(fā)表于 2023-11-23 12:31
就是反復(fù)執(zhí)行 LED4 0.5S閃一下 時(shí)間到了也 跳不出中斷,  就 不能執(zhí)行原先設(shè)定的倒計(jì)時(shí)時(shí)間,  比如,我 ...

原因就在于我說(shuō)的那兩句
作者: 三極管一樣的人    時(shí)間: 2023-11-23 18:01
tyrl800 發(fā)表于 2023-11-23 12:08
邏輯錯(cuò)誤

大佬,請(qǐng)指點(diǎn)下,哪里邏輯錯(cuò)了,我實(shí)際按鍵,也可以切換燈,就是,再按K2啟動(dòng)后,這時(shí)間就亂套了。
作者: 三極管一樣的人    時(shí)間: 2023-11-23 18:07
tyrl800 發(fā)表于 2023-11-23 12:51
else if ((temp ==240 ) && (count_select == 2))
              &#1 ...

   額... 我屢屢哈, 先0.5S,燈反一下,  然后,temp 存1,  累積120次,就是 60 000ms ,就是一分鐘, 然后,240次就是2分鐘,360次,就是三分鐘, 嗯, 大于3分鐘就歸零,從新存 。 這個(gè)思路沒(méi)錯(cuò)吧?
作者: 三極管一樣的人    時(shí)間: 2023-11-23 18:08
lkc8210 發(fā)表于 2023-11-23 14:09
原因就在于我說(shuō)的那兩句

我又看了規(guī)格書(shū)的范例, 改用了  IE2 &= ~0x04;    關(guān)掉中斷,總算可以結(jié)束倒計(jì)時(shí)了。 現(xiàn)在就是倒計(jì)時(shí)時(shí)間不對(duì), 沒(méi)有設(shè)想的一分鐘,2分鐘,3分鐘如期實(shí)現(xiàn)
作者: tyrl800    時(shí)間: 2023-11-23 18:21
三極管一樣的人 發(fā)表于 2023-11-23 18:07
額... 我屢屢哈, 先0.5S,燈反一下,  然后,temp 存1,  累積120次,就是 60 000ms ,就是一分 ...

你temp==120時(shí),后面temp=0; 永遠(yuǎn)不會(huì)出現(xiàn)temp==240了
作者: lkc8210    時(shí)間: 2023-11-24 09:26
三極管一樣的人 發(fā)表于 2023-11-23 18:08
我又看了規(guī)格書(shū)的范例, 改用了  IE2 &= ~0x04;    關(guān)掉中斷,總算可以結(jié)束倒計(jì)時(shí)了。 現(xiàn)在就是倒計(jì)時(shí)時(shí) ...

當(dāng)一變量會(huì)在主循環(huán)判斷并在中斷里更新時(shí)
該變量應(yīng)使用8位數(shù)據(jù)類型,如char,uchar
原因在我的貼子里有討論
http://www.torrancerestoration.com/bbs/dpj-213547-1.html



作者: 三極管一樣的人    時(shí)間: 2023-11-24 10:32
tyrl800 發(fā)表于 2023-11-23 18:21
你temp==120時(shí),后面temp=0; 永遠(yuǎn)不會(huì)出現(xiàn)temp==240了

額,我是這樣想的,   我這temp 一直加加, 加到temp==120 滿足時(shí)候,同時(shí)再去判斷 是否還要 同時(shí)滿足 count_select == 1  ,才會(huì)進(jìn)去執(zhí)行,執(zhí)行后,那就歸零。也就是停止計(jì)時(shí)中斷了。
相當(dāng)于要進(jìn)行下一輪按鍵選擇,和開(kāi)始
如果不滿足 就是去判斷下一個(gè)條件, ,如果都不滿足,這個(gè)是temp 已經(jīng)加到 360以上了,
那就歸零,再重頭計(jì)
(經(jīng)過(guò)改了關(guān)定時(shí)器2的語(yǔ)句)
現(xiàn)在最新實(shí)際情況是,這時(shí)間亂倒計(jì)。第二輪還不停。

作者: 三極管一樣的人    時(shí)間: 2023-11-24 10:52
lkc8210 發(fā)表于 2023-11-24 09:26
當(dāng)一變量會(huì)在主循環(huán)判斷并在中斷里更新時(shí)
該變量應(yīng)使用8位數(shù)據(jù)類型,如char,uchar
原因在我的貼子里有 ...

學(xué)習(xí)了 ,原來(lái)還有這種細(xì)節(jié)問(wèn)題。而且,帖子提到的那個(gè)前輩,看那段話風(fēng)格,眼熟,一查果然是江湖人稱鴻哥的早期經(jīng)驗(yàn)連載貼




歡迎光臨 (http://www.torrancerestoration.com/bbs/) Powered by Discuz! X3.1