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

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 1657|回復: 13
收起左側

單片機點燈程序,按鍵進入中斷后,就一直反復執行,跳不出來了

[復制鏈接]
ID:53813 發表于 2023-11-23 08:55 | 顯示全部樓層 |閱讀模式
如下,邏輯上感覺沒錯啊, 10ms ,中斷一次,0.5S燈閃一次, temp+1,累計到時間,判斷與設定的一樣補,一樣執行,不一樣,判斷下一個,都不一樣,繼續等待 ,找不到問題在哪了,求大佬來了

單片機源程序如下:
#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; //按鍵次數,初始值為1  
unsigned char count_status = 0; //倒計時狀態,初始值為1,表示倒計時未開始  
unsigned char count_select = 0; //倒計時選擇,初始值為1,表示選擇1分鐘倒計時  
unsigned int count = 0; //計數器,初始值為0,表示倒計時未開始   
unsigned int temp = 0; //計數器值暫存,初始值為0, COUNT計到1000,Ttemp 加1

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


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

// KEY2中斷服務程序,用于處理倒計時邏輯


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

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

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


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

        LED1=1;                        //先關燈
        LED2=1;
        LED3=1;
        LED4=1;
        
        
        //P3
        //P30,P31,P32,P33,P36,P37設置為推挽輸出
        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;                        //定時器時鐘12T模式
        T2L = 0xF0;                                //設置定時初始值
        T2H = 0xD8;                                //設置定時初始值
        AUXR |= 0x00;
        //AUXR |= 0x10;                        //定時器2開始計時
        
         
          EA = 1; //開啟總中斷  
        //IE2 |= 0x04;                        //使能定時器2中斷
        IE2 |= 0x00;                        //關閉定時器2中斷
         
          IT0 = 1; //設置INT0的中斷類型 為下降沿觸發
          EX0 = 1; //開啟外部中斷0 P3.2
         
          IT1 = 1; //設置INT1的中斷類型 為下降沿觸發
          EX1 = 1; //開啟外部中斷1 P3.3

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

}
回復

使用道具 舉報

ID:161164 發表于 2023-11-23 11:17 | 顯示全部樓層
反復執行啥?跳不出來啥?

IE2 |= 0x00; //關定時器2中斷
AUXR |= 0x00; //定時器2關閉計時
這兩句是沒作用的
2023-11-23_111534.png


回復

使用道具 舉報

