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;k } //一个数码管显示 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; } }