2017年11月18日
数码管计时器程序
#include<reg52.h>
单片机头文件
#include<intrins.h>
#include<intrins.h>
调用intrins函数库
#define uint unsigned int
#define uchar unsigned char
#define uint unsigned int
#define uchar unsigned char
宏定义名称替换
sbit we = P2^7;
sbit du = P2^6;
sbit LED1 = P1^0;
sbit we = P2^7;
sbit du = P2^6;
sbit LED1 = P1^0;
位声明段选、位选和LED灯信号
uchar counter,time_counter;
无符号字符型
uchar 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, //熄灭
0x00 //自定义
};
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 //自定义
};
数码管显示数据,可以由软件生成,这里用的是共阴极数码管
void delay(uint z)
{
uint x,y;
for(x = z;x > 0;x --)
for(y = 112;y > 0;y --);
}
{
uint x,y;
for(x = z;x > 0;x --)
for(y = 112;y > 0;y --);
}
延时函数,以便后面调用
void display(uchar i)
数码管显示函数
{
uchar shi,ge;
{
uchar shi,ge;
无符号字符型数据 shi、ge
shi = i /10;
shi = i /10;
ge = i % 10;
区分十位和个位,商是十位余数是个位
P0 = 0xff;
we = 1;
P0 = 0xfe;
we = 0;
P0 = 0xff;
we = 1;
P0 = 0xfe;
we = 0;
du = 1;
P0 = leddata[shi];
du = 0;
delay(5);
P0 = leddata[shi];
du = 0;
delay(5);
P0 = 0xff;
we = 1;
P0 = 0xfd;
we = 0;
we = 1;
P0 = 0xfd;
we = 0;
du = 1;
P0 = leddata[ge];
du = 0;
delay(5);
P0 = leddata[ge];
du = 0;
delay(5);
上面的程序是数码管会显示的数字
}
}
void main()
主函数
{
{
51单片机定时器有四种工作方式:
1、方式0,13位定时计数器,最大计数值2^13=8192也就是说定时8192个机器周期;
2、方式1,16位定时计数器,最大计数值2^16=65536也就是说定时65536个机器周期,这种方式可实现最大的定时时间和最大计数次数,是常用的方式之一;
3、方式2,8位自动重装计时方式,最大计数值2^8=256也就是说定时256个机器周期,此方式工作时不用重装值精度高,在串口通讯时常用此方式;
4、方式3,特殊功能方式,将定时器0分成两个彼此独立的8位计数器;
TMOD = 0X01;
TMOD = 0X01;
C51单片机有两个定时/计数器,这里用的时定时器0,工作方式1的十六位定时/计数器
TH0 = (65536-45872)/256;
TL0 = (65536-45872)%256;
这段程序是给定时器/计数器重装初值,让它们从指定的数字开始计数的一个指令,256是把方式1中的16位定时/计数器分成高八位和低八位其中取商的是高八位,取余数的是低八位
TR0 = 1;
TR0 = 1;
这是在定好定时器和其工作方式之后打开定时器的指令,如果是定时器1那这里就是TR1 = 1,说明一下我的开发板上用的是HTC宏晶公司的89C52单片机,52单片机本质上与51单片机并没有什么区别主要是它比51单片机多一个定时器/计数器,也就是说51单片机只有一个定时/计数器
while(1)
{
if(TF0 == 1)
while(1)
{
if(TF0 == 1)
这是查询计时器0/计数器0的溢出标志位是否为1
TF0是定时器0的溢出标志位,当定时器0计满数字溢出时由硬件使TF0置1并申请中断。进入中断服务程序后由硬件自动清0。如果使用定时器中断那么就不需要人为操作,但是如果使用软件查询方式的话,当查询到该位为1后就需要软件清0了。
而什么是溢出呢???
打个简单的比方日常烧水,水烧开了就相当于是单片机计数溢出你要采取后续的动作或程序来响应这个信号,这就是溢出!
{
TF0 = 0;
{
TF0 = 0;
TF0在单片机中是定时器0/计数器0溢出标志位,这里是它的软件清零
TH0 = 0x4b;
TL0 = 0xfe;
counter ++;
}
TH0 = 0x4b;
TL0 = 0xfe;
counter ++;
}
延时50ms,counter加1
if(counter == 20)
{
counter = 0;
LED1 = ~LED1;
if(counter == 20)
{
counter = 0;
LED1 = ~LED1;
LED灯每隔一秒亮一次
time_counter ++;
time_counter ++;
}
counter函数加满二十次也就是1000ms=1s时LED灯闪烁一次time_counter函数加1数码管数字显示加1
if(time_counter == 60)
if(time_counter == 60)
检测time_counter函数是否加了60次也就是1min
time_counter = 0;
time_counter = 0;
如果加到1min那么time_counter函数清零
display(time_counter);
display(time_counter);
显示time_counter函数数字
}
}
}
}