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


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

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

    #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,如果是的话,执行按键的功能,否则,继续检测下一个按键

    仍然存在的问题

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

    推测的原因

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

  • 相关阅读:
    Django 框架 # 51
    Django 框架 介绍# 51
    前端之Bootstrap框架 # 50
    phpcms调用一个指定的栏目的url和栏目名称
    phpcms导航栏调用二级栏目
    彻底弄懂JS的事件冒泡和事件捕获
    toggle 方法的使用
    关于内层DIV设置margin-top不起作用的解决方案
    phpmyadmin导入数据库大小限制修改
    phpcms v9 的表单向导功能的使用方法
  • 原文地址:https://www.cnblogs.com/JacZhu/p/5486542.html
Copyright © 2020-2023  润新知