LED数码管显示独立按键次数

前言

目标

2个独立按键,按下K1,数码管显示的数字加1
按下K2,数码管显示的数字减1

效果

https://www.bilibili.com/video/BV1aXo9YxEhY

原理

  • 独立按键,用于控制数字的加减

  • 把完整的数字,分成若干数位显示

  • 构造一个函数 show_digit(pos,digit) , 可以在指定位置(0<=pos<=7), 显示指定的数(0<=digit<=9)

  • 利用视觉暂留效应,快速遍历一个完整数字的所有位,可以做到“同时”显示多位数字

参考

遇到的问题

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
}
posted @ 2025-03-28 23:24  lucky_doog  阅读(82)  评论(0)    收藏  举报