多位数码管显示
本篇文章将系统对基础元件数码管进行介绍,具体包括数码管结构、分类、相关显示模块三个方面。
1.数码管结构
1.1 1位数码管
1位数码管外表图:
提一嘴,这里的a~g和dp为线码。
1位数码管内部结构图:
可以看出上图数码管那8个线码分别对于8个LED。
1.2 多位数码管
多位数码管外表图:
多位数码管内部结构图:
所有线码端共用1个I/O口,该图16、14、4、11、10端是位码端,用于控制哪个数码管显示。
2.数码管分类
(1)从内部结构来看,可以分为共阴极数码管和共阳极数码管。
(2)从使用方式来看,可以分为插入式数码管和贴片式数码管。
(3)从位数来看,可以分为1位数码管、2位数码管、4位数码管、8位数码管、16位数码管、32位数码管、64位数码管。
(4)从亮度来看,可以分为普通管和高亮度数码管。
(5)从显示角度来看,可以分为点阵式数码管和字符数数码管。
3.数码管显示
3.1 两种显示
数码管可以有静态显示和动态显示。
数码管静态显示是指数码管直接显示特定的数字。静态显示相对于动态显示,其优点在于显示稳定,可以清晰地显示出要表达的数字,但相应的,其显示效果相对较单一,无法表现动态效果。
数码管动态显示是指将数字逐个显示在数码管上,形成数字不断变化的效果。
共阴数码管和共阳数码管。共阴数码管的数字显示是通过将某个数字的共阴极接地,同时在其对应的阳极加电,使其发光显示。而共阳数码管则是将某个数字的共阳极接电源,同时在其对应的阴极接地,使其发光显示。
常见的控制方法有循环扫描和定时中断。
在循环扫描中,程序通过不断循环地切换每个数字的驱动信号,来实现动态显示。而在定时中断中,程序通过定时器中断来触发切换数字的操作,从而实现动态显示。
3.2 仿真图
3.3 代码及结果展示
3.3.1 静态显示
display.c
#include "display.h"
unsigned char code leddata[]={
0x3F, //0
0x06, //1
0x5B, //2
0x4F, //3
0x66, //4
0x6D, //5
0x7D, //6
0x07, //7
0x7F, //8
0x6F, //9
0x77, //A
0x7C, //B
0x39, //C
0x5E, //D
0x79, //E
0x71, //F
0x76, //H
0x38, //L
0x37, //n
0x3E, //u
0x73, //P
0x5C, //o
0x40, //-
0x00 //熄灭
};//数码管共阴极段码表
unsigned char LEDBuf[]={2,3,4,22};//缓冲区
unsigned char code PLACE_COOE[]={0xfe,0xfd,0xfb,0xf7};//位码
/******************************************************************************************
函数名:display
功能:数码管显示函数
参数:无
返回值:无
******************************************************************************************/
void display()
{
unsigned char i;
IO_DIG=leddata[LEDBuf[i]];//第一步--段码
IO_PLACE=PLACE_COOE[i];//第二步--位码
delay(1);//第三步--延时1ms
IO_DIG=0x00;//第四步--消隐
i++;
if(N==i)
i=0;
}
display.h
#ifndef __DISPLAY_H__
#define __DISPLAY_H__
#include <reg51.h>
#include "delay.h"
#define IO_DIG P0 //段码IO
#define IO_PLACE P2 //位码IO
#define N 4 //数码管个数
unsigned char code leddata[];//变量声明
extern unsigned char LEDBuf[];
void display();//数码管显示函数声明
#endif
main.c
#include "display.h"
/******************************************************************************************
函数名:main
功能:主函数
参数:无
返回值:无
******************************************************************************************/
void main()
{
while(1)
{
display();
}
}
结果展示
3.3.2 循环扫描
注:这里display.h与上面静态是一样的哦
main.c
#include <reg51.h>
#include "display.h"
/******************************************************************************************
函数名:main
功能:主函数
参数:无
返回值:无
******************************************************************************************/
void main()
{
unsigned int i;
unsigned int sum=1000;
for(i=0;i<5000;i++)
{
display();//数码管初始界面显示"----"
}
i=0;
while(1)
{
for(i=0;i<3000;i++)
{
LEDBuf[0]=sum/1000;//数码管千位数
LEDBuf[1]=sum/100%10;//数码管百位数
LEDBuf[2]=sum/10%10;//数码管十位数
LEDBuf[3]=sum%10;//数码管个位数
display();//数码管显示"1000"
}
sum++;
if(sum>2500)//数码管显示数值限制在2500以内
sum=0;
}
}
结果展示
首先,数码管初始界面为"----",后从1000开始显示,不断加1显示,直到显示2500后,重新从0显示,不断加1显示,直到显示2500,又重新显示为0,又不断加一,以此类推。
3.3.3 中断扫描
(1)代码显示
display.c
/******************************************************************************************
函数名:display
功能:数码管显示函数
参数:无
返回值:无
******************************************************************************************/
void display()
{
static unsigned char i=0;
switch(i)
{
case 0:
IO_DIG=0x00;//消隐
IO_DIG=leddata[LEDBuf[0]];//段码
IO_PLACE=PLACE_COOE[0];//位码
i++;
break;
case 1:
IO_DIG=0x00;//消隐
IO_DIG=leddata[LEDBuf[1]];//段码
IO_PLACE=PLACE_COOE[1];//位码
i++;
break;
case 2:
IO_DIG=0x00;//消隐
IO_DIG=leddata[LEDBuf[2]];//段码
IO_PLACE=PLACE_COOE[2];//位码
i++;
break;
case 3:
IO_DIG=0x00;//消隐
IO_DIG=leddata[LEDBuf[3]];//段码
IO_PLACE=PLACE_COOE[3];//位码
i=0;
break;
}
}
main.c
/**************************************************************************************
功能:中断法实现数码管动态刷新,数码管初始界面“----”,同时P1^0的led每0.5s闪灭一次,
共计5s,最后数码管动态刷新显示数据temp
时间:2023/7/30
**************************************************************************************/
//头文件声明
#include "reg51.h"//51头文件
#include "display.h"//数码管显示头文件
//函数的声明
void Timer0_Init();//定时器T0初始化函数的声明
void dis_service();//数码管显示服务函数的声明
unsigned int temp=1234;//数码管数据显示变量
unsigned char systemflag=1;//标志位
unsigned int systemTimer=0;//标志位
sbit LED0=P1^0;
/****************************************************************
函数名:main
参数:无
返回值:无
****************************************************************/
void main()
{
Timer0_Init();//定时器T0初始化函数
do
{
if(systemTimer%50==0) //50ms 50ms/1ms=50
LED0=~LED0; //电平反转
}while(systemTimer<=5000); //led闪炼5s 5000ms/1ms=5000
systemflag=0;
LED0=1;
while(1)
{
dis_service();//数码管显示服务函数
}
}
/****************************************************************
函数名:Timer0_Init
参数:无
返回值:无
****************************************************************/
void Timer0_Init() //1毫秒 @12.000MHz
{
TMOD &= 0xF0; //设置定时器模式
TMOD |= 0x01; //设置定时器模式
TL0 = 0x18; //设置定时初始值
TH0 = 0xFC; //设置定时初始值
TF0 = 0; //清除TF0标志
EA=1; //总中断打开
ET0=1; //定时器0的中断打开
TR0 = 1; //定时器0开始计时
}
void timer0() interrupt 1 //定时器0的中断服务函数
{
TR0=0; //关闭定时器0
if(systemflag==1)//软件拓充定时器
{
systemTimer++;
}
display(); //数码管显示函数放在定时器中断服务函数,实现延时功能
TL0 = 0x18; //设置定时初始值
TH0 = 0xFC; //设置定时初始值
TR0=1; //再次打开定时器0
}
/****************************************************************
函数名:dis_service
参数:无
返回值:无
****************************************************************/
void dis_service()//数码管显示服务函数
{
LEDBuf[0]=temp/1000; //显示temp的千位数
LEDBuf[1]=temp/100%10;//显示temp的百位数
LEDBuf[2]=temp/10%10; //显示temp的十位数
LEDBuf[3]=temp%10; //显示temp的个位数
}
(2)结果展示
新的一天,新的开始,望各位大佬多多支持,
你们的点赞关注就是我的无尽动力!!!
也请各位多多评价!!!