/*
名称:51单片机之数码管显示实验
说明:对于数码管来说,其本质上可以理解为按照一定规则组合的多个二极管。其使用只需按照特定规则显示对应的二极管即可。要稍微注意一点的就是多个数码管的显示分为静态显示和动态显示。静态显示就是每个二极管显示的内容是一样的,通过片选信号来决定是哪个二极管该显示。动态数码管,即利用人眼的视觉停留效果,快速扫描,快速显示每个数码管的内容,使得每个数码管看起来好像是一起显示的一样。
本实验编写了几个数码管显示的简单程序。在此不做赘述了。
*/
#include <reg52.h>
#define uchar unsigned char
//共阳极段码(a在高位,dp在低位)
uchar code _data[16] = {0x03,0x9F,0x25,0x0D,0x99,0x49,0x41,0x1F,0x01,0x09,
0x11,0xC1,0x63,0x85,0x61,0x71
};
//共阳极段码(a在低位,dp在高位)
uchar code _data1[16] = {0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90,0x88,
0x83,0xC6,0xA1,0x86,0x8E
};
//延时函数
void delay_ms(unsigned int n)
{
unsigned int i=0,j=0;
for(i=0;i<n;i++)
for(j=0;j<123;j++);
}
//一位数码管循环显示0-F(共阳极)
void OneNixieTube()
{
uchar i = 0;
while(1)
{
for(i = 0;i<16;++i)
{
P2 = _data1[i];
delay_ms(1000);
}
}
}
//静态数码管循环显示0-8
void StaticNixieTube()
{
uchar i = 0,temp = 0;
while(1)
{
for(i = 0;i<16;++i)
{
//片选部分
if(i%8 == 0)
temp = 0x01;
else
temp = temp<<1;
P0 = ~temp; //P0为片选输出端口,低电平有效
//显示部分
P2 = ~_data1[i]; //P2为显示输出端口
delay_ms(1000);
}
}
}
//动态数码管显示(0-7,8-F,8个数码管分两次显示)
void DynamicNixieTube()
{
uchar i = 0;
unsigned int delay_time = 0; //0-7 8-F每段的延时时间
uchar CS[8] = {0xFE,0xFD,0xFB,0xF7,0xEF,0xDF,0xBF,0x7F}; //片选码
while(1)
{
if(delay_time++ < 250)
{
//0-7段显示
for(i = 0;i < 8;++i)
{
P0 = CS[i];
P2 = ~_data1[i];
delay_ms(1); //延时极小的时间间隔,人眼察觉不出来
}
}
else if(delay_time++ < 500 ) //???都是循环250次,为什么0-7段显示的时间长于8-F段显示的时间???
{
//8-F段显示
for(i = 0;i < 8;++i)
{
P0 = CS[i];
P2 = ~_data1[i+8];
delay_ms(1); //延时极小的时间间隔,人眼察觉不出来
}
}
else
delay_time = 0; //重新置零
}
}
//数码管显示指定时间格式为 HH-MM-SS
void DisplayTime(uchar hour,uchar min,uchar sec)
{
uchar time[8] = {0};
uchar i = 0,j = 0;
uchar CS[8] = {0xFE,0xFD,0xFB,0xF7,0xEF,0xDF,0xBF,0x7F}; //片选码
//获取时间的每位信息
if(hour >= 0 && hour <=23 )
{
time[0] = hour / 10;
time[1] = hour % 10;
time[2] = ':';
}
if(min >= 0 && min <= 59)
{
time[3] = min /10;
time[4] = min % 10;
time[5] = ':';
}
if(sec >= 0 && sec <= 59)
{
time[6] = sec / 10;
time[7] = sec % 10;
}
//显示部分
for(i = 0;i<7;++i)
{
for(i = 0;i < 8;++i)
{
P0 = CS[i]; //片选
//显示时间
if(i != 2 && i != 5)
{
j = time[i];
P2 = ~_data1[j];
}
else //显示分隔符‘-’
{
j = 0xBF;
P2 = ~j;
}
delay_ms(1); //延时极小的时间间隔,人眼察觉不出来
}
}
}
int main()
{
// OneNixieTube();
// StaticNixieTube();
//DynamicNixieTube()
//DisplayTime(12,40,56);
return 0;
}