基础练习:
1)通过数码管显示当前模式
2)通过独立按键进行模式切换
整体功能介绍:
通过按键 S1,S2,S3,S4 能够控制 89C52RC 单片机的工作模式,每次按下 S1 按键时,单
片机进入模式一;按下 S2 按键时,单片机进入模式二;按下 S3 按键时,单片机进入模式三;
按下 S4 按键时,单片机进入模式四。
四个不同的模式下,89c52 单片机的数码管和 LED 灯有不同的工作状态。
模式 1
当按下独立按键 S1 的时候,左边四个 LED 与右边四个 LED 交替亮灭
模式 2
U2▢▢▢▢02
模式 3
U3▢▢▢▢XX
(其中XX为计时器,要求00-10依次显示)
模式 4
(原为模式三基础上要求LED流水灯)
独立按键控制LED流水灯开关
任务完成记录
模式一
模式一要求左边四个 LED 与右边四个 LED 交替亮灭,只需设置四个LED亮而另外四个灭,设置Delay函数延迟,再P2取反,循环即可。
模式二
模式二要求使用数码管显示,由于是静止显示,只需依次编写各个数码管所需显示的字母或数字即可。
模式三
模式三要求数码管最后两位起计时器的作用,要求以1s的频率依次显示00-10
重点在于1s的把控以及最后两个数码管在第10秒时的数字显示(即第7位显示1,第8位清零)
STC89C52RC的晶振频率为11.0592MHz,即每秒震荡11.0592 * 1 000 000次(11.0592百万次)
12分频后得到每秒有921600个时间周期
每次扫描数码管大约需要1000个时间周期,每次需要扫描4个数码管,那么我们可以得到每秒的扫描次数(921600 / 1000 / 4 = 230.4次)
那么我们可以通过计算扫描次数来得到大致一秒的时间
(以上来自学长总结的简单总结)
模式四
模式四为独立按键控制LED流水灯开关,只需使用P2=~(0x00<<num)即可完成LED灯亮的移动,重点在于按下按键可以控制模式的开关。我们需要判断按键是否再次被按下,以此控制模式的关闭。我们可以命名ledon=1为开,在按键重新被按下时对ledon进行取反,从而关闭LED流水灯。用if编写流水灯的代码即可,可以用delay函数控制流水灯的速度。
需要注意的是,当用按键重新开启LED流水灯时,流水灯会从上次停止的地方重新出发,我们可以在重新开启时令num=0,即可使LED流水灯从头开始。
代码实现
#include <REGX52.H>
unsigned char NixieTable[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x3E};
unsigned char cnt=0,num1=0,num2=0,num3=0;////0, 1, 2, 3, 4, 5, 6, 7, 8, 9, U, -对应的段码
bit ledon = 1;//模式4中LED流水灯开启状态,1表示开,0表示关
unsigned char alonekey_num;
void Delay(unsigned int xms) //@11.0592MHz
{
unsigned char data i, j;
while(xms--)
{
i = 2;
j = 199;
do
{
while (--j);
} while (--i);
}
}
unsigned char alonekey(void)//按键消抖
{
unsigned char alonekey_num=0;
if(P3_1==0){alonekey_num=1;}
if(P3_0==0){alonekey_num=2;}
if(P3_2==0){alonekey_num=3;}
if(P3_3==0){alonekey_num=4;}
return alonekey_num;
}
void alonekey_loop(void)
{
static unsigned char before_num=0,now_num=0;
before_num=now_num;
now_num=alonekey();
if(before_num!=now_num)
{
Delay(20);
}
if(before_num!=0 && now_num==0)
{
alonekey_num=before_num;
}
}
void Nixie(unsigned char Location,Number)//分别传入显示位置、显示内容
{
switch(Location)//选择显示位置
{
case 1:P2_4=1;P2_3=1;P2_2=1;break;
case 2:P2_4=1;P2_3=1;P2_2=0;break;
case 3:P2_4=1;P2_3=0;P2_2=1;break;
case 4:P2_4=1;P2_3=0;P2_2=0;break;
case 5:P2_4=0;P2_3=1;P2_2=1;break;
case 6:P2_4=0;P2_3=1;P2_2=0;break;
case 7:P2_4=0;P2_3=0;P2_2=1;break;
case 8:P2_4=0;P2_3=0;P2_2=0;break;
}
P0=NixieTable[Number];
Delay(1);
P0=0x00;
}
void main()
{
while(1)
{
alonekey();
alonekey_loop();
switch(alonekey_num)
{
case 1:
P2=0xF0;
Delay(300);
P2=~P2;
Delay(300);
break;
case 2:
Nixie(1,10);
Nixie(2,2);
Nixie(7,0);
Nixie(8,2);
break;
case 3:
cnt=0;
while(cnt<=230){
cnt++;
Nixie(1,10);
Nixie(2,3);
Nixie(7,0);
Nixie(8,num1);
if(cnt==230){
num1++;
if(num1==10){
cnt=0;
num1=0;
while(cnt<=230){
cnt++;
Nixie(1,10);
Nixie(2,3);
Nixie(7,1);
Nixie(8,0);
}
}
}
}
break;
case 4:
if(P3_3==0){ //再次检测按键状态
while(P3_3==0);
ledon = !ledon; // 切换流水灯状态
}
if(ledon){
P2=~(0x01<<num3);
Delay(100);
num3++;
if(num3>=8){
num3=0; //如果流水灯重新开启,则重置num3为0,从头开始
}
}else{
P2=~0x00; // 流水灯关闭,所有LED熄灭
}
break;
}
}
}

689

被折叠的 条评论
为什么被折叠?



