功能:使用数码管以及定时器实现时间数码跑灯
分析 :
问题一 如何用定时器实现定时10ms?
答案: 10ms = 10000us 用这个时间除以机器周期 10000 / 1.085 = 9217 那么只需要从 |9217-65535| 开始加起来,就行。
再将56319 换算成十六进制 就行,为 dbff 那么高八位 就是 0xdb 低八位就是0xff .
问题二 如何实现 用数码管显示 定时器的值?
答案:数码管跑灯本质就是数码管不断刷新字符得到,对于任何一个时间,例如4271 这应该是经过数次时间之后的,要想显示在数码管上,要将对应的数。赋值给不同的数码管。
首先介绍两个 运算符 % 和 /
对于 % a%b 得到的是 a/b 的余数;例如 4271%1000 结果就是 271。
对于 / a/b 得到的是 a/b 的商;例如 4271%1000 结果就是 4。
那么将4271的个十百千位分离出来就是非常简单
千位 4271 / 1000
百位 4271 %1000 / 100
十位 4271%100/10
个位 4271 % 10
注:1 对于 for 语句 如果其后面不加 {},就只能执行 其后的一个语句。
#include <reg52.h>
#include <intrins.h>
#define uint unsigned int
#define uchar unsigned char
sbit du = P2^6;//数码管段选
sbit we = P2^7;//数码管位选
sbit s2 = P3^0;//独立按键S2
sbit s3 = P3^1;//独立按键S3
sbit s4 = P3^2;//独立按键S4
sbit s5 = P3^3;//独立按键S5
uchar num;//数码管显示的值
//共阴数码管段选表0-9
uchar code leddata[]= {0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07, 0x7F, 0x6F,};
//毫秒级延时函数定义
void delay(uint z)
{
uint x,y;
for(x = z; x > 0; x--)
for(y = 114; y > 0 ; y--);
}
void main ()
{ uint a;
TMOD = 0x01; // 定时器0 16位定时器
TH0 = 0xdb;
TL0 = 0xff; //定时10ms 具体计算方法见上面分析
while(1)
{
if (TF0 == 1)
{
TF0 = 0;
TH0 = 0xdb;
TL0 = 0xff;
a++;
if(a > 9999)
a = 0;
}
we = 1;
P0 = 0xf7;
we = 0;
du = 1;
P0 = leddata[a / 1000];
du = 0;
delay(5);
we = 1;
P0 = 0xfb;
we = 0;
du = 1;
P0 = leddata[a % 1000 / 100];
du = 0;
delay(5);
we = 1;
P0 = 0xfd;
we = 0;
du = 1;
P0 = leddata[a % 100 / 10];
du = 0;
delay(5);
we = 1;
P0 = 0xfe;
we = 0;
du = 1;
P0 = leddata[ a % 10];
du = 0;
delay(5);
if (s2 == 0)
{
delay(5);
if(s2 == 0)
{
TR0 = 1;
while(!s2);
}
}
if (s3 == 0)
{
delay(5);
if(s3 == 0)
{
TR0 = 0;
}
while(!s5);
}
if (s4 == 0)
{
delay(5);
if(s4 == 0 && TR0 ==0)
{
a++;
}
while(!s4);
}
if (s5 == 0)
{
delay(5);
if(s5 == 0 && TR0 ==0)
{
a--;
}
while(!s5);
}
}
}