本帖最后由 QuaX_Chow 于 2024-7-3 15:58 编辑
2024/5/27 新建帖子
声明及本系列注意事项优先阅读:🔗
工程源码及仿真文件入口在文末
任务要求:使用C51实现双按键控制八位数码管滚动十六进制数,反向滚动间隔时间为正向的两倍,一开始无按键按下时不显示
想要实现以上功能,我们需要将任务拆分为以下几个部分:
- ms级定时器
- 数码管扫描函数
- 中断按键判断
延时函数(用于数码管余辉)
1.Proteus部分
数字显示使用的是Proteus中的八段共阴数码管,型号为:7SEG-MPX-8-CC-BLUE:
搭建好的仿真电路如下。红框为基础电路,外部中断0与按键之间使用与门且拉高:
2.代码部分
阳极连接的是P0口,需要在扫描函数中将每个十六位进制数对应的字段码
字段码如下:
smg[16]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};
而阴极连接单片机对应的片选代码如下:
unsigned char code yang[8]={0xFE, 0xFD, 0xFB, 0xF7, 0xEF, 0xDF, 0xBF, 0x7F};
声明uint类型的direct变量用于判断方向。在main函数中实现数码管扫描的仿真效果更好。
void main()
{
unsigned char i;
unsigned int k;
init();
Timer0Init();
direct = 2;//初始无滚动方向
while(1)
{
while(direct == 0)
{
flag = 0;
while(direct == 0)
{
for(i=0;i<8;i++)
{
k = flag+i;
if( flag+i >= 16) k -= 16;
choose = yang[i];
show = smg[k];
delay(1);
}
}
}
while(direct == 1)
{
flag = 16;
while(direct == 1)
{
for(i=0;i<8;i++)
{
k = flag+i;
if( flag+i < 0) k += 16;
if( flag+i >= 16) k -= 16;
choose = yang[i];
show = smg[k];
delay(1);
}
}
}
}
}
参考中断表编写中断服务函数,外部中断0的中断号为0,定时器0为1:
外部中断0的中断函数中对按键进行了判断,仿真电路无需消抖:
void change() interrupt 0// using 0
{
// do{
// key();
// }while(j == 1); //中断函数,当按键按下时中断
// if(P3_2 == 0)
// {
if(P1_6 == 0) direct = 0;
if(P1_7 == 0) direct = 1;
// }
}
定时器提供数码管刷新基准(flag),每当基准达到15则清零,反向滚动计数值为正向的两倍:
void intp1() interrupt 1
{
jm++;
if(direct == 0)
{
if(jm == 12)
{
TF0 = 0;
flag++;
if(flag==16) flag = 0;
jm = 0;
}
}
if(direct == 1)
{
if(jm == 24)
{
TF0 = 0;
flag--;
if(flag==0) flag = 16;
jm = 0;
}
}
}
最终效果如下:
任务完成
2024/7/3
源码以及仿真文件
#本文首发于EEWORLD,版权归作者所有