如下,邏輯上感覺沒錯啊, 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;
}
}
}
|