项目场景:

51单片机按下按键在数码管上显示相应的值


问题描述

平常按键检测程序,按下延时消抖,记录一个数字,再按下另一个记录一个数字,然后在一位数码管上显示,就出现了问题。数码管一直显示0 。
下面就是出问题程序,解决方案展示正确程序

#include <regx52.h>
sbit LS_A=P2^2;
sbit LS_B=P2^3;
sbit LS_C=P2^4;
unsigned code Nixie_Value[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x00};
void Delay(unsigned int xms)
{unsigned char i, j;while(xms--){i = 2;j = 239;do{while (--j);} while (--i);}
}
void Nixie(unsigned char location,unsigned char number)
{ switch(location){case 1: LS_A=0;LS_B=0;LS_C=0; break;case 2: LS_A=1;LS_B=0;LS_C=0; break;case 3: LS_A=0;LS_B=1;LS_C=0; break;case 4: LS_A=1;LS_B=1;LS_C=0; break;case 5: LS_A=0;LS_B=0;LS_C=1; break;case 6: LS_A=1;LS_B=0;LS_C=1; break;case 7: LS_A=0;LS_B=1;LS_C=1; break;case 8: LS_A=1;LS_B=1;LS_C=1; break;}P0=Nixie_Value[number];Delay(2);P0=0X00;
}
unsigned char Key()
{unsigned char KeyNumber=0;if(P3_1==0){Delay(20);while(P3_1==0);Delay(20);KeyNumber=1;}if(P3_0==0){Delay(20);while(P3_0==0);Delay(20);KeyNumber=2;}if(P3_2==0){Delay(20);while(P3_2==0);Delay(20);KeyNumber=3;}if(P3_3==0){Delay(20);while(P3_3==0);Delay(20);KeyNumber=4;}return KeyNumber;
}
int main()
{unsigned char value=0;while(1){value=Key();Nixie(1,value);}
}

几个问题:

位选表示哪个数码管 段选表示数码管显示什么
1、在这条语句

 P0=Nixie_Value[number];

后加长延时,不就可以显示了吗?确实可以,但是加上延时,程序卡在这里,如果有按键按下,就检测不到了。
2、延时消隐P0=0x00有什么用?

        P0=Nixie_Value[number];Delay(2);P0=0X00;

这个延时然后清零消影很关键。若不加这两条语句,由于数码管由一个IO控制,所以当位选成功,段选来临。数码管显示该段选。此时程序执行确定下一个位选,上一个的段选会影响下一个段选,因为P0已经赋值,而下一次段选程序还没执行。这样就会出现鬼影。
延时也是必须存在的,不然可能直接就熄灭不显示东西。

原因分析:

程序解读:程序一直在跑。

    while(1){value=Key();Nixie(1,value);}

当按键按下符合某一条语句,进入key()函数的if语句。假如P3_1按下

if(P3_1==0){Delay(20);while(P3_1==0);Delay(20);KeyNumber=1;}

然后延时,程序就卡在这了,继续执行while循环,检测松手,再延时消抖,返回数值。这是数值就是某个数了 (1 2 3 4)其中一个 。
接着跳出key函数,执行下一条语句。

Nixie(1,value);

数码管显示这个数字。在分析数码管显示函数Nixie()。
位选表示哪个数码管 段选表示数码管显示什么
三八译码器选择数码管位选,在给P0赋值确定段选。按键按下确实数码管显示过数字(1 2 3 4),但是又接着熄灭了。因为程序接着执行key();人手不可能连续再按下另一个按键,所以数码管又显示0 。再次按下按键分析同理。


解决方案:

将数码管显示函数放到key();函数里面,实现了功能。同时进行了优化,将位选直接写在main函数while循环之前,然后直接操作P0确定段选即可。并且也没有延时。

#include <regx52.h>
#include "key.h"
sbit LS_A=P2^2;
sbit LS_B=P2^3;
sbit LS_C=P2^4;
unsigned code Nixie_Value[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x00};
void Key()
{unsigned char KeyNumber=0;if(P3_1==0){Delay(20);while(P3_1==0);Delay(20);KeyNumber=1;P0=Nixie_Value[KeyNumber];}if(P3_0==0){Delay(20);while(P3_0==0);Delay(20);KeyNumber=2;P0=Nixie_Value[KeyNumber];}if(P3_2==0){Delay(20);while(P3_2==0);Delay(20);KeyNumber=3;P0=Nixie_Value[KeyNumber];}if(P3_3==0){Delay(20);while(P3_3==0);Delay(20);KeyNumber=4;P0=Nixie_Value[KeyNumber];}
}
int main()
{LS_A=0;LS_B=0;LS_C=0;P0=0x3F;while(1){key();}
}

