将单片机数码管显示驱动封装成一个函数,方便需要用到的时候直接调用
1、数码管电路原理图及原理
电路图(图一)
数码管显示原理(图二)
数码管根据内部连接不同,分为共阴极和共阳极。八段数码管内部有8颗LED组成,如果想要显示特定字形只需控制相应的LED亮起,其他LED熄灭即可。
数码管显示方式有两种:静态显示和动态显示
静态显示每个数码管端口都必须接上数据IO口来保持显示。当送入字形可一直保持,直到送入新字形为止。
优点:数码管显示无闪烁、亮度高、软件控制比较容易。
缺点:需要的硬件电路较多,如果数码管增多,当数码管全部被电量的时候,所需要的电流会增大,对电源的要求也随之增加。所以,大部分硬件设计中,很少采用静态显示的方式。
动态显示:所有位的数码管段选线并联在一起,由位选线进行动态扫描,控制是哪一位数码管有效。所谓动态扫描显示就是轮流向各位数码管送出字形码和相应的位选,利用发光数码管的余晖和人眼视觉残留的作用,使人感觉好像各位数码管同时都在显示。
扩展:眼睛的另一个重要特性是视觉惰性,即光象一旦在视网膜上形成,视觉将会对这个光象的感觉维持一个有限的时间,这种生理现象叫做视觉暂留性,对于中等亮度的光刺激,视觉暂留时间约为0.05至0.2秒。
优点:硬件简单(数码管越多,这个优势越明显),由于每个数码管只有一个被点亮,所以数码管消耗的电流较小。
缺点:数码管亮度不如静态显示的亮度高,如果刷新率低,会出现闪烁的现象。
2、数码管码表
//数码管码表,共阳极
unsigned char leddata[]={
0xC0, //"0"
0xF9, //"1"
0xA4, //"2"
0xB0, //"3"
0x99, //"4"
0x92, //"5"
0x82, //"6"
0xF8, //"7"
0x80, //"8"
0x90, //"9"
0x88, //"A"
0x83, //"B"
0xC6, //"C"
0xA1, //"D"
0x86, //"E"
0x8E, //"F"
0x89, //"H"
0xC7, //"L"
0xC8, //"n"
0xC1, //"u"
0x8C, //"P"
0xA3, //"o"
0xBF, //"-"
0xFF, //熄灭
0xFF //自定义
};
//数码管码表,共阴极
unsigned char 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, //熄灭
0x00 //自定义
};
3、位选IO管脚定义
sbit smg1 = P2^0;
sbit smg2 = P2^1;
sbit smg3 = P2^2;
sbit smg4 = P2^3;
4、延时函数
//注意:必须包含<intrins.h>头文件才能使用
void Delay1ms() //@11.0592MHz
{
unsigned char i, j;
_nop_();
i = 2;
j = 199;
do
{
while (--j);
} while (--i);
}
void delay_ms(unsigned int time)
{
unsigned int i;
for(i=0; i<time; i++)
{
Delay1ms();
}
}
5、动态显示一位数码管
//在数码管显示一位数字显示函数,
//unsigned char i 输入0-9以内的数字
void disply_one_digit(unsigned char i)
{
P0 = leddata[i];
smg4 = 0;
delay_ms(5);
smg4 = 1;
}
6、动态显示两位数码管
//在数码管显示两位数字显示函数,
//unsigned char i 输入0-99以内的数字
void disply_two_digit(unsigned char i)
{
unsigned char shi,ge;
shi = i / 10;
ge = i % 10;
P0 = leddata[ge];
smg4 = 0;
delay_ms(5);
smg4 = 1;
P0 = leddata[shi];
smg3 = 0;
delay_ms(5);
smg3 = 1;
}
7、动态显示三位数码管
//在数码管显示三位数字显示函数,
//unsigned char i 输入0-999以内的数字
void disply_three_digit(unsigned int i)
{
unsigned int ge,shi,bai;
bai = i / 100;
shi = i % 100 / 10;
ge = i % 10;
P0 = leddata[ge];
smg4 = 0;
delay_ms(5);
smg4 = 1;
P0 = leddata[shi];
smg3 = 0;
delay_ms(5);
smg3 = 1;
P0 = leddata[bai];
smg2 = 0;
delay_ms(5);
smg2 = 1;
}
8、动态显示四位数码管
//在数码管显示四位数字显示函数,
//unsigned char i 输入0-9999以内的数字
void disply_four_digit(unsigned int i)
{
unsigned int ge,shi,bai,qian;
qian = i / 1000 % 10;
bai = i / 100 % 10;
shi = i / 10 % 10;
ge = i % 10;
P0 = leddata[ge];
smg4 = 0;
delay_ms(5);
smg4 = 1;
P0 = leddata[shi];
smg3 = 0;
delay_ms(5);
smg3 = 1;
P0 = leddata[bai];
smg2 = 0;
delay_ms(5);
smg2 = 1;
P0 = leddata[qian];
smg1 = 0;
delay_ms(5);
smg1 = 1;
}
9、主函数调用示例
void main()
{
while(1)
{
// disply_one_digit(5);
//
// disply_two_digit(9);
//
// disply_three_digit(123);
disply_four_digit(1234);
}
}