51单片机编程学习笔记——动态数码管

有了《51单片机编程学习笔记——74HC138译码器》《51单片机编程学习笔记——74HC245八路三态输出双向收发器》的基础,我们就可以开始学习动态数码管的编程方法。
我们首先要看下动态数码管的电路图
在这里插入图片描述

选位置

可以看到该开发板上的动态数码管使用了两个元器件:74HC138译码器和74HC245八路三态输出双向收发器。
《51单片机编程学习笔记——74HC138译码器》一文中,我们知道该译码器将3位二进制数转换成8个管脚的输出,并且只有一个管脚是低电平,其他都是高电平。这样我们就可以使用该原理选择出动态数码管中的一位。比如我们希望左起第1个数字区域点亮,则可以让LED8端口为低电平,其他位高电平(只要让P24 P23 P22 都处于高电平即可,即0x111)。
在这里插入图片描述
这是因为动态数码管的每个数字区域是8个LED组成,它们分别是a、b、c、d、e、f、g和dp。这些LED的阳极可以连在一起,形成共阳极结构。这样我们可以通过控制每个LED的阴极电压来控制其是否点亮;对应的,有些数码管将这8个LED的阴极连在一起,形成共阴极结构。这个时候我们就可以通过控制每个LED的阳极电压来控制其是否点亮。我们开发板上的数码管就是共阴极方案。

由于这些LED的一端接的是P0系列管脚,提供了高电平。这样另外一端(共极)要提供低电平,才能让LED点亮。而74HC138译码器正好将选择的管脚设置为低电平。其他另外一端(共极)提供高电平的LED区域,因为形成不了电压差,所以不会点亮这8个LED等,从而不会显示任何数字。

在这里插入图片描述

显数字

然后我们需要分析下组成我们认识的数字需要点亮哪些LED灯。比如我们需要形成数字“0”,则除了dp和g不用点亮外,其他都要点亮;在比如数字8,除了dp不用点亮外,其他都要点亮。
下面给出了数字和需要点亮的LED灯之间的关系,区分了共阴极和共阳极两种动态数码管:

  • 共阴极方案
显示数字需点亮的 LED 段二进制编码(abcdefgdp)十六进制编码
0a、b、c、d、e、f0011 11110x3F
1b、c0000 01100x06
2a、b、d、e、g0101 10110x5B
3a、b、c、d、g0100 11110x4F
4b、c、f、g0110 01100x66
5a、c、d、f、g0110 11010x6D
6a、c、d、e、f、g0111 11010x7D
7a、b、c0000 01110x07
8a、b、c、d、e、f、g0111 11110x7F
9a、b、c、d、f、g0110 11110x6F
  • 共阳极方案
显示数字需点亮的 LED 段二进制编码(abcdefgdp)十六进制编码
0a、b、c、d、e、f1100 00000xC0
1b、c1111 10010xF9
2a、b、d、e、g1010 01000xA4
3a、b、c、d、g1011 00000xB0
4b、c、f、g1001 10010x99
5a、c、d、f、g1001 00100x92
6a、c、d、e、f、g1000 00100x82
7a、b、c1111 10000xF8
8a、b、c、d、e、f、g1000 00000x80
9a、b、c、d、f、g1001 00000x90

这儿需要提醒下,二进制的顺序要从高位向低位,即从P07到P00。
在这里插入图片描述

实验

在有了上面的铺垫后,我们通过代码实现如下功能:从坐起第一个位置开始,逐位显示0~7。

首先我们需要选择在哪个位置上显示数字

void select_led_index(unsigned char index) {
	// 如果index=0,则P22=1,P23=1,P24=1
	// 如果index=1,则P22=0,P23=1,P24=1
	// 如果index=2,则P22=1,P23=0,P24=1
	// 如果index=3,则P22=0,P23=0,P24=1
	// 如果index=4,则P22=1,P23=1,P24=0
	// 如果index=5,则P22=0,P23=1,P24=0
	// 如果index=6,则P22=1,P23=0,P24=0
	// 如果index=7,则P22=0,P23=0,P24=0
	P22 = (index & 0x01) ? 0 : 1;
    P23 = (index & 0x02) ? 0 : 1;
    P24 = (index & 0x04) ? 0 : 1;
}

然后在选择位置上显示各个数字

unsigned char digit[10] = {0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07, 0x7f, 0x6f};
……
void display(unsigned char index, unsigned char digit) 
{	
	select_led_index(index);
	P0 = digit;
}
……
for(i=0;i<8;i++) {
	display(i, digit[i]);
	Delay(200);
}

完整代码如下

#include <REG52.H>
#include <intrins.h>

void Delay1ms()		//@11.0592MHz
{
	unsigned char i, j;

	_nop_();
	i = 2;
	j = 199;
	do
	{
		while (--j);
	} while (--i);
}

void Delay(unsigned int millisecond) {
	unsigned int i = 0;
 	for (i = 0; i < millisecond; i++) {
		Delay1ms();	
	}
}

sbit P22 = P2^2;
sbit P23 = P2^3;
sbit P24 = P2^4;

void select_led_index(unsigned char index) {
	// 如果index=0,则P22=1,P23=1,P24=1
	// 如果index=1,则P22=0,P23=1,P24=1
	// 如果index=2,则P22=1,P23=0,P24=1
	// 如果index=3,则P22=0,P23=0,P24=1
	// 如果index=4,则P22=1,P23=1,P24=0
	// 如果index=5,则P22=0,P23=1,P24=0
	// 如果index=6,则P22=1,P23=0,P24=0
	// 如果index=7,则P22=0,P23=0,P24=0
	P22 = (index & 0x01) ? 0 : 1;
    P23 = (index & 0x02) ? 0 : 1;
    P24 = (index & 0x04) ? 0 : 1;
}

void display(unsigned char index, unsigned char digit) 
{	
	select_led_index(index);
	P0 = digit;
}

void main() {
	unsigned char i;
	unsigned char digit[10] = {0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07, 0x7f, 0x6f};
	while(1) {
		for(i=0;i<8;i++) {
			display(i, digit[i]);
			Delay(200);
		}
	}
}

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

breaksoftware

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值