遇到的几个问题,个人体会

为什么数码管滚动?
因为两个位选之间有延时,延时大了,人眼可分辨出来,其实只能控制一个数码管,上一个亮了然后消影,延时后刚好下一个亮。
发现诀窍:重要、重要、重要
静态数码管几个数码管共同点亮,这是利用人眼分辨率低,其实这些数码管已经经历了亮灭,这个亮然后灭,下一个再亮,延时太低,就会导致以为数码管都一直亮着。
数码管亮度控制,当段选后需要一个延时然后消影。然后在一个延时,下一个点亮(位选确定),这两个延时就导致数码管亮度变化。第一个延时长,第二个短,表示数码管亮的时间长,灭队时间短,有占空比理解,则亮度高,反之亮度很低。详细代码见程序二。
先执行Nixie()函数

         Nixie(i,i);

执行Nixie()函数延时200毫秒。段选后有延时,点亮200毫秒

        P0=Nixie_Value[number];Delay(200);//延时时间要灵活,这是一个变化的值P0=0X00;

两个位选之间100毫秒延时,其实是熄灭100毫秒

            Nixie(i,i);Delay(100);

这两个延时就控制了数码管亮度,亮200灭100
程序一、数码管显示1-8不滚动
因此若想数码管都亮着则需要延时很短,可以消影和位选间没有延时。下面这个程序实现数码管显示1-8

    #include <regx52.h>
sbit LS_A=P2^2;
sbit LS_B=P2^3;
sbit LS_C=P2^4;
unsigned code Nixie_Value[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x00};
void Delay(unsigned int xms)
{unsigned char i, j;while(xms--){i = 2;j = 239;do{while (--j);} while (--i);}
}
void Nixie(unsigned char location,unsigned char number)
{ switch(location){case 1: LS_A=0;LS_B=0;LS_C=0; break;case 2: LS_A=1;LS_B=0;LS_C=0; break;case 3: LS_A=0;LS_B=1;LS_C=0; break;case 4: LS_A=1;LS_B=1;LS_C=0; break;case 5: LS_A=0;LS_B=0;LS_C=1; break;case 6: LS_A=1;LS_B=0;LS_C=1; break;case 7: LS_A=0;LS_B=1;LS_C=1; break;case 8: LS_A=1;LS_B=1;LS_C=1; break;}P0=Nixie_Value[number];Delay(2);//延时时间要灵活,这是一个变化的值P0=0X00;
}
int main()
{unsigned char i=0;while(1){for(i=1;i<=8;i++){Nixie(i,i);}}
}

注意段选和消影之间必须有延时,否则不会亮。

P0=Nixie_Value[number];Delay(2);//延时时间要灵活,这是一个变化的值P0=0X00;

程序二、当延时长时,人眼可观察到,就实现了数码管滚动。逐个显示1-8
其实只是在程序一基础上改了延时,就可以实现滚动和亮度控制

#include <regx52.h>
sbit LS_A=P2^2;
sbit LS_B=P2^3;
sbit LS_C=P2^4;
unsigned code Nixie_Value[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x00};
void Delay(unsigned int xms)
{unsigned char i, j;while(xms--){i = 2;j = 239;do{while (--j);} while (--i);}
}
void Nixie(unsigned char location,unsigned char number)
{ switch(location){case 1: LS_A=0;LS_B=0;LS_C=0; break;case 2: LS_A=1;LS_B=0;LS_C=0; break;case 3: LS_A=0;LS_B=1;LS_C=0; break;case 4: LS_A=1;LS_B=1;LS_C=0; break;case 5: LS_A=0;LS_B=0;LS_C=1; break;case 6: LS_A=1;LS_B=0;LS_C=1; break;case 7: LS_A=0;LS_B=1;LS_C=1; break;case 8: LS_A=1;LS_B=1;LS_C=1; break;}P0=Nixie_Value[number];Delay(200);//延时时间要灵活,这是一个变化的值P0=0X00;
}
int main()
{unsigned char i=0;while(1){for(i=1;i<=8;i++){Nixie(i,i);Delay(100);}}
}

