#include
#define uchar unsigned char
#define uint unsigned int
sbit dula=P0^6;
sbit wela=P0^7;
uchar num, duan_num, wei_num;
uchar code table_duan[]={
0x3f,0x06,0x5b,0x4f,0x66,0x6d,
0x7d,0x07,0x7f,0x6f,0x77,0x7c,
0x39,0x5e,0x79,0x71};
uchar code table_wei[]={
0xfe,0xfc,0xfb,0xf7,0xef,0xdf};
void display();
void main()
{
//打开定时器中断
EA=1;
ET0=1;
//设置定时器工作模式
TMOD=0x01;
//十六位定时器,就使用65536,装初值
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
//启动定时器,有几种启动方式
TR0=1;
while(1)
{
if(num==20) //是否到了1s
{
num=0;
if(duan_num==6)
{
duan_num=0;
}
if(wei_num==6)
{
wei_num=0;
}
display();
duan_num++;
wei_num++;
}
}
}
//中断函数不需要声明和调用
void time0() interrupt 1
{
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
num++;
}
void display()
{
P0=table_duan[duan_num+1];
dula=1;
dula=0;
P0=table_wei[wei_num];
wela=1;
wela=0;
}
程序加载到单片机中,看到数码管是1个个地显示,第一个数码管显示1,第二个数码管显示2,……1秒钟显示一个数码管。
然后老师将程序进行修改。
#include
#define uchar unsigned char
#define uint unsigned int
sbit dula=P0^6;
sbit wela=P0^7;
uchar num, duan_num, wei_num;
uchar code table_duan[]={
0x3f,0x06,0x5b,0x4f,0x66,0x6d,
0x7d,0x07,0x7f,0x6f,0x77,0x7c,
0x39,0x5e,0x79,0x71};
uchar code table_wei[]={
0xfe,0xfc,0xfb,0xf7,0xef,0xdf};
void display();
void main()
{
//打开定时器中断
EA=1;
ET0=1;
//设置定时器工作模式
TMOD=0x01;
//十六位定时器,就使用65536,装初值
TH0=(65536-500)/256;
TL0=(65536-500)%256;
//启动定时器,有几种启动方式
TR0=1;
while(1)
{
if(num==2) //是否到了1s
{
num=0;
if(duan_num==6)
{
duan_num=0;
}
if(wei_num==6)
{
wei_num=0;
}
display();
duan_num++;
wei_num++;
}
}
}
//中断函数不需要声明和调用
void time0() interrupt 1
{
TH0=(65536-500)/256;
TL0=(65536-500)%256;
num++;
}
这个就是动态扫描。
每个数码管是1ms的显示间隔。我们从原来的1s,除以1000,得到1ms。
动态显示的特点是将所有数码管的段选线并联在一起,由位选线控制室哪一位数码管有效。这样就没有并要为每一位数码管配一个锁存器,大大简化了硬件电路。选亮数码管采用动态扫描显示。
所谓动态扫描,即是通过分时轮流送出字形码和相应的位选,使各个数码管轮流收控显示。在轮流显示的过程中,每一位数码管的点亮时间为1~2ms,由于人的视觉暂留现象及发光二极管的余晖效应,尽管实际上各位数码管并非同时点亮,但只要扫描的速度足够快,给人的印象就是一个稳定的显示资料,不会有闪烁感,动态显示的效果和静态显示是一样的,能够节省大量的I/O口,而且功耗降低。
数码管的消隐:
延迟函数的测试:
3位数码管显示秒数。从0到999。
#include
#define uchar unsigned char
#define uint unsigned int
sbit dula=P0^6;
sbit wela=P0^7;
uchar num, duan_num, wei_num;
uint disnum;
uchar code table_duan[]={
0x3f,0x06,0x5b,0x4f,0x66,0x6d,
0x7d,0x07,0x7f,0x6f,0x77,0x7c,
0x39,0x5e,0x79,0x71};
uchar code table_wei[]={
0xfe,0xfc,0xfb,0xf7,0xef,0xdf};
void display(uint);
void delay(uchar);
void main()
{
//delay(10);
//打开定时器中断
EA=1;
ET0=1;
//设置定时器工作模式
TMOD=0x01;
//十六位定时器,就使用65536,装初值
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
//启动定时器,有几种启动方式
TR0=1;
while(1)
{
if(num==20) //是否到了1s
{
num=0;
if(disnum==1000)
{
disnum=0;
}
disnum++;
}
display(disnum);
}
}
//中断函数不需要声明和调用
void time0() interrupt 1
{
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
num++;
}
void display(uint disnum)
{
P0=table_duan[disnum/100];
dula=1;
dula=0;
P0=table_wei[0];
wela=1;
wela=0;
delay(10);
P0=table_duan[disnum%100/10];
dula=1;
dula=0;
P0=table_wei[1];
wela=1;
wela=0;
delay(10);
P0=table_duan[disnum%100%10];
dula=1;
dula=0;
P0=table_wei[2];
wela=1;
wela=0;
delay(10);
}
void delay(uchar x)
{
uchar a, b;
for(a=x;a>0;a--)
{
for(b=200;b>0;b--);
}
}
delay(),这个函数的功能是数码管的间接延时。1个数码管点亮保持一段时间,然后点亮第二个数码管,再延迟保持一段时间,然后再点亮第三个数码管。这样反复运行。
disnum其实应该使用sec更加合适。
delay这个时间不要太长。正常要控制在10ms之内。