LED数码管显示独立按键次数
前言
目标
2个独立按键,按下K1,数码管显示的数字加1
按下K2,数码管显示的数字减1
效果
https://www.bilibili.com/video/BV1aXo9YxEhY
原理
-
独立按键,用于控制数字的加减
-
把完整的数字,分成若干数位显示
-
构造一个函数
show_digit(pos,digit), 可以在指定位置(0<=pos<=7), 显示指定的数(0<=digit<=9) -
利用视觉暂留效应,快速遍历一个完整数字的所有位,可以做到“同时”显示多位数字
参考
-
独立按键控制LED数码管 https://www.cnblogs.com/luckydoog/p/18798811
遇到的问题
1. 超过3位就无法显示
原因是红色框起来的地方,一开始写成了 pos%=3
属于是笔误

2. 残影
原因:根据江科大51单片机的教程,残影问题来自于两次位选之间,段数据未清零,导致第二个位置显示了前一个位置的字符,留下了残影
解决方法:可以通过在两次位选之间,进行 清零 来解决

3. 无法显示 超过 65535 的数
这是由于一开始这里的 digit 只用了 unsigned int 类型

而我们的51单片机上的 unsigned int 只有 16 位,表示范围 是 0 - 65535
解决方法
用 unsigned long 来定义 digit 变量,表示范围是 0 到 232-1
完整代码
#include <REGX52.H>
#include <INTRINS.H>
#define uchar unsigned char
#define uint unsigned int
#define ulong unsigned long
unsigned char led_data[]={
0x3F, //"0"
0x06, //"1"
0x5B, //"2"
0x4F, //"3"
0x66, //"4"
0x6D, //"5"
0x7D, //"6"
0x07, //"7"
0x7F, //"8"
0x6F, //"9"
};
void Delay1ms() ;
void Delay(int t);
void show(ulong digit);
void show_digit(uchar pos, uchar digit);
void main()
{
ulong digit = 0;
while(1){
if(0 == P3_1){
Delay(10);
while(0 == P3_1){
//nop
}
Delay(10);
if(digit<99999999)
{
digit++;
}else{
digit = 0;
}
}
else if(0 == P3_0){
Delay(10);
while(0 == P3_0){
//nop
}
Delay(10);
if(digit>0)
{
digit--;
}else{
digit = 99999999;
}
}
show(digit);
}
}
void Delay1ms() //@11.0592MHz
{
unsigned char i, j;
_nop_();
i = 2;
j = 199;
do
{
while (--j);
} while (--i);
}
void Delay(int t){
int i = 0;
for(i=0;i<t;i++){
Delay1ms();
}
}
void show(ulong digit)
{
unsigned char pos = 0;
do
{
show_digit(pos,digit%10);
digit/=10;
pos++;
}while(digit);
}
void show_digit(uchar pos, uchar digit)
{
static uchar pos_map[][3] = {{0,0,0},{0,0,1},{0,1,0},{0,1,1},
{1,0,0},{1,0,1},{1,1,0},{1,1,1}};
pos %= 8;
P2_2 = pos_map[pos][2];
P2_3 = pos_map[pos][1];
P2_4 = pos_map[pos][0];
digit %= 10;
P0 = led_data[digit];
Delay1ms();
P0 = 0;//clear
}

浙公网安备 33010602011771号