【STC89C52】优化数码管的静态和动态显示效果
今天我跟大家分享的是数码管静态显示和动态显示实验的学习笔记,希望对你有所帮助!!!如果有什么错误欢迎评论区留言指正!!!
目录
一、原理图分析
1)数码管原理
一位数码管是由8个LED构成,可以显示数字、字符,把相对应的LED点亮即可。
数码管分成共阴极和共阳极,开发板上的数码管是共阴极的,导通段选高电平,位选低电平。段选确定亮的字形,位选确定是哪一个数码管亮。
如何判断实物数码管是共阴极还是共阳极的呢?可以用万用表红表笔接a,黑表笔接GND,如果亮则为共阴极,如果不亮反过来接(红表笔接VCC,黑表笔接a),亮了则为共阳极。
怎么赋值呢???
H dp g f e d c b a L
如果想显示2,a,b,d,e,g亮
01011011
0x5B
2)原理图
8位共阴极数码管由两个锁存器控制,一个控制位选(确定哪一个数码管亮),一个控制段选(确定亮的字形)。OE需要接地,输出端Q才可以输出高低电平。LE高电平时,输出端Q随输入端D的数据而变化,LE低电平时,输出端Q不随输入端D的数据而变化。
真值表:
L为低电平,H为高电平,X为任意值,Z为高阻态
锁存器与P0口相连,中间连着上拉电阻,上拉电阻的作用是可以输出高低电平,当P0口作为输入/输出口时,上电复位后处于开漏模式,只能输出低电平,无法输出高电平。P0口内部无上拉电阻,所以作I/O口必须外接10K-4.7K的上拉电阻。(上拉就是将不确定的信号通过一个电阻钳位在高电平,电阻同时起限流作用。下拉同理,也是将不确定的信号通过一个电阻钳位在低电平。)
正常模式:输入0,反相器变成1,栅极是1,源极是0,正偏,源极与漏极相连,输出0。
输入1,反相器变成0,栅极是0,源极是0,源极与漏极断开,上拉电阻输出1。
开漏模式:输入0,反相器变成1,栅极是1,源极是0,正偏,源极与漏极相连,输出0。
输入1,反相器变成0,栅极是0,源极是0,源极与漏极断开,高阻态。
如果想让数码管亮,我们可以先把位选打开,把想亮的数码管传给P0,P0传到锁存器,进行锁存,再打开段选,把想亮的字形传给P0,P0传到锁存器,进行锁存。
二、静态显示
#include <reg52.h>
sbit WE=P2^7;//位选
sbit DU=P2^6;//段选
void main(){
//第1位数码管显示2
WE=1;//打开位选
P0=0xfe;//11111110
WE=0;//进行锁存
DU=1;//打开段选
P0=0x5b;//01011011
DU=0;//进行锁存
}
三、动态显示
1)0-9段选表
0x3F, //"0"
0x06, //"1"
0x5B, //"2"
0x4F, //"3"
0x66, //"4"
0x6D, //"5"
0x7D, //"6"
0x07, //"7"
0x7F, //"8"
0x6F, //"9"
2)动态显示是一次显示一个数码管的字形,但是变化极快,视觉效果同时显示好几个数码管的字形。静态显示一次只能显示一个字形,如果想要在多个数码管显示多个不同字形,需要多个IO口。
3)动态显示一定要while(1)循环,不然只显示最后一个数码管的字形,静态显示可以利用自身的循环,一直显示到下一次下载。
4)动态显示每一位数码管显示完要进行清除断码和延时,不然太快了,前面的段码还在,下一个数码管的位选已经打开了,就会出现乱码。
#include <reg52.h>
sbit WE=P2^7;//位选
sbit DU=P2^6;//段选
#define uint unsigned int
#define uchar unsigned char
//延时函数
void delay(uint z){
uint x=0;
uint y=0;
for(x=z;x>0;x--)
for(y=114;y>0;y--);
}
//共阴极数码管0-9段选表
uchar board[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F};
void display(uint z){
uint bai=z/100;//百位
uint shi=z%100/10;//十位
uint ge=z%10;//个位
//第1位数码管
P0=0xff;//清除段码
WE=1;//打开位选
P0=0xfe;//11111110
WE=0;//进行锁存
DU=1;//打开段选
P0=board[bai];
DU=0;//进行锁存
delay(5);
//第2位数码管
P0=0xff;//清除段码
WE=1;//打开位选
P0=0xfd;//11111101
WE=0;//进行锁存
DU=1;//打开段选
P0=board[shi];
DU=0;//进行锁存
delay(5);
//第3位数码管
P0=0xff;//清除段码
WE=1;//打开位选
P0=0xfb;//11111011
WE=0;//进行锁存
DU=1;//打开段选
P0=board[ge];
DU=0;//进行锁存
delay(5);
}
void main(){
//显示123
while(1){
display(123);
}
}
#include <reg52.h>
sbit WE=P2^7;//位选
sbit DU=P2^6;//段选
void main(){
//第1位数码管显示2
WE=1;//打开位选
P0=0xfe;//11111110
WE=0;//进行锁存
DU=1;//打开段选
P0=0x5b;//01011011
DU=0;//进行锁存
}