ID:275826 發表于 2023-11-23 11:56 | 顯示全部樓層
if(key_count < 3)                 { //如果按鍵次數小于3次                   key_count++; //按鍵次數加1                   if(key_count == 1)                                 { //如果按了一次按鍵                                 LED1 = 0; LED2 = 1; LED3 = 1;                     count_select = 2; //選擇2分鐘倒計時                       //count = 120; //設置倒計時為2分鐘                           }                    else if(key_count == 2)                                 { //如果按了兩次按鍵                                 LED1 = 1; LED2 = 0; LED3 = 1;                     count_select = 3; //選擇3分鐘倒計時                       //count = 180; //設置倒計時為3分鐘                           }                    else if(key_count == 3)                                 { //如果按了三次按鍵                                   LED1 = 1; LED2 = 1; LED3 = 0;                     count_select = 1; //重置倒計時選擇為1分鐘                       //count = 60; //設置倒計時為1分鐘                           }               }
回復

使用道具 舉報

ID:275826 發表于 2023-11-23 12:08 | 顯示全部樓層
邏輯錯誤
回復

使用道具 舉報

ID:53813 發表于 2023-11-23 12:31 | 顯示全部樓層
lkc8210 發表于 2023-11-23 11:17
反復執行啥?跳不出來啥?

IE2 |= 0x00; //關定時器2中斷

就是反復執行 LED4 0.5S閃一下 時間到了也 跳不出中斷,  就 不能執行原先設定的倒計時時間,  比如,我上電默認是一分鐘, 按KEY2后,定時器中斷打開,0.5S燈翻一下, 原本按照邏輯應該是一分鐘后,關中斷,倒計時結束,對應引腳輸出信號。現在就卡在中斷里面,一直閃燈,時間到了也不停止。
回復

使用道具 舉報

ID:275826 發表于 2023-11-23 12:51 | 顯示全部樓層
else if ((temp ==240 ) && (count_select == 2))
                                                {
                                                        IE2 |= 0x00; //關定時器2中斷
                                                        AUXR |= 0x00; //定時器2關閉計時
                                                        temp = 0;
                                                        Pin2out_H = 0;        //先輸出低電平
                                                        Pin4out_H = 1;
                                                        count_status = 0; //倒計時結束
                                                }
                                else if( (temp ==360 ) && (count_select == 3))
                                                {
                                                        IE2 |= 0x00; //關定時器2中斷
                                                        AUXR |= 0x00; //定時器2關閉計時
                                                        temp = 0;
                                                        Pin2out_H = 0;        //先輸出低電平
                                                        Pin4out_H = 1;
                                                        count_status = 0; //倒計時結束
                                                } 這些語句都不會執行的
回復

使用道具 舉報

ID:161164 發表于 2023-11-23 14:09 | 顯示全部樓層
三極管一樣的人 發表于 2023-11-23 12:31
就是反復執行 LED4 0.5S閃一下 時間到了也 跳不出中斷,  就 不能執行原先設定的倒計時時間,  比如,我 ...

原因就在于我說的那兩句
回復

使用道具 舉報

ID:53813 發表于 2023-11-23 18:01 | 顯示全部樓層

大佬,請指點下,哪里邏輯錯了,我實際按鍵,也可以切換燈,就是,再按K2啟動后,這時間就亂套了。
回復

使用道具 舉報

ID:53813 發表于 2023-11-23 18:07 | 顯示全部樓層
tyrl800 發表于 2023-11-23 12:51
else if ((temp ==240 ) && (count_select == 2))
              &#1 ...

   額... 我屢屢哈, 先0.5S,燈反一下,  然后,temp 存1,  累積120次,就是 60 000ms ,就是一分鐘, 然后,240次就是2分鐘,360次,就是三分鐘, 嗯, 大于3分鐘就歸零,從新存 。 這個思路沒錯吧?
回復

使用道具 舉報

ID:53813 發表于 2023-11-23 18:08 | 顯示全部樓層
lkc8210 發表于 2023-11-23 14:09
原因就在于我說的那兩句

我又看了規格書的范例, 改用了  IE2 &= ~0x04;    關掉中斷,總算可以結束倒計時了。 現在就是倒計時時間不對, 沒有設想的一分鐘,2分鐘,3分鐘如期實現
回復

使用道具 舉報

ID:275826 發表于 2023-11-23 18:21 | 顯示全部樓層
三極管一樣的人 發表于 2023-11-23 18:07
額... 我屢屢哈, 先0.5S,燈反一下,  然后,temp 存1,  累積120次,就是 60 000ms ,就是一分 ...

你temp==120時,后面temp=0; 永遠不會出現temp==240了
回復

使用道具 舉報

ID:161164 發表于 2023-11-24 09:26 | 顯示全部樓層
三極管一樣的人 發表于 2023-11-23 18:08
我又看了規格書的范例, 改用了  IE2 &= ~0x04;    關掉中斷,總算可以結束倒計時了。 現在就是倒計時時 ...

當一變量會在主循環判斷并在中斷里更新時
該變量應使用8位數據類型,如char,uchar
原因在我的貼子里有討論
http://www.zg4o1577.cn/bbs/dpj-213547-1.html


回復

使用道具 舉報

ID:53813 發表于 2023-11-24 10:32 | 顯示全部樓層
tyrl800 發表于 2023-11-23 18:21
你temp==120時,后面temp=0; 永遠不會出現temp==240了

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

使用道具 舉報

ID:53813 發表于 2023-11-24 10:52 | 顯示全部樓層
lkc8210 發表于 2023-11-24 09:26
當一變量會在主循環判斷并在中斷里更新時
該變量應使用8位數據類型,如char,uchar
原因在我的貼子里有 ...

學習了 ,原來還有這種細節問題。而且,帖子提到的那個前輩,看那段話風格,眼熟,一查果然是江湖人稱鴻哥的早期經驗連載貼
回復

使用道具 舉報

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

本版積分規則

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

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 日韩第一页| 国产日韩欧美一区 | 久久精品国产99国产精品亚洲 | 免费一区在线 | 成年人精品视频在线观看 | 亚洲国产成人精品女人久久久 | 国产精品国产精品国产专区不卡 | 日韩精品在线视频免费观看 | 在线一级片 | 欧美日韩视频在线 | 精品欧美一区二区三区久久久 | 99九九久久 | 日韩在线一区二区三区 | 欧美日韩一区二区在线播放 | 精品国产一区探花在线观看 | 国产精品不卡视频 | 亚洲精品视频网站在线观看 | 91在线精品视频 | 亚洲一区国产精品 | 91精品国产91久久久久久吃药 | 超碰在线播 | 九九久视频| 国产成人在线播放 | 午夜不卡一区二区 | 中文字幕一区二区三区精彩视频 | 欧产日产国产精品v | 成人国产网站 | 狠狠躁天天躁夜夜躁婷婷老牛影视 | 中文字幕免费在线 | av资源中文在线天堂 | 91国在线高清视频 | 国产亚洲精品精品国产亚洲综合 | 亚洲一区久久 | 久草视频在线播放 | 精品视频在线免费观看 | 黄色一级免费观看 | 91免费在线| 91亚洲精品在线 | 男女免费在线观看视频 | 久久久久国产精品一区二区 | 巨大荫蒂视频欧美另类大 |