51单片机按键值显示在数码管上,数码管亮度控制,数码管显示原理相关推荐

  1. 利用51单片机+hc595芯片配合在led点阵上玩贪吃蛇 第一篇“显示贪吃蛇”

    利用51单片机+hc595芯片配合在led点阵上玩贪吃蛇 第一篇"显示贪吃蛇" 完整的项目链接: https://github.com/linxinloningg/51_chip_ ...

  2. 单片机c语言的按键程序,51单片机按键扫描C程序

    原标题:51单片机按键扫描C程序 大二上学期做过80 的按键程序,当时项目要求实现按键控制 屏显示并且接收GPRS传来的数据.当时为了节省成本,就去大西电子市场买来8*8的LED块,然后自己一点一点的 ...

  3. 【Proteus仿真】51单片机+按键控制步进电机驱动+LCD1602显示

    [Proteus仿真]51单片机+按键控制步进电机驱动+LCD1602显示 Proteus仿真 在Proteus当中,步进电机选取的不同,接线的顺序不同,为了避免在接线出错,将里面的两种步进电机都选择 ...

  4. 51单片机按键消抖方式总结

    尊重他人劳动成果,请勿转载!!! 电路图如下: MCU采用89C52单片机,晶振12MHZ. 1.没有消除抖动的原始代码: #include <REGX52.H> #include < ...

  5. 51单片机按键亮灯汇编,作者刚刚开始学习汇编

    提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 51单片机按键亮灯 总结 51单片机按键亮灯 ORG 0000HLCALL DEFLCALL ABCLCALL BCDLCA ...

  6. 利用51单片机+hc595芯片配合在led点阵上玩贪吃蛇 第二篇“自动运行函数”

    利用51单片机+hc595芯片配合在led点阵上玩贪吃蛇 第二篇"自动运行函数" 完整的项目链接: https://github.com/linxinloningg/51_chip ...

  7. 51单片机按键控制数码管显示0-9

    实验题目:使用51单片机设计两个按键控制数码管显示0-9,当K1按下减1,当K2按下加1. 理解程序可参考我的另外两个文章; 51单片机数码管显示0-9_学习笔记吧的博客-CSDN博客 51单片机独立 ...

  8. 普中51单片机按键-数码管显示

    基于普中单片机按键-数码管显示 简介 1.硬件部分 普中单片机开发板 数码管 独立按键 2.软件部分 keil软件 硬件部分 普中单片机开发板 数码管 独立按键 (这些都是开发板的最基本的配置) 软件 ...

  9. 51单片机按键扫描程序汇编程序(独立按键与矩阵按键)(使用定时器)(可移植的汇编程序)矩阵键盘控制两个led数码管(汇编语言)与UART通信总结(上)

    一,按键控制数码管 1四按键控制程序(汇编) (您的关注点赞是作者创作的最大动力哦) //******************************************************* ...

最新文章

  1. 杨超越第一,Python第二
  2. java之ibatis数据缓存
  3. Centos 编译安装nodejsexpress框架
  4. 1流明等于多少lux_光通量(流明)和照度(勒克司)定义及换算关系
  5. 计算机视觉研究那些事 |CVPR 2020 论文分享会
  6. 牛客网刷题(纯java题型 211~240题)
  7. 我的docker随笔26:制作arm平台的python-pandas镜像
  8. windows下运行python打印有颜色的字_Windows和Linux下Python输出彩色文字的方法教程...
  9. LayaAir Sprite 容器添加子节点
  10. 《Head First设计模式》第二版中译本的译稿(摘)
  11. c语言手机程序代码,C语言必背18个经典程序(示例代码)
  12. 高薪设计师必修课 AE移动UI动效设计从入门到实战
  13. 使用PC版Zune以全新的方式体验您的音乐
  14. 计算机软考知识点总结,计算机软考考试必备知识点:风险识别
  15. 推荐三款最好用的压缩/解压软件
  16. Android自学笔记:Tab控件源码剖析
  17. 理解openssl协议:x509、crt、cer、key、csr、ssl、tls 这些都是什么鬼? 如何给自己网站颁发证书?
  18. Android studio 简易流式布局
  19. 两部苹果手机同步照片_苹果手机误删照片怎么恢复?
  20. 编写一个掷色子猜大小的游戏

热门文章

  1. group by 报错 出现In aggregated query without
  2. SpringBoot----[16]—SpringBoot集成MyBatis
  3. 几款开源ESB总线的比较
  4. SiT3807:高性能单端压控振荡器VCXO
  5. 暂无支持此机型的手机版本_安卓门禁模拟软件(需Root)暂无苹果版本
  6. storm32和pixhawk_STORM32云台板调参教程 新人可参考 大师请指点
  7. halcon颜色识别的两种简单方式
  8. dsp调音一次多少钱_如何快速学会汽车音响DSP调音技术?
  9. Ubuntu安装pidgin及QQ插件
  10. Centos7系统中wget安装方法