三、动态显示
1)0-9段选表
0x3F, //"0"
0x06, //"1"
0x5B, //"2"
0x4F, //"3"
0x66, //"4"
0x6D, //"5"
0x7D, //"6"
0x07, //"7"
0x7F, //"8"
0x6F, //"9"
2)动态显示是一次显示一个数码管的字形,但是变化极快,视觉效果同时显示好几个数码管的字形。静态显示一次只能显示一个字形,如果想要在多个数码管显示多个不同字形,需要多个IO口。
3)动态显示一定要while(1)循环,不然只显示最后一个数码管的字形,静态显示可以利用自身的循环,一直显示到下一次下载。
4)动态显示每一位数码管显示完要进行清除断码和延时,不然太快了,前面的段码还在,下一个数码管的位选已经打开了,就会出现乱码。
#include <reg52.h>
sbit WE=P2^7;//位选
sbit DU=P2^6;//段选
#define uint unsigned int
#define uchar unsigned char
//延时函数
void delay(uint z){
uint x=0;
uint y=0;
for(x=z;x>0;x--)
for(y=114;y>0;y--);
}
//共阴极数码管0-9段选表
uchar board[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F};
void display(uint z){
uint bai=z/100;//百位
uint shi=z%100/10;//十位
uint ge=z%10;//个位
//第1位数码管
P0=0xff;//清除段码
WE=1;//打开位选
P0=0xfe;//11111110
WE=0;//进行锁存
DU=1;//打开段选
P0=board[bai];
DU=0;//进行锁存
delay(5);
//第2位数码管
P0=0xff;//清除段码
WE=1;//打开位选
P0=0xfd;//11111101
WE=0;//进行锁存
DU=1;//打开段选
P0=board[shi];
DU=0;//进行锁存
delay(5);
//第3位数码管
P0=0xff;//清除段码
WE=1;//打开位选
P0=0xfb;//11111011
WE=0;//进行锁存
DU=1;//打开段选
P0=board[ge];
DU=0;//进行锁存
delay(5);
}
void main(){
//显示123
while(1){
display(123);
}
}
1)0-9段选表
0x3F, //"0"
0x06, //"1"
0x5B, //"2"
0x4F, //"3"
0x66, //"4"
0x6D, //"5"
0x7D, //"6"
0x07, //"7"
0x7F, //"8"
0x6F, //"9"
2)动态显示是一次显示一个数码管的字形,但是变化极快,视觉效果同时显示好几个数码管的字形。静态显示一次只能显示一个字形,如果想要在多个数码管显示多个不同字形,需要多个IO口。
3)动态显示一定要while(1)循环,不然只显示最后一个数码管的字形,静态显示可以利用自身的循环,一直显示到下一次下载。
4)动态显示每一位数码管显示完要进行清除断码和延时,不然太快了,前面的段码还在,下一个数码管的位选已经打开了,就会出现乱码。
#include <reg52.h>
sbit WE=P2^7;//位选
sbit DU=P2^6;//段选
#define uint unsigned int
#define uchar unsigned char
//延时函数
void delay(uint z){
uint x=0;
uint y=0;
for(x=z;x>0;x--)
for(y=114;y>0;y--);
}
//共阴极数码管0-9段选表
uchar board[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F};
void display(uint z){
uint bai=z/100;//百位
uint shi=z%100/10;//十位
uint ge=z%10;//个位
//第1位数码管
P0=0xff;//清除段码
WE=1;//打开位选
P0=0xfe;//11111110
WE=0;//进行锁存
DU=1;//打开段选
P0=board[bai];
DU=0;//进行锁存
delay(5);
//第2位数码管
P0=0xff;//清除段码
WE=1;//打开位选
P0=0xfd;//11111101
WE=0;//进行锁存
DU=1;//打开段选
P0=board[shi];
DU=0;//进行锁存
delay(5);
//第3位数码管
P0=0xff;//清除段码
WE=1;//打开位选
P0=0xfb;//11111011
WE=0;//进行锁存
DU=1;//打开段选
P0=board[ge];
DU=0;//进行锁存
delay(5);
}
void main(){
//显示123
while(1){
display(123);
}
}
以上就是我今天的分享!如果有什么建议或补充欢迎评论区留言!!!如果觉得这篇博客还不错的话可以点个赞再走哟~