8位机使用软件定时器模块出现的错误

工作笔记
Article Directory
  1. 1.问题场景
  2. 2.解决办法

1.问题场景

使用软件定时器模块

https://github.com/czc13611858691/code_module/tree/main/soft_timer

8位单片机AVR64DA32

解决问题参考文章

https://www.cxyzjd.com/article/weixin_42952614/109251285

问题描述

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
/* 单片机定时器中断 */
timer_isr()
{
g_soft_timer_ticks++;
}

/*其他地方调用*/
g_lin_4s_ticks_last=g_soft_timer_ticks;

main()
{
while(1)
{
g_lin_4s_ticks=g_soft_timer_ticks;
uint16_t delta = (uint16_t)(g_lin_4s_ticks - g_lin_4s_ticks_last);
if (delta >= 4000)
{
// 时间到达位置
}
}
}

理论上g_lin_4s_ticks_last一直更新的话,程序不应该到达(时间到达位置)注释位置

但是出现偶然情况

g_lin_4s_ticks=0x6100;

g_lin_4s_ticks_last=0x61ff;

值不一定,但是g_lin_4s_ticks最后两位总是00,g_lin_4s_ticks_last最后两位总是ff

2.解决办法

按照 解决问题参考文章 所述

  • 8位单片机一次只能处理一个8位数据
  • g_soft_timer_ticks–>0x60ff
  • g_lin_4s_ticks_last取g_soft_timer_ticks低字节ff,之后触发中断
  • g_soft_timer_ticks++ –> 0x6100,退出中断
  • g_lin_4s_ticks_last取g_soft_timer_ticks高字节61,
  • g_lin_4s_ticks_last –> 0x61ff
  • 然后他们之间的差值就成负数了,转化为无符号数之后远远大于4000

办法

1
if (delta >= 4000)

改为–>

1
if ((delta >= 4000) && (delta < 60000))