文档库 最新最全的文档下载
当前位置:文档库 › 定时器初始值确定

定时器初始值确定

> 单片机 > 实例进阶 > 数码管前三位显示1个跑表,从000到999之间以1%秒速度运行,当按下一个独立键盘时跑表停止...
数码管前三位显示1个跑表,从000到999之间以1%秒速度运行,当按下一个独立键盘时跑表停止...
时间:2010-4-24 21:58:51 来源:https://www.wendangku.net/doc/205119541.html, 作者:大头爸爸 点击:405次 数码管前三位显示一个跑表,从000到999之间以1%秒速度运行,当按下一个独立键盘时跑表停止,松开手后跑表继续运行。(用定时器设计表)。

题目分析:
1、要求以1%秒的速度运行。即10ms数字更换一次。
定时器的初值=2n-定时时间/机器周期(n为计数器的工作方式位数,如方式0,13位定时器,n值为13)

那么本题中,根据上面公式,求得定时器10ms能累加9216次。

所以这里能判断,可以只能用计数器方式1(16位计数器)。初值为:65536-9216

计数器方式0(13位计数器)和计数器方式2(8位初值自动重装的8位定时器/计数器)都不符合要求。
因为13位计数器满值为:213=8192 小于9216

以下是代码片段:

#include
#define uchar unsigned char
#define uint unsigned int
uchar code table[]={
0x3f,0x06,0x5b,0x4f,0x66,0x6d,
0x7d,0x07,0x7f,0x6f,0x77,0x7c,
0x39,0x5e,0x79,0x71
};

uchar bai,shi,ge;
uint shu;//调试了一个小时,真晕。问题出在这!!!我这个猪脑子。
sbit dula=P2^6;
sbit wela=P2^7;
sbit s2=P3^4;//独立键盘s2

//初始化
void init()
{
TMOD=0x01;
TH0=0xdc;//(65536-9216)/256=220
TL0=0x00;//(65536-9216)%256=0
EA=1;
ET0=1;
TR0=1;
wela=0;
dula=0;
}

void delay(uchar ms)
{
uchar i,j;
for(i=ms;i>0;i--)
for(j=114;j>0;j--);
}

//在数码管动态显示
void display()
{
//显示个位
P0=table[ge];
dula=1;
dula=0;
P0=0xfb;
wela=1;
wela=0;
delay(20);
//显示十位
P0=table[shi];
dula=1;
dula=0;
P0=0xfd;
wela=1;
wela=0;
delay(20);
//显示百位
P0=table[bai];
dula=1;
dula=0;
P0=0xfe;
wela=1;
wela=0;
delay(20);
}
void main()
{
init();
while(1)
{
display();//在数码管显示
if(s2==0)
{
delay(10);//去抖
if(s2==0)
{
TR0=0;//如果键被按下,则停止计数
while(!s2)display();//在此等待按键松开,松开后,继续计数
TR0=1;
}
}
}
}

void T0_timer() interrupt 1
{
TH0=0xdc;
TL0=0x00;
shu++;
if(shu>999)
shu=0;
//提取百位,十位和个位。
bai=shu/100;//提取百位数
shi=shu%100/10;//提取十位数
ge=shu%10;//提取个位数
}

注意问题:

1、考虑数码动态显示出现的问题——中间的延时时间长度

如果用下面方法延时

j=200;while(j--); j的范围在200~700左右。突破1000以上,显示不连贯;小于150以下,不应该显示的地方略暗隐约显示,效果

不好。

2、中断事件是每10ms发生一次。考虑延时与中断之关的关系。我这里将百位、十位、个位分解是放在中断处理程序中的。考虑一下为什么不能放到display函数中。

3、注意数据类型所容纳值的范围。unsigned char型,最大值是256。


在上题的基础上,用另外三个独立键盘实现按下第一个时计时停止,按下第二个时计时开始,按下第三个是计数值清零从头开始。

以下是程序代码:

#include
#define uchar unsigned char
#define uint unsigned int
uchar code table[]={
0x3f,0x06,0x5b,0x4f,0x66,0x6d,
0x7d,0x07,0x7f,0x6f,0x77,0x7c,
0x39,0x5e,0x79,0x71
};

uchar bai,shi,ge;
uint shu;
sbit dula=P2^6;
sbit wela=P2^7;
sbit s2=P3^4;//独立键盘s2

sbit s3=P3^5;//独立键盘s3
sbit s4=P3^6;//独立键盘s4
sbit s5=P3^7;//独立键盘s5

//初始化
void init()
{
shu=0;
TMOD=0x01;
TH0=0xdc;//(65536-9216)/256=220
TL0=0x00;//(65536-9216)%256=0
EA=1;
ET0=1;
TR0=1;
wela=0;
dula=0;
}

void delay(uchar ms)
{
uchar i,j;
for(i=ms;i>0;i--)
for(j=114;j>0;j--);
}

void display()
{
//显示个位
P0=0xfb;
wela=1;
wela=0;
P0=table[ge];
dula=1;
dula=0;
delay(10);
//显示十位
P0=0xfd;
wela=1;
wela=0;
P0=table[shi];
dula=1;
dula=0;
delay(10);
//显示百位
P0=0xfe;
wela=1;
wela=0;
P0=table[bai];
dula=1;
dula=0;
delay(10);
}


//按键检查函数
void scankey()
{
//按下去第一个暂停,松开手继续
if(s2==0)
{
delay(10);
if(s2==0)
{
TR0=0;
while(s2==0)display();//等待释放按键
//上面如果等待按键释放,则按下去后,只显示一位数(因为是动态显示),下面同理。
TR0=1;
}
}
//按下第一个时计时停止
if(s3==0)
{
delay(10);
if(s3==0)
{
//while(s3==0);//等待释放按键
TR0=0;
}
}
//按下第二个时计时开始
if(s4==0)
{
delay(10);
if(s4==0)
{
//while(s4==0);//等待释放按键
TR0=1;
}
}
//按下第三个是计数值清零从头开始
if(s5==0)
{
delay(10);
if(s5==0)
{
//while(s5==0);//等待释放按键
shu=0;
TR0=1;
}
}
}

void main()
{
init();
while(1)
{
scankey();
//在数码管动态显示
display();
}
}

void T0_timer() interrupt 1
{
TH0=0xdc;
TL0=0x00;
shu++;
if(shu>999) shu=0;
//提取百位,十位和个位。
bai=shu/100;//提取百位数
shi=shu%100/10;//提取十位数
ge=shu%10;//提取个位数
}

相关文档