找回密码
 立即注册
查看: 80|回复: 2

如何正确读取16位定时器值

[复制链接]
  • 打卡等级:初来乍到
  • 打卡总天数:4
  • 最近打卡:2025-08-18 08:27:59
已绑定手机

5

主题

3

回帖

51

积分

注册会员

积分
51
发表于 6 天前 | 显示全部楼层 |阅读模式
定时器有2个BYTE, TxH, TxL。在定时器持续运行时,如何读取正确的值?

其它8位机的方式是读取TxH, TxL会自动保存,然后再读TxL. 但是STC 并没有这样的描述。 意味着我们可能无法读取到正确的值。
回复

使用道具 举报 送花

3

主题

2031

回帖

910

积分

等待验证会员

积分
910
发表于 6 天前 | 显示全部楼层
在使用16位定时器(如STC系列单片机中的定时器)时,正确读取定时器值是确保系统时序准确性的关键。对于具有两个字节(TxH、TxL)的16位定时器,在定时器持续运行过程中,直接读取这两个寄存器可能会导致数据不一致,从而引发读取错误。

一、问题背景

在许多8位微控制器中,为了防止在读取高字节和低字节之间发生计数器变化导致的数据错误,通常采用一种“锁存”机制:即在读取高字节后,系统会自动将当前的计数值锁存到一个临时寄存器中,随后再读取低字节,以确保读取的是同一时刻的完整16位值。这种机制在某些8位MCU中被明确描述。

然而,在STC系列单片机中,并未提供类似的功能描述,这意味着用户在读取16位定时器值时,需要自行处理可能发生的计数器翻转问题。

二、读取方法建议

为确保在定时器持续运行时读取到正确的16位值,可以采取以下几种策略:

1. 双次读取法

该方法通过两次读取定时器的高低字节,并进行比较,以判断是否在读取过程中发生了计数器翻转。具体步骤如下:
先读取低字节(TxL);
再读取高字节(TxH);
再次读取低字节(TxL);
比较两次读取的低字节值,若相同,则说明读取过程未发生翻转,可使用第一次读取的高字节与低字节组合成16位值;
若不同,则说明在读取过程中发生了翻转,应重新读取。

此方法虽然增加了读取次数,但能有效避免因计数器翻转而导致的数据错误。

2. 禁用中断或暂停定时器

如果应用允许在读取期间暂停定时器操作,可以在读取前暂时关闭定时器,待读取完成后重新启动。这种方法适用于对实时性要求不高或可以接受短暂延迟的应用场景。

3. 使用硬件锁存功能(如有)

部分高端MCU提供了硬件锁存功能,可在读取时自动锁存当前的计数值。但在STC系列中,此类功能并未被广泛支持,因此需依赖软件实现。

三、代码示例(C语言)

以下是一个基于双次读取法的示例代码片段,用于读取16位定时器值:

```c
unsigned int ReadTimerValue(void) {
    unsigned char tmpl1, tmpl2;
    unsigned int tmph;

    tmpl1 = TxL;           // 第一次读低字节
    tmph = TxH;            // 读高字节
    tmpl2 = TxL;           // 第二次读低字节

    if (tmpl1 == tmpl2) { // 判断低字节是否一致
        return ((unsigned int)tmph

[本文内容由国芯人工智能辅助生成,仅供参考]
回复

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:537
  • 最近打卡:2025-08-24 01:00:11
已绑定手机

86

主题

5979

回帖

1万

积分

超级版主

积分
10832
发表于 6 天前 | 显示全部楼层
原子操作问题
https://www.stcaimcu.com/thread-11928-1-1.html
不要在持续运行时读值,读值先关闭定时器

定时器中断内使用 unsigned int 变量计数,在主函数内读该变量,这样读值时一定是退出中断的

使用16位高级PWM代替
回复

使用道具 举报 送花

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|手机版|小黑屋|深圳国芯人工智能有限公司 ( 粤ICP备2022108929号-2 )

GMT+8, 2025-8-24 06:42 , Processed in 0.107639 second(s), 62 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

快速回复 返回顶部 返回列表