常用的单片机裸机非阻塞式框架
软件定时器
1.设置1ms定时器中断,设置变量在定时器中断函数中++/–,以此计数,while(1)中对改变量进行值判断就能得到指定时间。 2.不仅适用于51系列,跑裸机都可以使用此框架,非阻塞式延时。 3.注意MCU的工作频率和机器周期。
unsigned int Cnt1 = 0;
unsigned int Cnt1 = 0;
void main()
{
while(1)
{
if(Cnt1)
{
Cnt1 = 0;
task_1ms();
}
if(Cnt2 >= 10)
{
Cnt2 = 0;
task_10ms();
}
}
}
void timer0() interrupt 1
{
TL0 = 0x1C;
TH0 = 0xFC;
Cnt1 = 1;
Cnt2++;
}
按键扫描消抖
1.机械按键按下会产生抖动,通过非阻塞式的延时去抖。 2.根据不同场景,可以增加双击、组合键等功能,需要代码的评论或私发。 3.最好放在1ms中断函数中,对时间要求高。
void KeyScan(void)
{
static uint Su16TouchKeyCnt = 0;
static bit SbTouchKeyLock = 0;
static bit SbKeyShortPressFlag = 0;
if(!(Tu16CurKey & (0x08)))
{
SbTouchKeyLock = 0;
Su16TouchKeyCnt = 0;
if(SbKeyShortPressFlag)
{
SbKeyShortPressFlag = 0;
}
}
else if(!SbTouchKeyLock)
{
Su16TouchKeyCnt++;
if(Su16TouchKeyCnt >= 20)
{
SbKeyShortPressFlag = 1;
}
if(Su16TouchKeyCnt >= 2000)
{
SbTouchKeyLock = 1;
SbKeyShortPressFlag = 0;
}
}
}
void Key_Task(void)
{
switch或者if判断是哪种类型的按键按下
}
数码管显示
1.假设是共阳双八数码管。 2.假设用按键设置时,数码管闪烁显示。 3.假设是单片机的P2口连接数码管引脚。
void DisplayScan(void)
{
static uchar Su8ScanStep = 0;
if(GbWorkStatus)
{
if(GbLedEnableFlag )
{
P2 = (unsigned char)0xFF;
LED_COM1_CLOSE;
LED_COM2_CLOSE;
switch(Su8ScanStep)
{
case 0:
P2 = Gu8LedDigTableBuf[Gu8LedFirstShowData];
LED_COM1_OPEN;
LED_COM2_CLOSE;
Su8ScanStep++;
break;
case 1:
P2 = Gu8LedDigTableBuf[Gu8LedSecondShowData];
P27 = !GbLedThirdShowEnable;
LED_COM1_CLOSE;
LED_COM2_OPEN;
if(!GbLedFlickerFlag)
{
Gu16LedOffFlickerCnt = 0;
Su8ScanStep = 0;
}
else if(++Gu16LedOffFlickerCnt >= LED_ON_FLICKER_TIME)
{
Gu16LedOffFlickerCnt = 0;
Su8ScanStep++;
}
else
Su8ScanStep = 0;
break;
case 2:
LED_COM1_CLOSE;
LED_COM2_CLOSE;
if(++Gu16LedOnFlickerCnt >= LED_OFF_FLICKER_TIME)
{
Gu16LedOnFlickerCnt = 0;
Su8ScanStep = 0;
}
break;
}
}
else
{
LED_COM1_CLOSE;
LED_COM2_CLOSE;
}
}
}
无源蜂鸣器
1.通电后需要一定震荡频率蜂鸣器才会响。
unsigned int xdata Gu16BuztimerCnt = 0;
#define BUZ_OPEN (Gu16BuztimerCnt = 200)
void BeepTask(void)
{
static bit Su8Buzlock = 0;
static uchar TempCnt = 0;
static uint IntervalCnt = 0;
static SbVoiceIntervalFlag = 0;
if(SbVoiceIntervalFlag == 0 && Gu16BuztimerCnt > 0)
{
if(Su8Buzlock == 0)
{
Su8Buzlock = 1;
TempCnt = Gu16BuztimerCnt;
PWM_Set(Enable,x);
}
else
{
TempCnt--;
if(TempCnt == 0)
{
Gu16BuztimerCnt = 0;
SbVoiceIntervalFlag = 1;
PWM_Set(Disable,x);
Su8Buzlock = 0;
}
}
}
else if(SbVoiceIntervalFlag == 1)
{
IntervalCnt++;
if(IntervalCnt >= 50)
{
IntervalCnt = 0;
SbVoiceIntervalFlag = 0;
Gu16BuztimerCnt = 0;
}
}
}
基础的后续慢更
|