我正试着在Atmega8上做一个时钟。我有8 8Mhz石英。
我对时钟时钟使用timer0中断:
/* Settings */
#define TMR_RELOAD 80 - 5 /* 8 kHz / 80 = 100 Hz */
#define TMR_CNT_MAX 100 /* 1Hz internal counter */
/* internal variables */
static uint8_t tmr_cnt;
inline void TMR0_Init()
{
/* set clock source f_t0 = 8МHz/1024 = 8 kHz */
TCCR0 = _BV(CS00) | _BV(CS02);
TIMSK |= _BV(TOIE0); /* Enable TMR0 interrupt on overflow*/
}
ISR (TIMER0_OVF_vect)
{
if (tmr_cnt == 0)
Clock_Tick1s();
tmr_cnt++;
if (tmr_cnt >= TMR_CNT_MAX)
tmr_cnt = 0;
TCNT0 -= TMR_RELOAD;
}问题是我的钟跑得太快或太慢.
我在TCNT0寄存器中输入的计算值为80,但在这种情况下,时钟运行得太慢。当我使用80-4的时候,时钟也运行得太慢了。当我用80-5的时候,太快了。
我不知道,怎么可能?
更新:现在的设置如下,但仍然存在问题。
/* Settings */
#define TMR_RELOAD 125 /* 31.25 kHz / 125 = 250 Hz */
#define TMR_CNT_MAX 250 /* 1Hz internal counter */
inline void TMR0_Init()
{
/* set clock source f_t0 = 8МHz/256 = 31.25 kHz */
TCCR0 = _BV(CS02);
TIMSK |= _BV(TOIE0); /* Enable TMR0 interrupt on overflow*/
}
ISR (TIMER0_OVF_vect)
{
TCNT0 -= TMR_RELOAD;
if (tmr_cnt == 0)
Clock_Tick1s();
tmr_cnt++;
if (tmr_cnt >= TMR_CNT_MAX)
tmr_cnt = 0;
}发布于 2014-10-14 08:57:25
注意,当你打电话给
TCNT0 -= TMR_RELOAD;TCNT0寄存器已经是0。因此,您可以得到TCNT0 = 131,它需要124个滴答才能溢出。这意味着你的钟
1/31250 * 250 = 8ms
更快的每秒,结果是
8ms *60x60 x3 = 86.4s
每3小时。这不是您在评论中提到的5分钟,但错误在那里。您的8 8MHz晶体可能会产生一些额外的错误。这取决于晶体质量和你的谐振电路设计的好坏。
我建议您使用Timer2的输出比较中断,而不是使用溢出中断并重新加载TCNT值。
“输出比较寄存器包含一个连续与计数器值(TCNT2)相比较的8位值。匹配可用于生成输出比较中断.”
它更容易处理,你不需要处理“重新加载”计时器。
你也可以考虑使用32.768kHz的时钟晶体。
发布于 2014-10-11 19:11:22
第一个问题很明显,频率为8 8MHz/1024=7812.5 Hz,即使用80没有意义。操作TCNT0也是个问题,因为计数器已经达到零,中断被执行,代码流到达最后指令,所以会有一些延迟。第三个是水晶的频率,你确定那是8兆赫吗?由于不适当的电容负载或仅仅的频移,可能会带来定时误差。
https://stackoverflow.com/questions/26317208
复制相似问题