前言
学习数字管扫描,按键扫描,定时器,中断,三极管,pwm浅试项目后。初始倒计时为2分钟,风速为A,红灯800ms闪烁一次,蓝灯随风速亮度不同,按键控制。按键k控制计时,按后停止倒计时,k2k三是加减分钟,k4退出调时倒计时,未按k1直接按k2k3k4控制风速A(占空比30)B(占空比50)C(占空比70)。
代码思路
使用定时器0和中断1cnt每一ms加一次,1000时清0同时减少倒计时总秒数。pwm利用cnt控制停止转动的结果%(如占空比70就是cnt小于8时通电大于等于8断电。 。按键k2k二键多用(使用)k控制变量a的值 见代码)。数字管扫描中断每11次ms扫描消隐消抖,按钮扫描中断使用16ms连续扫描。代码可以优化按钮扫描的空间for循环简化等,可提高空间为利用串口通信,红外通信控制。
主要问题
1:数码管显示调时,但停止计时
k在计时模块中,按后控制变量值的变化if(某变量==某某)
2:单片机电流无法驱动电机
用三极管放大电流
3:数码管只有一个亮点
使用switch扫描时case写数字要空一格,case当下一次中断时,下一行显示后一个句子的变量。注意这个变量使用局部静态变量或全局变量,否则只能显示一个数字管。case后break句子不能丢失。
4:按键抖动
若启用定时中断,每2次ms进一步中断,扫描按钮状态并存储。连续扫描8次后,查看连续8次的按钮状态是否一致。8个按钮的时间约为16个ms,这16ms如果按钮状态一直一致,可以确定按钮处于稳定阶段,而不是抖动阶段,如图8-12所示。
111111111111111弹起 01001 抖动0000000000000000000000按下 100101 抖动11111111111111111111111弹起
如果左边的时间是0点,每次2点ms左移一次,每移动一次,判断当前连续8次按钮状态是全1还是全0。如果是全1,则判定为弹起,如果是全0,则判定为按下,如果是0和 交错,认为是抖动,不做任何判断。(参考代码)
#include<reg52.h>
sfr P4=0xe8;
sbit ADDR0=P1^0;
sbit ADDR1=P1^1;
sbit ADDR2=P1^2;
sbit ADDR3=P1^3;
sbit ENLED=P1^4;
sbit ENSEG=P1^5;
sbit mada37=P3^7;
sbit led_lan=P3^6;
sbit led_hong=P3^5;
sbit key_in1=P4^3;
sbit key_in2=P3^2;
sbit key_in3=P4^1;
sbit key_in4=P2^3;
sbit key_out1=P2^4;
sbit key_out2=P2^5;
sbit key_out3=P2^6;
sbit key_out4=P2^7;
unsigned char ledcode[10]={0x03,0x9f,0x25,0x0d,0x99,0x49,0x41,0x1f,0x01,0x09}; ///数字管显示转换表0123456789
unsigned char ledcode2[10]={0x02,0x9e,0x24,0x0c,0x98,0x48,0x40,0x1e,0x00,0x08};
unsigned char ledcode8[4]={0x11,0x01,0x63,0xff};
unsigned char led[5]={0x03,0x24,0x03,0x03,0x11};
unsigned int sec=120;
unsigned char flag1s=0;
unsigned char a=0;
unsigned char m=0;
unsigned int i;
bit key3sta=1;
bit key2sta=1;
bit key4sta=1;
bit key1sta=1;
void led_chang();
void main()
{
bit key1backup=1;
bit key2backup=1;
bit key3backup=1;
bit key4backup=1;
unsigned int h=100;
EA=1;
ENLED=1;
ENSEG=0;
ADDR3=1;
mada37=0; //1时停,0时转
TMOD=0x01;
TH0=0xfc;
TL0=0x67;
ET0=1;
TR0=1;
key_out4=0;
key_out3=1;
key_out2=1;
key_out1=1;
led_hong=0;
led_lan=1;
while(1)
{
if(key1sta!=key1backup)
{
if(key1backup==0)
a=1;
key1backup=key1sta;
}
if(flag1s==1)
{
if(a==0)
{
flag1s=0;
sec--;
if(sec<=0)
{
m=3;
EA=0;
P0=0xff;
}
}
led[0]=ledcode[sec/60/10];
led[1]=ledcode2[sec/60];
led[2]=ledcode[sec`/10];
led[3]=ledcode[sec`];
led[4]=ledcode8[m];
}
if(i==800)
led_hong=1;
if(i>=900)
led_hong=0;
if(a==0)
{
nbsp; if(key4sta!=key4backup)
{
if(key4backup==0)
m=2;
key4backup=key4sta;
}
if(key2sta!=key2backup)
{
if(key2backup==0)
m=0;
key2backup=key2sta;
}
if(key3sta!=key3backup)
{
if(key3backup==0)
m=1;
key3backup=key3sta;
}
}
if(m==0) //2o
{
if((i%10)<=3)
{mada37=0;
led_lan=1; }
if((i%10)>3)
{ mada37=1;
led_lan=0;}
}
if(m==1) //50
{
if((i%2)==0)
{mada37=1;
led_lan=0;}
if((i%2)==1)
{mada37=0;
led_lan=1;}
}
if(m==2) //70
{
if((i%10)<=7)
{mada37=0;
led_lan=1;}
if((i%10)>7)
{mada37=1;
led_lan=0;}
}
if(m==3) //0
{
mada37=1;
led_lan=0;
}
if(a==1)
{
if(key4sta!=key4backup)
{
if(key4backup==0)
a=0;
i=0;
key4backup=key4sta;
}
if(key1sta!=key1backup)
{
if(key1backup==0)
m=3;
key1backup=key1sta;
}
if(key2sta!=key2backup)
{
if(key2backup==0)
{
if(sec<=5940)
sec+=60;
}
key2backup=key2sta;
}
if(key1sta!=key1backup)
{
if(key1backup==0)
m=3;
key1backup=key1sta;
}
if(key3sta!=key3backup)
{
if(key3backup==0)
{
if(sec>=60)
sec-=60;
}
key3backup=key3sta;
}
}
}
}
void ledscan()
{
static unsigned char b=0;
P0=0xff;
switch(b)
{
case 0:ADDR0=1;ADDR1=1;ADDR2=1;b++;P0=led[0];break;
case 1:ADDR0=0;ADDR1=1;ADDR2=1;b++;P0=led[1];break;
case 2:ADDR0=1;ADDR1=0;ADDR2=1;b++;P0=led[2];break;
case 3:ADDR0=0;ADDR1=0;ADDR2=1;b++;P0=led[3];break;
case 4:ADDR0=0;ADDR1=0;ADDR2=0;b=0;P0=led[4];break;
}
}
void chongzhi_jishi()
{
TH0=0xfc;
TL0=0x67;
i++;
if(i>=1000)
{
flag1s=1;
i=0;
}
}
void zhongduan0() interrupt 1 //1ms
{
static unsigned char key3keybuf=0xff;
static unsigned char key2keybuf=0xff;
static unsigned char key4keybuf=0xff;
static unsigned char key1keybuf=0xff;
chongzhi_jishi();
ledscan();
key4keybuf=(key4keybuf<<1)|key_in4;
if(key4keybuf==0x00)
{
key4sta=0;
}
else if(key4keybuf==0xff)
{
key4sta=1;
}
key3keybuf=(key3keybuf<<1)|key_in3;
if(key3keybuf==0x00)
{
key3sta=0;
}
else if(key3keybuf==0xff)
{
key3sta=1;
}
key2keybuf=(key2keybuf<<1)|key_in2;
if(key2keybuf==0x00)
{
key2sta=0;
}
else if(key2keybuf==0xff)
{
key2sta=1;
}
key1keybuf=(key1keybuf<<1)|key_in1;
if(key1keybuf==0x00)
{
key1sta=0;
}
else if(key1keybuf==0xff)
{
key1sta=1;
}
}