关于数码管以及74HC573锁存器的分析放在这,有详细的分析过程,请自行查看https://blog.csdn.net/chrisbum/article/details/115583779?spm=1001.2014.3001.5502
设计要求:在实验板上,第一个数码管显示数字0,时间为1ms,然后关闭它,立即让第二个数码管显示1,时间为1ms,再关闭它,直到最后一个数码管显示7,时间同样为1ms,关闭它再回来显示第一个数码管,一直循环下去。
方法1(比较常规)
程序:
#include //51单片机头文件
sbit WE = P2^7; //位选信号的锁存器控制 位定义 WE为标识符 代表着位选 P2^7为地址符 申明U8锁存器的锁存端
sbit DU = P2^6; //段选信号的锁存器控制 位定义 DU为标识符 代表着段选 P2^7为地址符 申明U9锁存器的锁存端
#define uchar unsigned char //宏定义(预处理指令,不是语句,后面不用加分号)其中直接用uchar替换了unsigned char 此时我们可以用uchar num等价于unsigned char num;
#define uint unsigned int //宏定义(用法和上面类似)
uchar code table[] = { //显示0~f的码表
0x3f,0x06,0x5b,0x4f,
0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,
0x39,0x5e,0x79,0x71};
void delay(uint z) //延时函数
{
unsigned int x,y;
for(x = z;x>0;x--)
for(y=144;y>0;y--);
}
int main() //主函数
{
while(1) //大循环
{
P0 = 0xff; //在进行位选择时候,先关闭所有显示,防止打开位选时,P0口还保持原来的数据
WE = 1; //打开U8锁存器
P0 = 0xfe; //第1个数码管显示
WE = 0; //关闭U8锁存器
DU = 1; //打开U9锁存器
P0 = table[0]; //调用数组
delay(1); //调用延时函数
P0 = 0xff;
WE = 1;
P0 = 0xfd; //第2个数码管显示
WE = 0;
DU = 1;
P0 = table[1]; //调用数组,显示数字
delay(1); //调用延时函数
P0 = 0xff;
WE = 1;
P0 = 0xfb; //第3个数码管显示
WE = 0;
DU = 1;
P0 = table[2]; //调用数组,显示数字2
delay(1); //调用延时函数
P0 = 0xff;
WE = 1;
P0 = 0xf7; //第4个数码管显示
WE = 0;
DU = 1;
P0 = table[3]; //调用数组,显示数字3
delay(1); //调用延时函数
P0 = 0xff;
WE = 1;
P0 = 0xef; //第5个数码管显示
WE = 0;
DU = 1;
P0 = table[4]; //调用数组,显示数字4
delay(1); //调用延时函数
P0 = 0xff;
WE = 1;
P0 = 0xdf; //第6个数码管显示
WE = 0;
DU = 1;
P0 = table[5]; //调用数组,显示数字5
delay(1); //调用延时函数
P0 = 0xff;
WE = 1;
P0 = 0xbf; //第7个数码管显示
WE = 0;
DU = 1;
P0 = table[6]; //调用数组,显示数字6
delay(1); //调用延时函数
P0 = 0xff;
WE = 1;
P0 = 0x7f; //第8个数码管显示
WE = 0;
DU = 1;
P0 = table[7]; //调用数组,显示数字7
delay(1); //调用延时函数
}
}
P0 = 0xff; //在进行位选择时候,先关闭所有显示,防止打开位选时,P0口还保持原来的数据
这条语句有一个专业的名字叫”消影“。
”消影“:在刚送完段选数据后,P0口仍然保持着上次段选的数据,接下来要执行打开位选锁存器的命令后,原来保持在P0口的段选数据将立即通过位选锁存器直接加在数码管上,接下来才是再次通过P0口给位选锁存器送入位选数据,虽然这个过程很短暂,但是在数码管高速显示状态下,会出现数码管乱码的现象,加上”消影“后,在开启位选锁存器后,P0口全为高电平,所以哪个数码管都不后亮,所以”消影“很重要。
方法2(代码格式比较简单)
程序:
#include //51单片机头文件
#define uchar unsigned char //宏定义(预处理指令,不是语句,后面不用加分号)其中直接用uchar替换了unsigned char 此时我们可以用uchar num等价于unsigned char num;
#define uint unsigned int //宏定义(用法和上面类似)
sbit DU = P2^6; //段选信号的锁存器控制
sbit WE = P2^7; //位选信号的锁存器控制
uchar num;
uchar code WEI [] = {
0xfe,0xfd,0xfb,0xf7,
0xef,0xdf,0xbf,0x7f}; //数码管各位的码表
uchar code DUAN [] ={
0x3f,0x06,0x5b,0x4f,
0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,
0x39,0x5e,0x79,0x71}; //0-f的码表
void delay(uint z)
{
uint x,y;
for(x = z;x>0;x--)
for(y = 144;y>0;y--);
} //延时函数
void main()
{
while(1)
{
for(num=0;num<8;num++)
{
P0 = 0xff; //在进行位选择时候,先关闭所有显示,防止打开位选时,P0口还保持原来的数据
WE = 1;
P0 = WEI[num];
WE = 0;
DU = 1;
P0 = DUAN[num];
DU = 0;
delay(1); //时间间隔短,这是关键(所谓的同时显示,只是间隔较短而已,利用人眼的余辉效应,觉得每个数码管都一直在亮)。
}
}
}
进阶显示1
设计要求:
在单片机上,让第一位数码管显示数字1,接着让第二位数码管显示数字2,以此类推,最后让第八个数码管显示数字7。
程序:
#include
#define uchar unsigned char
#define uint unsigned int
sbit DU = P2^6; //段选信号的锁存器控制
sbit WE = P2^7; //位选信号的锁存器控制
uchar num;
uchar code WEI[] = {
0xfe,0xfd,0xfb,0xf7,
0xef,0xdf,0xbf,0x7f};
//数码管各位的码表
uchar code DUAN[] = {
0x3f,0x06,0x5b,0x4f,
0x66,0x6d,0x7d,0x07,};
//0-7的码表
void delay(uint z) //延时函数
{
uint x,y;
for(x = z;x>0;x--)
for(y = 144;y>0;y--);
}
void main() //主函数
{
while(1) //大循环
{
for(num=0;num<8;num++) //进行for循环,在num大于等于8之前一直执行花括号中的内容,直到循环结束
{
P0 = 0xff; //消影
WE = 1; //打开位选锁存器
P0 = WEI[num]; //调用数组
WE = 0; //关闭位选锁存器
DU = 1; //打开段选锁存器
P0 = DUAN[num]; //调用数组
DU = 0; //关闭段选锁存器
delay(500); //延时函数 注意:小括号内的数越大数码管显示的时候给人带来的视觉缓存就越大
}
}
}
效果: