主题中讨论的其他器件:MSP-EXP430FR5739
您好!
我正在尝试在 TB1上执行计时器捕获。 该计时器脱离 SMCLK (24MHz DCOCLK)运行、应与 CPU 同步。 我正在使用异步外部信号从 P2.2上的 CCI0A 在 CCR0上进行捕获。 外部信号可以非常快、大约为50kHz 甚至更高。
我一直在研究 SCS 同步模式及其使用时间/方式。 (请参阅 此 和 此。) 在我的情况下、由于定时器使用的时钟源与 CPU 相同、我可以直接在软件中读取 TB1R、而无需执行任何技巧(例如软件触发的捕获或连续读取 TB1R)。 对于我的 CCR0外部捕捉、在 TB1R (可能)正在转换时、我应该使用 SCS 来避免异步捕捉。 因此、我的计时器配置如下:
TB1CTL = TBSSEL_2 | MC_2; //使用 SMCLK、连续模式 TB1CCTL0 = CM_3 | CCIS_0 | SCS | CAP;//双边沿、CCI0A、同步、捕捉模式
实际上、我在任何时候读取 TB1R 都没有遇到任何问题。 但是、如果我在 不考虑 CCIFG 的情况下以紧密循环读取 TB1CCR0、我有时会遇到数据损坏。 以下代码将在大约10、000 - 200、000次迭代后失败:
void wait_for_halt (void){ uint16_t timer_current、timer_captured、timer_delta; 执行{ Timer_captured = TB1CCR0; Timer_current = TB1R; Timer_delta = timer_current - timer_captured; } while (timer_delta < 300); }
但这始终通过测试 CCIFG 来实现:
void wait_for_halt (void){ uint16_t timer_current、timer_captured、timer_delta、timer_flag; 执行{ TB1CCTL0 &=~(CCIFG | COV); Timer_captured = TB1CCR0; //此读取操作不会清除 CCIFG Timer_flag = TB1CCTL0和 CCIFG;//如果 CCIFG 在读取期间出现、Timer_captured 无效 Timer_current = TB1R; Timer_delta = timer_current - timer_captured; } while (timer_flag!= 0 || timer_delta < 300); }
这通过读取寄存器两次来工作:
void wait_for_halt (void){ uint16_t timer_current、timer_captured、timer_redundant、timer_delta; 执行{ Timer_captured = TB1CCR0; Timer_redundant = TB1CCR0; Timer_current = TB1R; Timer_delta = timer_current - timer_captured; } while (timer_captured!= timer_redundant || timer_delta < 300); }
我的问题是:为什么我需要这样做? 我假设这些寄存器中没有任何一个是缓冲的。 这将解释为什么如果使用外部时钟来驱动定时器、那么您需要向后弯曲来读取 TB1R。 但是、为什么 我会对 TB1CCR0产生这个问题、尤其是在 SCS 同步模式被启用的情况下? 我想这会导致寄存器与计时器和 CPU 同步更新;这意味着我可以随时读取它。 或者同步是否会导致寄存器在我的读取发生的那一刻更新?
我已尝试禁用 SCS。 正如预期的那样、这会定期失败、以上实施均无帮助。
请注意、我了解可以通过简单地观察输入转换并在软件中跟踪时间来实现此示例。 但我需要能够在进入函数时立即检测到缺少信号。