单片机C语言开发学习笔记---动态的数码管

本文探讨了在使用按键控制数码管时遇到的问题,即按键按下时第一位数码管熄灭的现象,并提供了修改后的代码示例及解决方案。文章还讨论了可能存在的问题及原因推测。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在郭天祥的那本书中,有一个通过按键控制数码管的例子,在运行这个例子的时候,我发现当按键按下的时候,第一位数码管会熄掉,这是为什么呢?
后来在网上找到了原因,当我按下按键不松开的时候,接下来要运行的代码会阻塞,因为多位数码管是动态扫描显示的,所以就会发生上述问题。

修改后的代码如下(未验证)

#include "mylib.h"
#include <reg52.h>

#define uchar unsigned char
#define uint unsigned int


/**
 * Global Value
 */
sbit key1 = P3 ^ 4; //increase the number
sbit key2 = P3 ^ 5; //decrease the number
sbit key3 = P3 ^ 6; //start
sbit key4 = P3 ^ 7; //clear

uchar key1Flag = 0;
uchar key2Flag = 0;
uchar key3Flag = 0;
uchar key4Flag = 0;

sbit dula = P2 ^ 6;
sbit wula = P2 ^ 7;

uchar numt0, num;
uchar pressed = 0;

void Init();
void ScanKey();
void Display(uchar numdis);

void main()
{
    Init();
    while (1)
    {
        ScanKey();
        Display(num);
    }
}

void Init()
{
    TMOD = 0x01;        //set the counter mode
    TH0 = (65536 - 45872) / 256;
    TL0 = (65536 - 45872) % 256;
    EA = 1;
    ET0 = 1;
}
void ScanKey()
{
    if (key1 == 0)
    {
        Delay(10);
        if ((key1 == 0))
        {
            key1Flag = 1;

        }
    }
    else if (key1 == 1)
    {
        if (key1Flag == 1)
        {
            key1Flag = 0;
            num++;
            if (num == 60)
            {
                num = 0;
            }
        }
    }

    if (key2 == 0)
    {
        Delay(10);
        if ((key2 == 0))
        {
            key2Flag = 1;
        }

    }
    else if (key2 == 1)
    {
        if (key2Flag == 1)
        {
            key2Flag = 0;
            if (num == 0)
            {
                num = 60;
            }
            num--;
        }
    }
    if (key3 == 0)
    {
        Delay(10);
        if ((key3 == 0) && (pressed == 0))
        {
            pressed = 1;
            num = 0;
        }

    }
    else
    {
        if (pressed == 1)
        {
            pressed = 0;
        }
    }
    if (key4 == 0)
    {
        Delay(10);
        if ((key4 == 0) && (pressed == 0))
        {
            pressed = 1;
            TR0 = ~TR0;
        }

    }
    else
    {
        if (pressed == 1)
        {
            pressed = 0;
        }
    }
}

void Display(uchar numdis)
{
    uchar tens, ones;
    tens = numdis / 10;
    ones = numdis % 10;

    dula = 1;
    P0 = digCode[tens];
    dula = 0;

    P0 = 0xff;

    wula = 1;
    P0 = 0xef;
    wula = 0;
    Delay(4);

    dula = 1;
    P0 = digCode[ones];
    dula = 0;

    P0 = 0xff;

    wula = 1;
    P0 = 0xdf;
    wula = 0;
    Delay(4);
}

void T0_time() interrupt 1
{
    TH0 = (65536 - 45872) / 256;
    TL0 = (65536 - 45872) % 256;
    numt0++;
    if (numt0 == 20)
    {
        numt0 = 0;
        num++;
        if (num == 60)
        {
            num = 0;
        }
    }
}

原谅我没加上注释,毕竟这段代码还是不够完美。

解决方案详解

当第一次扫描到按键按下的信号,延时10ms(去抖),再次判断信号是否存在,如果存在,设置该按键的被按下的旗帜为1。在没有检测到按键按下的信号的时候,判断该按键的被按下的旗帜是否为1,如果是的话,执行按键的功能,否则,继续检测下一个按键

仍然存在的问题

第一位的数码管在按键按下的时候会变暗

推测的原因

扫描函数又臭又长,可能导致第一位数码管的扫描显示间隔比较大

转载于:https://www.cnblogs.com/JacZhu/p/5486542.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值