youright 发表于 2022-2-22 11:47:09

STC单片机,如何确保同时准确读取计数器CL,CH的值?

本帖最后由 youright 于 2022-2-22 11:49 编辑

在一些需要精确定时,或PWM输出时,需要准确读取计数器CH,CL的值,再做计算处理,例如:
j=(CH<<8)+CL+10;

问题来了,(CH<<8)运算器件,CL的值可能发生了变化,进位了,如CL=255,则CH也发生了变化。

即使采用i=CL;j=CH;也有可能2次取值过程中,CH,CL发生变化。

运算速度再快,只要有时间差,这种取值变化的几率同样存在,只是速度越快,几率越小而已。

如何解决?

wye11083 发表于 2022-2-22 12:12:19

要么读2次判相同,要么关中断再读呗。

modbus 发表于 2022-2-22 13:17:31

先读高,再读低,再读高并和上次读高判断,相同则正确,不相同重来

t3486784401 发表于 2022-2-22 14:23:07

AVR 硬件带有16bit 同步缓冲,就是解决这个问题。

从这个角度看,软件无最优解。要么关定时器,要么多读几次自己判断(同样有失败几率),还可以召唤老妖给你加缓冲

youright 发表于 2022-2-22 16:10:44

t3486784401 发表于 2022-2-22 14:23
AVR 硬件带有16bit 同步缓冲,就是解决这个问题。

从这个角度看,软件无最优解。要么关定时器,要么多读几 ...
(引用自4楼)

是的,表达很准确。

即使读2次,做二次判断,同样有这种几率。
能否间接利用PCA的捕获功能,去抓取CH、CL的值?

t3486784401 发表于 2022-2-22 16:30:37

都用 PCA 模块了,那从最开始的需求上就应该绕开“读取 TH:TL 产生 PWM”这样的想法。
直接用硬件 PWM 发波应该更合适。当然对于软 PWM 需求来说依旧不够灵活。

51 的结构就不适合频繁访问 TH:TL 变量,非要访问的话,我选择先读 TL

redroof 发表于 2022-2-22 16:31:45

t3486784401 发表于 2022-2-22 14:23
AVR 硬件带有16bit 同步缓冲,就是解决这个问题。

从这个角度看,软件无最优解。要么关定时器,要么多读几 ...
(引用自4楼)

没什么大问题啊,20年前的51的书里面就已经有了正确的做法,就是上面说过的,先读高,再读低,再读高。
如果两次高字节不一样就是你碰到了进位的时刻, 重读一次肯定可以。因为只有低位记满了才向高位进位一次,你只有恰好这个时候读才可能读到不一致,那么重读一次就不可能再碰上进位的时刻了。
除非你第二次读的时候又被一个中断打断,中断耽误了一些时间导致又到下一个进位的时间了,那就继续重读呗~
程序写个死循环必须读到两次高字节一致才返回就行。你知道大于99%概率它只会执行一次就是了。小概率执行两次也不碍什么事

youright 发表于 2022-2-22 16:43:35

modbus 发表于 2022-2-22 13:17
先读高,再读低,再读高并和上次读高判断,相同则正确,不相同重来
(引用自3楼)

非常好,逻辑合理。
这个方法,最大的误差可以控制在CL+1,避免了CH的变化,CH的变化是致命的。

兄弟来广州,请你吃饭哦!

youright 发表于 2022-2-22 16:48:35

redroof 发表于 2022-2-22 16:31
没什么大问题啊,20年前的51的书里面就已经有了正确的做法,就是上面说过的,先读高,再读低,再读高。
...
(引用自7楼)

是的,还是我基本功不扎实

多一次比较就可以了,这样的做法,最大误差可以控制在CL+1

redroof 发表于 2022-2-22 16:54:06

youright 发表于 2022-2-22 16:48
是的,还是我基本功不扎实

多一次比较就可以了,这样的做法,最大误差可以控制在CL+1
(引用自9楼)

那不算误差。
其实在进位的那个时刻附近,你不管读到旧值还是新值都无所谓的,都应该可以接受,误差不到计数器的一个时钟周期。你有32位的数据总线可以直接读也好不到哪里,最大误差还是一样。
只要不是半旧半新就行,半旧半新就错了,误差是256个计数器时钟周期。

youright 发表于 2022-2-22 16:57:43

redroof 发表于 2022-2-22 16:54
那不算误差。
其实在进位的那个时刻附近,你不管读到旧值还是新值都无所谓的,都应该可以接受,误差不到 ...
(引用自10楼)

是的,非常清楚了,感谢大家的讲解。

页: [1]
查看完整版本: STC单片机,如何确保同时准确读取计数器CL,CH的值?