你所遇到的問(wèn)題的確可能是因?yàn)樵趫?zhí)行 display_sos() 函數(shù)時(shí),按鍵掃描沒有被及時(shí)處理,導(dǎo)致按第三下按鍵時(shí),LED沒有熄滅。這個(gè)問(wèn)題的根本原因是按鍵處理函數(shù)在 display_sos() 運(yùn)行時(shí)沒有機(jī)會(huì)執(zhí)行,因?yàn)槟愕拇a是單線程順序執(zhí)行的。display_sos() 函數(shù)中包含了長(zhǎng)時(shí)間的延時(shí)操作,導(dǎo)致在這段時(shí)間內(nèi)程序不能響應(yīng)按鍵的變化。
要解決這個(gè)問(wèn)題,可以采用中斷處理或者使用一個(gè)狀態(tài)機(jī)來(lái)管理LED的狀態(tài),而不是在 display_sos() 函數(shù)中使用阻塞延時(shí)。以下是使用狀態(tài)機(jī)的方法的簡(jiǎn)化思路:
1. 移除阻塞的延時(shí)將阻塞延時(shí)改為非阻塞計(jì)數(shù)器方式,這樣主循環(huán)可以繼續(xù)檢查按鍵狀態(tài)。
2. 使用狀態(tài)機(jī)使用狀態(tài)機(jī)來(lái)管理LED的不同狀態(tài)(比如長(zhǎng)亮、SOS、熄滅),并根據(jù)按鍵的狀態(tài)來(lái)切換。
代碼實(shí)現(xiàn) #include <STC8.h>
#include <intrins.h>
sbit KEY = P3^5;
sbit LED = P3^4;
unsigned int LED_flag = 0;
unsigned int sos_step = 0;
unsigned int delay_counter = 0;
void Init_IO()
{
P0M1 = 0x00; P0M0 = 0x00;
P1M1 = 0x00; P1M0 = 0x00;
P2M1 = 0x00; P2M0 = 0x00;
P3M1 = 0x00; P3M0 = 0x00;
P4M1 = 0x00; P4M0 = 0x00;
P5M1 = 0x00; P5M0 = 0x00;
P6M1 = 0x00; P6M0 = 0x00;
P7M1 = 0x00; P7M0 = 0x00;
}
void Delay10ms()
{
unsigned char i, j, k;
i = 2; j = 56; k = 172;
do { do { while (--k); } while (--j); } while (--i);
}
void LED_SOS_Handler()
{
switch (sos_step)
{
case 0: case 2: case 4:
LED = 1; delay_counter = 20; sos_step++; break; // LED on for 200ms
case 1: case 3: case 5:
LED = 0; delay_counter = 20; sos_step++; break; // LED off for 200ms
case 6: case 8: case 10:
LED = 1; delay_counter = 50; sos_step++; break; // LED on for 500ms
case 7: case 9: case 11:
LED = 0; delay_counter = 50; sos_step++; break; // LED off for 500ms
case 12: case 14: case 16:
LED = 1; delay_counter = 20; sos_step++; break; // LED on for 200ms
case 13: case 15: case 17:
LED = 0; delay_counter = 20; sos_step++; break; // LED off for 200ms
case 18:
delay_counter = 200; sos_step = 0; LED_flag = 3; break; // Wait 2s, then turn off LED
}
}
void display()
{
if (LED_flag == 1)
{
LED = 1; // Turn on LED
}
else if (LED_flag == 2)
{
LED_SOS_Handler(); // Handle SOS signal
}
else if (LED_flag == 3)
{
LED = 0; // Turn off LED
}
}
void KeyScan()
{
if(KEY == 0)
{
Delay10ms();
if(KEY == 0)
{
LED_flag++;
if (LED_flag > 3) LED_flag = 0;
}
while (!KEY);
}
}
void main()
{
Init_IO();
LED = 0;
while (1)
{
KeyScan();
if (delay_counter > 0)
{
delay_counter--;
}
else
{
display();
}
}
}解釋:LED_SOS_Handler() 函數(shù)按步驟控制LED閃爍,實(shí)現(xiàn)SOS信號(hào)。
display() 函數(shù)根據(jù) LED_flag 的值控制LED行為。
延時(shí)計(jì)數(shù)器 delay_counter 用于代替阻塞延時(shí),讓主循環(huán)能繼續(xù)執(zhí)行按鍵掃描。
這種設(shè)計(jì)能夠在處理LED行為的同時(shí),繼續(xù)監(jiān)控按鍵輸入,避免按鍵在特定情況下失效。