实战之8051驱动8位数码管

2022-12-08  

8051驱动共阴极

过年有点时间,整理电脑,翻到一个之前的小作品,应一位刚入门的朋友的要求做的,控制8位数码管,依次显示0~9。发出来给大家瞧瞧,高手请略过。

由于当时手上没有开发板,就用Proteus来做电路仿真了。


工作环境:

Keil uVision5

Proteus 8 Professional


数码管




首先了解下数码管的相关知识

数码管的基本单元是发光二极管,按段数可分为七段数码管和八段数码管,八段数码管比七段数码管多一个发光二极管单元,也就是多一个小数点(DP),这个小数点可以更精确的表示数码管想要显示的内容;按能显示多少个(8)可分为1位、2位、3位、4位、5位、6位、7位、8位等数码管。



>数码管内部原理


上图是一个数码管的内部示意图,一个数码管的显示部分由8个二极管构成,刚好是一个字节,51单片机也是8位单片机。

根据内部发光二极管的公共连接端不同,可以分为共阳极接法和共阴极接法,共阳极接法就是发光二极管的正极共同接电源VCC,通过控制每个发光二极管的负极是否接地来显示数字。共阴极接法就是每个发光二极管的负极共同接地GND,通过控制每个发光二极管的正极是否接电源来显示数字。

图中a~g管脚分别控制着每个发光二极管的亮灭,所以,如果要显示1的话,只需要点亮b,c两段即可(把单片机对应端口输出0x06即可);如果要显示数字5,则只需要点亮a,f,g,c,d段即可组成数字5的显示(0x6d)。



>多位数码管内部原理图






上图是4位数码管的内部接线,每位数码管的阳极(或阴极)相连,其他相同引脚的引脚相连,一共有12个控制引脚,也可以得出8位的数码管有16个控制引脚,8个共阳(或共阴)端,8个控制a~g显示内容。



74LS138译码器

从数码管的显示原理来看,一个数码管要显示不同的字符,就要对数码管中的每个二极管进行不同控制,每个二极管要用到单片机的一个控制引脚,比如在实际应用中八位的共阴极或共阳极数码管,共有16个引脚,如果都使用单片机引脚进行控制,这就太浪费了,本来单片机的资源就很紧张。


解决办法是用一个译码器作为数码管的位选择器,需要哪一位显示就控制哪一位数码管的共阳(或共阴)端。



74LS138译码器1~3为输入端,由高到低为CBA; 7~15为输出端,由高到低为Y7-Y0。

工作过程:输入端输入三位二进制数,转成十进制,经过译码器后,输出端对应该十进制数的引脚(对应的Y)为低电平,其余为高电平,比如:


输入000,十进制为0,输出端的0位引脚为低电平,其余为高,也就是1111 1110;


输入101,十进制为5,输出端的5位引脚为低电平,其余为高,也就是1101 1111。

三位二进制数刚好可以表示0~7,8个数字,也就是可以控制8位数码管。


P=============roteus电路图



程序设计

#include

//延时函数

void delay(unsigned int ms){

int k,l;

for(k=0;kfor(l=0;l<120;l++);

}


//一个数码管显示 0~f 十六进制数组

char numHex[] = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};


/**

选择数码管,并显示出对应的十进制数

index :数码管位下标

num :char numHex[] 数组对应十进制数的下标

*/

void setIndexNum(unsigned char index,unsigned char num){

switch(index){//数码管位选,74LS138译码器的输入

case 0:

P1_2=0;

P1_3=0;

P1_4=0;

break;

case 1:

P1_2=1;

P1_3=0;

P1_4=0;

break;

case 2:

P1_2=0;

P1_3=1;

P1_4=0;

break;

case 3:

P1_2=1;

P1_3=1;

P1_4=0;

break;

case 4:

P1_2=0;

P1_3=0;

P1_4=1;

break;

case 5:

P1_2=1;

P1_3=0;

P1_4=1;

break;

case 6:

P1_2=0;

P1_3=1;

P1_4=1;

break;

case 7:

P1_2=1;

P1_3=1;

P1_4=1;

break;

}

P3=numHex[num];//数码管显示字符

}


void main(){

//proteus 不用while即可循环,不明白

unsigned char i,j;

for(i = 0;i < 8;i++){

for(j = 0;j < 16;j++){

setIndexNum(i,j);

delay(300);

if(j >= 15) break;

}

if(i >= 7) break;

}

}


文章来源于:电子工程世界    原文链接
本站所有转载文章系出于传递更多信息之目的,且明确注明来源,不希望被转载的媒体或个人可与我们联系,我们将立即进行删除处理。