**
关于数码管动态扫描制作简易计数器
**
第一次写博客,肤浅之处望路过的大佬做出指点。这两天无事琢磨了一下数码管的显示问题,并制作了一个简易的计数器。好了,废话不多说直接进入正题。
由于电路图比较简单故直接采用开发板 QX-MINI51 V2.0。
直接上图
注:独立键盘低电位触发。
4位共阳数码管:公共端经三极管接入P2.0~P2.3实现片选。
实现功能
1.按键计数:按一次计数键,数码管显示的数加1,能实现进位。
2.按键清零:按一次清零键,个位、十位全部置零。
设计思路
1.单片机重复扫描按键状态,检查全局变量,由全局变量映射给I/O口。
2.数码管动态扫描显示数字。
#include <reg51.h>
#define u8 unsigned char
#define u16 unsigned int
u8 digital_code[16] = {0xc0, 0xf9, 0xa4, 0xb0, 0x99, 0x92, 0x82, 0xf8, 0x80, 0x90, 0x88, 0x83, 0xc6, 0xa1, 0x86, 0x8e}; //共阳
Bit_choose[] = {0xf7,0xfc};
u8 count = 0,ten = 0;
sbit count_button = P3^4;
sbit clean_button = P3^5;
void Delay10ms();
void getKey();
void Delay1ms();
void display();
void main(void)
{
while (1)
{
getKey();
display();
}
return ;
}
void getKey()
{
if (count_button == 0) //计数按键
{
Delay10ms();
if (count_button == 0)
{
count++;
if (count == 10) //满十进位
{
count = 0;
ten++;
if (ten == 3)
{
ten = 0;
}
}
}
while (!count_button);
}
if (clean_button == 0)
{
Delay10ms();
if (clean_button == 0)
{
count = 0;
ten = 0;
}
while (!clean_button);
}
return ;
}
void display()
{
P2 = 0xf7;
P0 = digital_code[count];
Delay1ms();
P2 = 0xFb;
P0 = digital_code[ten];
Delay1ms();
}
void Delay10ms() //@12.000MHz
{
unsigned char i, j;
i = 117;
j = 184;
do
{
while (--j);
} while (--i);
}
void Delay1ms() //@12.000MHz
{
u8 i , j;
i = 12;
j = 169;
do
{
while (--j);
}
while (--j);
}
函数思路
getKey()
计数键:确定按键是否正真按下,按下之后统计按下次数,若按下10次之后 重 新清零,且进行十位进位。若十位也到达计数上限,所有变量全部清零,重新计数。
清零键:确定按键按下之后,对个位和十位全部清零即可。
display()
单片机通过循环扫描此函数以达到动态显示,I/O口通过全局变量映射出的电平操作数码管。就算没有按键按下,全局变量没被改变I/O口仍保存上次的电平不会一闪而过也不会消失。
总结
写这篇博客无非就是记录一下学习数码管动态扫描的心得,数码管的动态显示无非就是单片机I/O口太少无法满足多个数码管同时存在而设立的一种机制。相当于数码管传数据的8个口是通用的,当想用到其中一个口时就拉低这个数码管公共端的电位(共阳共阴的电位相反),这样数据就会传到你想要的数码管上。
若要在多个数码管上都有不同的数据显示时,我们就给不同的公共端拉低电平,传输不同的数据,由于单片机处理的数据的频率远大于人的眼睛能看到的频率,这样就会看到各个数码管上显示对应的数字啦。