Ai8G利用定时器实现延时,精度不准确,求指正
#include <STC8G.H>void GPIO_Init(void)
{
P5M0 |= 0x10; P5M1 &= ~0x10;
}
void Delay_Us(uint us)//@12.000MHz
{
AUXR &= 0x7F;//定时器时钟12T模式
TMOD &= 0xF0;
TMOD |= 0x01;
TH0 = (65536 - us)/256;
TL0 = (65536 - us)%256;
TF0 = 0; //清除TF0标志
TR0 = 1;//定时器0开始计时
while(!TF0);
TR0 = 0;
TF0 = 0;//清除TF0标志
}
void main()
{
GPIO_Init();
while(1)
{
P54 = 1;
Delay_Us(200);
P54 = !P54;
Delay_Us(200);
}
}
延时的200us变成延迟320us,求大佬们指点
针对您提出的关于STC8G系列单片机使用定时器实现延时精度不准确的问题,以下是对代码及延时机制的分析与建议。
首先,您的代码中使用了定时器0(Timer 0)来实现微秒级延时。该方法在理论上是可行的,但实际效果可能受多种因素影响,包括系统时钟频率、定时器配置、中断处理以及程序执行时间等。以下是对代码的逐行分析和改进建议:
1. GPIO初始化函数:
P5M0 |= 0x10; P5M1 &= ~0x10;
此段代码将P5.4引脚设置为推挽输出模式,逻辑正确,无问题。
2. DelayUs函数:
AUXR &= 0x7F;:此操作将定时器时钟模式设置为12T模式,即每12个时钟周期完成一次计数。这是正确的配置,适用于大多数情况。
TMOD &= 0xF0; TMOD |= 0x01;:将定时器0设置为方式1(16位定时器),逻辑正确。
TH0 = (65536 - us)/256; TL0 = (65536 - us)%256;:此部分计算的是定时器初值,用于实现指定时间的延时。然而,此处存在一个关键问题:未考虑系统时钟频率。
STC8G系列单片机的系统时钟通常为12MHz或更高,但代码中并未明确指定时钟频率。若系统时钟为12MHz,则每个机器周期为1μs;若为24MHz,则每个机器周期为0.5μs。因此,延时时间的计算必须基于实际时钟频率。
假设系统时钟为12MHz,那么定时器的计数频率为12MHz / 12 = 1MHz,即每个计数周期为1μs。此时,延时时间应为:
us = (65536 - TH0256 - TL0) / 1
因此,原代码中直接使用us作为初始值的方式是错误的。
正确的做法是根据目标延时时间计算定时器初值。例如,若希望延时200μs,则:
TH0 = (65536 - 200) / 256;
TL0 = (65536 - 200) % 256;
3. 延时精度问题:
您提到的“200μs变成320μs”可能是由于以下原因导致:
系统时钟频率未正确配置;
定时器初始化代码被其他操作干扰;
程序中存在额外的指令开销,导致实际延时时间变长;
中断服务程序未关闭,导致定时器被意外重置。
4. 改进建议:
明确系统时钟频率,并根据该频率重新计算定时器初值;
在延时函数开始前关闭全局中断,避免中断干扰;
使用更精确的延时方法,如使用定时器中断配合标志位判断;
对于高频系统(如24MHz以上),可考虑使用定时器1或调整定时器模式以提高精度。
综上所述,您当前的延时函数存在一定的误差,主要原因是未充分考虑系统时钟频率对定时器的影响。建议根据实际时钟频率重新计算定时器初值,并优化延时函数结构,以提高延时精度。如需进一步帮助,欢迎提供更多系统配置信息。
[本文内容由国芯人工智能辅助生成,仅供参考] 国芯人工智能 发表于 2025-8-15 20:38
针对您提出的关于STC8G系列单片机使用定时器实现延时精度不准确的问题,以下是对代码及延时机制的分析与建 ...
您好,我想要实现的是任意微秒的延时,需要做哪些修改 微秒级延时,寄存器操作时间和数学运算时间不能忽略,程序中有减法除法取余运算是耗时间的,而毫秒级延时,这些时间占比很小,才可以忽略不计 DebugLab 发表于 2025-8-16 19:52
微秒级延时,寄存器操作时间和数学运算时间不能忽略,程序中有减法除法取余运算是耗时间的,而毫秒级延时, ...
是的,感谢指正
页:
[1]