随着单片机学习深入和实践的增多,我发现总结一下单片机常用的函数和套路对编写程序时有很大的帮助,所以我花了几天时间稍微总结了一下。
流水灯unsigned char LedCharRtoL[]={
0x7F,0xBF,0xDF,0xEF,0xF7,0xFB,0xFD,0xFE
}; //从右向左 (电开)板子数码管真值表
unsigned char LedCharLtoR[]={
0xFE,0xFD,0xFB,0xF7,0xEF,0xDF,0xBF,0x7F
}; //从左向右 (电开)板子数码管真值表
从左向右来回循环①
void main()
{
unsigned char sec = 0; //实际转换时间
unsigned char cnt = 0; //定时器溢出计数变量
ENLED = 0;
P22 = 1;
P21 = 1;
P20 = 0; //设定 38译码器 打开LED总开关
TMOD = 0x01; //设定定时器工作模式
TH0 = 0x2F;
TL0 = 0xAB; //设定定时器初值 令定时器20ms(0.02s)
TR0 = 1; //打开定时器T0
while(1)
{
if(TF0 == 1)
{
TF0 = 0; //溢出标志归零
TH0 = 0x2F;
TL0 = 0xAB; //重置定时器初值
cnt++; //溢出计数加一
if(cnt == 5) //达到目的时间100ms(0.1s)
{
cnt = 0;
P0=LedChar[sec];
sec++;
}
if(sec==15)
{
sec=0;
}
}
}
}
数码管 1100 0000unsigned char LedChar[]={
0xC0,0xF9,0xA4,0xB0,0X99,0x92,0x82,0xF8,0x80,0x90,0x88,0x80,
0xC6,0xC0,0x86,0x8E
};
嗡鸣器#include<reg52.h>
sbit PWMOUT = P1^3;
unsigned char T0RH=0;
unsigned char T0RL=0;
void OpenBuzz(unsigned int frequ);
void StopBuzz();
void main()
{ unsigned int i;
EA = 1;
TMOD = 0x01;
while(1)
{
OpenBuzz(4000);
for(i=0;i<40000;i++);
StopBuzz();
for(i=0;i<40000;i++);
OpenBuzz(1000);
for(i=0;i<40000;i++);
StopBuzz();
for(i=0;i<40000;i++);
}
}
void OpenBuzz(unsigned int frequ)
{
unsigned int reload;
reload = 65536 - (32000000/12)/(frequ*2);//x * 12/频率 = 1/(freq*2)
T0RH = (unsigned char)(reload >> 8);
T0RL = (unsigned char)reload;
TH0 = 0xFF;
TL0 = 0xFE;
ET0 = 1;
TR0 = 1;
}
void StopBuzz()
{
ET0 = 0;
TR0 = 0;
}
void InterruptTimer()interrupt 1
{
TH0 = T0RH;
TL0 = T0RL;
PWMOUT = ~PWMOUT;
}
按键①独立按键 void main()
{
unsigned char backup = 1;
ENLED = 0;
P22 = 1;
P21 = 0;
P20 = 1;
EA = 1;
ET0 = 1;
TMOD = 0X01;
TH0 = 0xEB;
TL0 = 0x2B;
TR0 = 1;
P2 = 0xF7;
P0 = LedChar[cnt];
while(1)
{
if(KeySta != backup)
{
if(backup == 0)
{
cnt++;
if(cnt >= 10)
{
cnt = 0;
}
P0 = LedChar[cnt]; //
}
backup = KeySta;
}
}
}
void InterruptTimer0 () interrupt 1
{
static unsigned char keybuf = 0xFF;
TH0 = 0xEB;
TL0 = 0x2B;
keybuf = (keybuf <<1) |K4; //记录按键微观输出状态
if(keybuf == 0x00)
{
KeySta = 0;//宏观按下
}
else if(keybuf == 0xFF)
{
KeySta = 1;//宏观弹起
}
else
{
}
}
②矩阵按键 void main() { unsigned char i, j; unsigned char backup [4][4] = { {1,1,1,1}, {1,1,1,1}, {1,1,1,1}, {1,1,1,1}, }; EA = 1; ENLED = 0; ADDR3 = 1; ADDR2 = 0; ADDR1 = 0; ADDR0 = 0; TMOD = 0x01; TH0 = 0xFC; TL0 = 0x67; ET0 = 1; TR0 = 1; P0 = LedChar[0]; while(1) { for(i=0; i<4; i++) { for(j=0; j<4; j++) { if(backup[j] != KeySta[j]) { if(backup[j] == 0) { P0 = LedChar[i*4+j]; } backup[j] = KeySta[j]; } } } } } void InterruptTimer0() interrupt 1 { static unsigned char keyout = 0; unsigned char i = 0; static unsigned char keybuf[4][4] = { {0xFF, 0xFF, 0xFF, 0xFF}, {0xFF, 0xFF, 0xFF, 0xFF}, {0xFF, 0xFF, 0xFF, 0xFF}, {0xFF, 0xFF, 0xFF, 0xFF} }; TH0 = 0xFC; TL0 = 0x67; keybuf[keyout][0] = (keybuf[keyout][0] <<1) | KEY_IN_1; keybuf[keyout][1] = (keybuf[keyout][1] <<1) | KEY_IN_2; keybuf[keyout][2] = (keybuf[keyout][2] <<1) | KEY_IN_3; keybuf[keyout][3] = (keybuf[keyout][3] <<1) | KEY_IN_4; //检测第keybuf行 并记录按键微观状态 for(i=0; i<4; i++) { if((keybuf[keyout] & 0x0F) == 0x00) { KeySta[keyout] = 0;//宏观按下 } else if((keybuf[keyout] & 0x0F) == 0x0F) { KeySta[keyout] = 1;//微观弹起 } } keyout++; keyout = keyout & 0x03; switch(keyout) { case 0: KEY_OUT_4 = 1; KEY_OUT_1 = 0; break; case 1: KEY_OUT_1 = 1; KEY_OUT_2 = 0; break; case 2: KEY_OUT_2 = 1; KEY_OUT_3 = 0; break; case 3: KEY_OUT_3 = 1; KEY_OUT_4 = 0; break; default: break; } }
|