【51单片机零基础-chapter4:LED数码管】
LED数码管本质是一种廉价的显示器,由多个发光二极管封装组成的8字形器件
如果要显示6,那么需要点亮除了B以外的所有段,并且开发板上默认是共阴极
阳极A->G除了B全点亮,所以7,4,2,1,9,10全接正极:10111110
这个就是段码,表示显示的数据
静态LED显示
开发板上是四个一体的LED灯
每个LED单独引出一个共阴极(或阳极)端
但是所有的LED其余各个段连在一起
比如想第三个LED显示1
那么第一二四个LED灯共阴极接在正极上,所以保证它们不会亮
然后BC段全给1,其余接0,这时第三个LED因为一头连负极,一头的各段存在正极(BC段)那么只有第三个LED灯的BC段亮,即0110 0000这样子赋.
但这样子搞,只会同一时刻一组LED显示同一数字,因为下面的段是相同的(led共用引脚)
动态数码管显示
一组LED各自显示不同的数字
其实本质仍是静态的,因为共用引脚决定了同一时刻只能显示一个数字.
但是如果切换的够快,那么人眼分辨不出一组LED的不同数字不是在同一时刻,视觉上像是同时显示了不同数据(类似于OS的并发,切换的足够快,使每个用户(LED)感觉像是独占)
其中3个控制8个原理是三位二进制转十进制,转到谁,谁有效,给负电平,其余全1
C B A Y
位权 4 2 1 十进制
0 0 0 Y0->0111 1111
0 0 1 Y1->1011 1111
1 0 1 Y5->1111 1011
双向数据缓冲器
DIR方向,代表是左缓冲到右,还是右缓冲到左
接高电平,则左边缓冲到右遍.因为数码管显示一般是送数据(左到右)不需要读回来,所以一般是给高电平
VDD,GND正负极
OE使能,一般称CE
A0-B0,A1-B1,…,A7-B7
电容
8个电阻组成排阻,R是欧姆,限流电阻,防止数码管电流过大
总结
先选中某个LED的共阴极,通过138译码器
p22,p23,p24赋值,有三位二进制,转十进制x,则LEDx的共阴极接上低电平0,其余全1,只有LEDx满足条件,然后给p0口一个阳码数据,其中只有1的才是给了高电平
有高低电平,数码管段才会亮
让LED5显示6
led5,则共阴极5->二进制101,则p2的234赋值101;
显示6,则从段a到dp分别是1011 1110
由于从高位往低位读,则是0111 1101
转化为16进制(1+2+4 1+4+8=7 13 ,10为A,13为D):7 D
#include <REGX52.H>
//light LED5
void main(){
//6=101
P2_4=1;
P2_3=0;
P2_2=1;
P0=0x7D;
while(1){
}
}
让LED显示985
#include <REGX52.H>
unsigned char lednum[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
void light(unsigned char location,num);
void Delay(unsigned char x);
void main(){
while(1){
light(1,9);Delay(10);
light(2,8);Delay(10);
light(3,5);Delay(10);
light(6,2);Delay(10);
light(7,1);Delay(10);
light(8,1);Delay(10);
}
}
void light(unsigned char location,num){
switch(location){
case 1:P2_4=1;P2_3=1;P2_2=1; break;
case 2:P2_4=1;P2_3=1;P2_2=0; break;
case 3:P2_4=1;P2_3=0;P2_2=1; break;
case 4:P2_4=1;P2_3=0;P2_2=0; break;
case 5:P2_4=0;P2_3=1;P2_2=1; break;
case 6:P2_4=0;P2_3=1;P2_2=0; break;
case 7:P2_4=0;P2_3=0;P2_2=1; break;
case 8:P2_4=0;P2_3=0;P2_2=0; break;
}
P0=lednum[num];
}
void Delay(unsigned char x) //@12.000MHz
{
while(x--){
unsigned char i, j;
i = 2;
j = 239;
do
{
while (--j);
} while (--i);
}
}
数码管消影
逻辑:位选,段选,位选,…
单片机速度过快会导致数据窜位
需要每次段选完后清零,但不能马上清零,否则导致灯光过暗
Delay(1);P0=0x00;
#include <REGX52.H>
unsigned char lednum[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
void light(unsigned char location,num);
void Delay(unsigned char x);
void main(){
while(1){
light(1,9);Delay(1);
light(2,8);Delay(1);
light(3,5);Delay(1);
light(6,2);Delay(1);
light(7,1);Delay(1);
light(8,1);Delay(1);
}
}
void light(unsigned char location,num){
switch(location){
case 1:P2_4=1;P2_3=1;P2_2=1; break;
case 2:P2_4=1;P2_3=1;P2_2=0; break;
case 3:P2_4=1;P2_3=0;P2_2=1; break;
case 4:P2_4=1;P2_3=0;P2_2=0; break;
case 5:P2_4=0;P2_3=1;P2_2=1; break;
case 6:P2_4=0;P2_3=1;P2_2=0; break;
case 7:P2_4=0;P2_3=0;P2_2=1; break;
case 8:P2_4=0;P2_3=0;P2_2=0; break;
}
P0=lednum[num];
//消影
Delay(1);
P0=0x00;
}
void Delay(unsigned char x) //@12.000MHz
{
while(x--){
unsigned char i, j;
i = 2;
j = 239;
do
{
while (--j);
} while (--i);
}
}