- 如何学习单片机
- 学习什么单片机
- 如何学习单片机
- 单片机学习的准备工作
- 单片机开发环境搭建 - Keil uVision4 安装教程
- Keil uVision4 简单使用教程
- 第一章问题汇总
- 点亮你的 LED 灯
- 单片机内部资源(内部结构)
- 单片机最小系统 [配图] [超详细]
- 单片机上的发光二极管(LED 灯)
- 51 单片机特殊功能寄存器和位定义
- 使用 Keil uVision 新建一个工程
- 第一个单片机程序(C 语言编写)
- 将程序下载到单片机
- 单片机硬件基础知识学习
- 电磁干扰 EMI
- 单片机中去耦电容的应用
- 三极管的的概念及其工作原理
- 单片机中三极管的应用
- 单片机中 74HC138 三八译码器的应用
- 单片机 LED 灯闪烁程序
- C 语言基础及流水灯的实现
- 二进制、十进制和十六进制
- C 语言变量类型和范围
- C 语言基本运算符
- C 语言 for 循环语句
- C 语言 while 循环语句
- C 语言函数的简单介绍
- 单片机延时方法(Keil 软件延时)
- 单片机 LED 流水灯程序[详细]
- 单片机定时器与数码管基础
- 单片机逻辑电路与逻辑运算
- 单片机定时器介绍
- 单片机定时器的寄存器
- 单片机中定时器的应用
- 单片机中 LED 数码管的介绍
- 单片机数码管的真值表
- 单片机数码管的静态显示
- 单片机的中断与数码管动态显示
- C 语言数组
- C 语言 if 语句
- C 语言 switch 语句
- 单片机数码管动态显示程序[带解释]
- 单片机数码管显示消隐
- 单片机中断系统
- 单片机中断的优先级
- 变量进阶与点阵 LED
- C 语言变量的作用域
- C 语言变量的存储类别
- 单片机 LED 点阵的介绍
- 单片机 LED 点阵的图形显示
- 单片机 LED 点阵的纵向移动(动态显示)
- 单片机 LED 点阵的横向移动(动态显示)
- C 语言函数进阶与单片机按键
- 单片机最小系统解析(电源、晶振和复位电路)
- C 语言函数的调用
- C 语言函数的形参和实参
- 单片机按键(独立按键和矩阵按键)
- 单片机独立按键扫描程序
- 单片机按键消抖程序
- 单片机矩阵按键的扫描
- 单片机简易加法计算器程序
- 单片机中的步进电机与蜂鸣器
- 单片机 IO 口的结构
- 单片机上下拉电阻
- 电机的分类
- 28BYJ-48 步进电机原理
- 让 28BYJ-48 步进电机转起来
- 28BYJ-48 步进电机转动精度与深入分析
- 28BYJ-48 步进电机控制程序基础
- 实用的 28BYJ-48 步进电机控制程序
- 单片机蜂鸣器控制程序和驱动电路
- 单片机实例练习与经验积累
- 单片机数字秒表程序
- 单片机中 PWM 的原理与控制程序
- 单片机交通灯控制程序和设计原理
- 51 单片机 RAM 区域的划分
- 单片机长短按键的应用
- UART 串口通信
- 单片机串行通信介绍
- RS232 通信接口
- USB 转串口通信
- 单片机 IO 口模拟 UART 串口通信
- UART 串口通信的基本应用
- 单片机通信实例与 ASCII 码
- C 语言指针基础与 1602 液晶的初步认识
- C 语言变量的地址
- C 语言指针变量的声明
- C 语言指针的简单示例
- C 语言指向数组元素的指针
- C 语言字符数组和字符指针
- 1602 液晶介绍(电路和引脚图)
- 1602 液晶的读写时序介绍
- 1602 液晶指令介绍
- 1602 液晶简单显示程序
- 单片机 1602 液晶与串口的应用实例
- 单片机通信时序解析
- 1602 液晶整屏移动程序
- 多个.c 文件的初步认识
- 单片机计算器程序设计[详细]
- 单片机串口通信原理和控制程序
- 单片机 I2C 总线与 EEPROM
- 单片机 I2C 时序介绍
- 单片机 I2C 寻址模式
- 单片机 EEPROM 简介
- 单片机 EEPROM 单字节读写操作时序
- 单片机 EEPROM 多字节读写操作时序
- 单片机 EEPROM 的页写入
- 单片机 I2C 和 EEPROM 的综合编程
- 实时时钟 DS1302
- BCD 码介绍
- 单片机 SPI 通信接口
- 实时时钟芯片 DS1302 介绍
- DS1302 的硬件信息
- DS1302 寄存器介绍
- DS1302 通信时序介绍
- DS1302 的 BURST 模式
- C 语言复合数据类型(结构体,共用体,枚举类型)
- 单片机电子时钟程序设计
- 红外通信与 DS18B20 温度传感器
- 红外光的基本原理
- 红外遥控通信原理
- NEC 协议红外遥控器
- 温度传感器 DS18B20
- 模数转换 A/D 与数模转换 D/A
- A/D 和 D/A 的基本概念
- A/D(模数转换) 的主要指标
- PCF8591 硬件接口(电路图引脚图)
- PCF8591 应用程序
- A/D 差分输入信号
- D/A 输出
- 单片机信号发生器程序
- RS485 通信与 Modbus 协议
- 单片机 RS485 通信接口、控制线、原理图及程序实例
- Modbus 通信协议介绍
- 单片机 Modbus 多机通信程序设计
单片机数码管显示消隐
不知道同学们是否发现了,我们的这两个数码管动态显示程序的运行效果似乎并不是那么完美,第一个小问题,大家仔细看,数码管的不应该亮的段,似乎有微微的发亮,这种现象叫做 鬼影
,这个 鬼影
严重影响了我们的视觉效果,我们该如何解决呢?
同学们在今后可能会遇到各种各样的实际问题,可能很多都是我们没有讲过的,遇到问题怎么办呢?大家要相信,你作为初学者,遇到的问题肯定不是第一个遇到的,肯定有前辈已经遇到过相同的或类似的问题,他们一般都会在网上发表各种帖子,各种讨论,所以大家遇到问题,首先就应该形成一个到网上搜索的条件反射,这个问题大家可以到网上搜: 数码管消隐
或者 数码管鬼影解决
,多找相关关键词搜索试试,会搜索也是一种能力。
大家在网上搜了一下会发现,解决这类问题的方法有两个,其中之一是延时,延时之后我们肉眼就可能看不到这个 鬼影
了。但是延时是一个非常拙劣的手段,且不说延时多久能让我们看不到 鬼影
,延时后,我们的数码管亮度会普遍降低。我们解决问题呢,不能只知其然,还要知其所以然,那么我们首先就来弄明白为什么会出现 鬼影
。
鬼影
的出现,主要是在数码管位选和段选产生的瞬态造成的。举个简单例子,我们在数码管动态显示的那部分程序中,实际上每一个数码管点亮的持续时间是 1ms 的时间,1ms 后进行下个数码管的切换。在进行数码管切换的时候,比如我们从 case 5 要切换到 case 0 的时候,case 5 的位选用的是 ADDR0=1; ADDR1=0; ADDR2=1;假如此刻 case 5 也就是最高位数码管对应的值是 0,我们要切换成的 case 0 的数码管位选是 ADDR0=0; ADDR1=0; ADDR2=0;而对应的数码管的值假如是 1。又因为 C 语言程序是一句一句顺序往下执行的,每一条语句的执行都会占用一定的时间,即使这个时间非常非常短暂。但是当我们把 ADDR0=1
改变成 ADDR0=0
的时候,这个瞬间存在了一个中间状态 ADDR0=0; ADDR1=0; ADDR2=1;在这个瞬间上,我们就给 case 4 对应的数码管 DS5 瞬间赋值了 0。当我们全部写完了 ADDR0=0;
ADDR1=0; ADDR2=0;后,这个时候,我们的 P0 还没有正式赋值,而 P0 此刻却保持了前一次的值,也就是在这个瞬间,我们又给 case 0 对应的数码管 DS1 赋值了一个 0。直到我们把 case 0 后边的语句全部完成后,我们的刷新才正式完成。而在这个刷新过程中,有 2 个瞬间我们给错误的数码管赋了值,虽然很弱(因为亮的时间很短),但是我们还是能够发现。
那么搞明白了原理后,解决起来就不是困难的事情了,我们只要避开这个瞬间错误就可以了。不产生瞬间错误的方法是,在进行位选切换期间,避免一切数码管的赋值即可。方法有两个,一个方法是刷新之前关闭所有的段,改变好了位选后,再打开段即可;第二个方法是关闭数码管的位,赋值过程都做好后,再重新打开即可。这个不是很难,答案我都公布一下。
关闭段
在 switch(i) 这句程序之前,加一句 P0=0xFF;这样就把数码管所有的段都关闭了,当把 ADDR
的值全部搞定后,再给 P0 赋对应的值即可。
关闭位
在 switch(i) 这句程序之前,加上一句 ENLED=1;等到把 ADDR2=0; ADDR1=0;ADDR0=0; i++; P0=LedBuff[0];这几条刷新程序全部写完后,再加上一句 ENLED=0;然后再进行 break 操作即可。
这个地方逻辑思路上稍微有点复杂,大家一定要理解深刻,深刻理解,彻底弄明白,把这个瞬间的问题弄明白了,后边很多牵扯到此类情况的问题,我们都可以一并搞定。
上边的数码管程序还有第二个问题,大家仔细看,我们的数码管上的数字每一秒变化一次,变化的时候,不参加变化的数码管可能出现一次抖动,这个抖动没有什么专业的名字,我们就称之为数码管抖动吧。这种数码管抖动是什么原因造成的呢?为何在数据改变的时候才抖动呢?
来分析一下我们的程序,程序在定时到 1 秒的时候,执行了 秒数+1 并转换为数码管显示字符
这个操作,一个 32 位整型数的除法运算,实际上是比较耗费时间的,至于这一段程序究竟耗费了多少时间,大家可以通过第四章讲的调试方法来看看这段程序运行用了多少时间。由于每次定时到 1 秒的时候,程序都多运行了这么一段,导致了某个数码管的点亮时间比其他情况下要长一些,总时间就变成了 1ms+本段程序运行时间,于此同时,其它的数码管就熄灭了 5ms+本段程序运行时间,如果这段程序运行时间非常短,那么可以忽略不计,但很明显,现在这段程序运行时间已经比较长了,以致于严重影响到视觉效果了,所以我们要采取另外一种思路去解决这个问题。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论