标题:
为什么单片机计时器的计时功能一直都不准,而且偏差很大?
[打印本页]
作者:
善良的大学生
时间:
2020-6-2 09:51
标题:
为什么单片机计时器的计时功能一直都不准,而且偏差很大?
单片机源程序如下:
#include<reg52.h>
sbit KEY1 = P3^0;
sbit KEY2 = P3^1;
sbit KEY3 = P3^2;
sbit KEY4 = P3^3;
unsigned char code LedChar[] = {
0xC0, 0xF9, 0xA4, 0xB0, 0x99, 0x92, 0x82, 0xF8,
0x80, 0x90, 0x88, 0x83, 0xC6, 0xA1, 0x86, 0x8E
};
unsigned char LedBuff[6] = {
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
};
unsigned char KeySta[4] = {1,1,1,1};
unsigned char T0RH = 0;
unsigned char T0RL = 0;
bit kd = 0;
bit lk = 1;
bit stopwatchRefresh = 1;
bit stopwatchRunning = 0;
unsigned char DecimalPart = 0;
unsigned int IntegerPart = 0;
void ConfigTimer0(unsigned int ms);
void stopwatchDisplay();
void KeyDriver();
void main()
{
EA = 1;
ConfigTimer0(2);
while(1)
{
if(stopwatchRefresh)
{
stopwatchRefresh = 0;
stopwatchDisplay();
}
KeyDriver();
}
}
void ConfigTimer0(unsigned int ms)
{
unsigned long tmp;
tmp = 11059200/12;
tmp = (tmp*ms)/1000;
tmp = 65536 - tmp;
tmp +=18;
T0RH = (unsigned char)(tmp>>8);
T0RL = (unsigned char)tmp;
TMOD &=0xf0;
TMOD |=0X01;
TH0 = T0RH;
TL0 = T0RL;
ET0 = 1;
TR0 = 1;
}
void stopwatchDisplay()
{
signed char i;
unsigned char buf[4];
LedBuff[0] = LedChar[DecimalPart%10];
LedBuff[1] = LedChar[DecimalPart/10];
buf[0] = IntegerPart%10;
buf[1] = IntegerPart/10%10;
buf[2] = IntegerPart/100%10;
buf[3] = IntegerPart/1000%10;
for(i=3;i>=1;i--)
{
if(buf[ i]==0)
{
LedBuff[i+2]=0xFF;
}else break;
}
for(;i>=0;i--)
{
LedBuff[i+2] = LedChar[buf[ i]];
}
LedBuff[2] &=0x7f;
}
void Stopwatchjc()
{
signed char i;
unsigned char buf[4];
static unsigned char Dec[10] = 0;
static unsigned int Int[10] = 0;
static char cnt = 0;
static char cnt1 = 0;
Dec[cnt] = DecimalPart;
Int[cnt] = IntegerPart;
cnt++;
if(kd == 1)
{
LedBuff[0] = LedChar[Dec[cnt1]%10];
LedBuff[1] = LedChar[Dec[cnt1]/10];
buf[0] = Int[cnt1]%10;
buf[1] = Int[cnt1]/10%10;
buf[2] = Int[cnt1]/100%10;
buf[3] = Int[cnt1]/1000%10;
for(i=3;i>=1;i--)
{
if(buf[ i]==0)
{
LedBuff[i+2]=0xFF;
}else break;
}
for(;i>=0;i--)
{
LedBuff[i+2] = LedChar[buf[ i]];
}
LedBuff[2] &=0x7f;
cnt1++;
}
}
void Stopwatchsy()
{
stopwatchRunning = 0;
kd = 1;
stopwatchRefresh = 1;
}
void StopwatchAction()
{
stopwatchRunning = ~stopwatchRunning;
}
void StopwatchReset()
{
stopwatchRunning = 0;
lk = 0;
DecimalPart = 0;
IntegerPart = 0;
stopwatchRefresh = 1;
}
void KeyDriver()
{
static unsigned char backup[4] = {1,1,1,1};
unsigned char i;
for(i=0;i<4;i++)
{
if (KeySta[ i] != backup[ i])
{
if (backup[ i] == 0)
{
if(i==0)
Stopwatchjc();
else if(i==1)
Stopwatchsy();
else if(i==2)
StopwatchReset();
else if(i==3)
StopwatchAction();
}
backup[ i] = KeySta[ i];
}
}
}
void LedScan()
{
static unsigned char i=0;
P0 = 0xFF;
switch(i) //??1y1ms′óμíμ??????¢D?ò???êy??1ü
{
case 0:P2=0x01;i++; P0= LedBuff[0]; break;
case 1:P2=0x02;i++; P0= LedBuff[1]; break;
case 2:P2=0x04;i++; P0= LedBuff[2]; break;
case 3:P2=0x08;i++; P0= LedBuff[3]; break;
case 4:P2=0x10;i++; P0= LedBuff[4]; break;
case 5:P2=0x20;i=0; P0= LedBuff[5]; break;
default :break;
}
}
void KeyScan()
{
static unsigned char keybuf[4] ={ 0xFF,0xFF,0xFF,0xFF};
static unsigned char i=0;
keybuf[0] = (keybuf[0]<<1) | KEY1;
keybuf[1] = (keybuf[1]<<1) | KEY2;
keybuf[2] = (keybuf[2]<<1) | KEY3;
keybuf[3] = (keybuf[3]<<1) | KEY4;
for(i=0;i<4;i++)
{
if (keybuf[ i] == 0x00)
{
KeySta[ i] = 0;
}
else if (keybuf[ i] == 0xFF)
{
KeySta[ i] = 1;
}
else
{}
}
}
void StowatchCount()
{
if(stopwatchRunning)
{
DecimalPart++;
if(DecimalPart>=100)
{
DecimalPart=0;
IntegerPart++;
if(IntegerPart>=10000)
{
IntegerPart=0;
}
}
stopwatchRefresh=1;
}
}
void InterruptTimer0() interrupt 1
{
static unsigned char ter10ms = 0;
TH0 = T0RH;
TL0 = T0RL;
LedScan();
KeyScan();
ter10ms++;
if (ter10ms>=5)
{
ter10ms = 0;
StowatchCount();
}
}
复制代码
作者:
xianfajushi
时间:
2020-6-2 16:28
中断里面放置太多其他执行东西影响了。
作者:
yzwzfyz
时间:
2020-6-2 21:40
你如何证明你有的晶振是:11.0592,而不是11.0510呢?
作者:
xianfajushi
时间:
2020-6-4 08:39
可参我这个回复的例子中的中断使用,计时和其它操作莫放在中断里面。
https://ask.csdn.net/questions/1078609
作者:
xianfajushi
时间:
2020-6-4 18:45
无标题.png
(529.82 KB, 下载次数: 34)
下载附件
2020-6-4 18:45 上传
欢迎光临 (http://www.51hei.com/bbs/)
Powered by Discuz! X3.1