独立按键和一位闪烁的数码管
本文主要内容:使用Proteus设计单片机外围电路图并模拟最终效果。用动态显示的方法点亮四位极数码管,有一位需要以固定频率闪烁。另有四个按键分别为KS0~KS3,按下KS1将使闪烁的数位循环右移,按下K2将使闪烁数位的数字加一,达到0x0F时归零。
Proteus设计图:
说明:数码管位选信号输出时将被取反;按键按下时引脚为“0”;80C51单片机频率是12MHz;数码管共阴极(CC);设计图只为验证逻辑功能,无实际考量。
C语言代码:
#includeunsigned char code SegCode[16] = { 0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07, 0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71
}; unsigned char Numbers[4]; #define BlinkON 1 #define BlinkOFF 0 unsigned char BlinkStatus, BlinkGrid;
void BtnRoutine_K0() {} void BtnRoutine_K1() { BlinkGrid += 1; BlinkGrid &= 0x03; } void BtnRoutine_K2() { Numbers[BlinkGrid] += 1; Numbers[BlinkGrid] &= 0x0F; } void BtnRoutine_K3() {} void (*KeyRoutines[4])(void) = { BtnRoutine_K0, BtnRoutine_K1, BtnRoutine_K2, BtnRoutine_K3 }; int main() { unsigned char i, j, KeyBitMap, LastKeyBitMap = 0; for (i = 0; i < 4; i++) Numbers[i] = 0; BlinkStatus = BlinkOFF; BlinkGrid = 0; P0 = 0; P2 = 0xF0; TMOD = 1; TH0 = 0xD8; TL0 = 0xF0; ET0 = 1; TR0 = 1; EA = 1; while (1) { P2 |= 0xF0; KeyBitMap = (~P2) >> 4; for (i = 0; i < 4; i++) { j = 0x01 << i; if (KeyBitMap & j){ if (!(LastKeyBitMap & j)) LastKeyBitMap |= j; }else if (LastKeyBitMap & j){ KeyRoutines[i](); LastKeyBitMap &= ~j; } } } } void Timer0_Routine() interrupt 1 { static unsigned char Cnt10ms = 0; static unsigned char WhichLed = 0; TH0 = 0xD8; TL0 = 0xF0; if (++Cnt10ms == 30) { BlinkStatus = ~BlinkStatus; Cnt10ms = 0; } if (WhichLed == BlinkGrid && BlinkStatus == BlinkOFF) { P0 = 0; P2 = 0xF0 | (0x01 << BlinkGrid); P0 = 0; } else { P0 = 0; P2 = 0xF0 | (0x01 << WhichLed); P0 = SegCode[Numbers[WhichLed]]; } WhichLed = (WhichLed + 1) & 0x03; }