This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

[参考译文] CCS/MSP-EXP430FR5969:尝试学习计时器和时钟系统、溢出 ISR 计数器在以预期速率迭代之前跳转到高值

Guru**** 2024750 points
Other Parts Discussed in Thread: MSP430FR5969
请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/microcontrollers/msp-low-power-microcontrollers-group/msp430/f/msp-low-power-microcontroller-forum/567429/ccs-msp-exp430fr5969-trying-to-learn-the-timers-and-clock-system-overflow-isr-counter-jumps-to-high-value-before-iterating-at-expected-rate

器件型号:MSP-EXP430FR5969
主题中讨论的其他器件:MSP430FR5969

工具/软件:Code Composer Studio

我正在尝试学习 MSP430FR5969上的时钟系统和计时器、并遇到了一个有趣的问题。 我使用32kHz 晶体振荡器来驱动 ACLK、进而从 ACLK 获取计时器 A0和 B0。 我的目标是从系统以较长的 int 启动以来简单地捕获32kHz 时钟(请参阅下面的代码)。 我遇到的困难是、我用于计算溢出的变量在其第一个++上跳转到3332、然后开始计数通常以每2秒1次的速度上升。 我已经尝试在连续模式下使用溢出中断、在向上计数模式下使用比较中断。 后者为以下代码。 我还延迟了一段时间、看看是否存在某种振荡器趋稳问题、但这没有影响。 此外、为了进行诊断、我在溢出计数器变量处放置了一个代码中断、以便在第一次调用它时捕获它。 在第一个呼叫中、它会跳至3332、然后在每个连续呼叫上按预期上升+1。 有什么想法吗?

#include  

#include

unsigned long int volatile timerBOverflow = 0;
unsigned char volatile timerAComp = 0;
unsigned int volatile compTime[100]={0};
unsigned long int volatile systime = 0;

int main (void){

WDTCTL = WDTPW | WDTHOLD;//停止看门狗计时器

PJSEL0 = BIT4 | BIT5;//对于 LFXT

FRCTL0_H = 0xA5;// FRAM 控制器密码
FRCTL0_L = 0x10;//针对 FRAM 访问限制将等待状态设置为1 (最大8MHz)
FRCTL0_H = 0xA6;//禁用 FRAM 控制器寄存器写入访问
CSCTL0_H = 0xA5;//时钟系统密码
CSCTL1 = DCORSEL | DCOFSEL_4;//将 DCO 设置为16MHz
CSCTL2 = SELA_LFXTCLK | SELESS__DCOCLK | SELM_DCOCLK;//设置系统时钟源
CSCTL3 = DIVA__1 | DIVM_1 | DIVM__1;//将 A/M/SMclk 设置为 src/1
CSCTL4 = HFXTOFF | VLOOFF | LFXTDRIVE_1;//将 LFXT 设置为外部晶体振荡器、关闭 VLO 并硬驱动 LFXT
执行{
CSCTL5 = 0;//终止 LFXT 故障标志
SFRIFG1 &=~OFIFG;
} while (SFRIFG1&OFIFG);
CSCTL0_H = 0xA6;//禁用时钟系统寄存器写入访问

_bis_SR_register (GIE);

TB0CTL = TBSSEL_ACLK | TBCLR;//将 Timer-B 设置为从 Aclk 源、启用中断并开始计数
TB0CCR0 = 0xFFFF;//比较溢出值(65535)
TA0CTL = tassel__ACLK | TACLR;//为上数设置 Timer-A 到 TA0CCR0、设置 BIT4以使用 Aclk 激活1ms 计时器操作
TA0CCR0 = 0x0020;//将 Timer-A 比较值设置为32、在32kHz 时为1ms
TA0CCTL0 = CCIE;//为 CCR0启用比较中断
TB0CCTL0 = CCIE;//为 CCR0启用比较中断

TB0CTL |= MC__UP;//启动计数
TA0CTL |= MC__UP;//启动计数

//禁用 GPIO 上电默认高阻抗模式以激活
//先前配置的端口设置
PM5CTL0 &=~LOCKLPM5;
while (1){
systime = TB0R + timerBOverflow*0x0000FFFF;//软件计时器


// Timer_B7中断向量(TBIV)处理程序
#if defined (__TI_Compiler_version__)|| Defined (__IAR_systems_ICC__)
#pragma vector=TIMERB0_vector
_interrupt
#Elif defined (_GNU_)
__attribute__((interrupt (TIMERB0_vector))
#endif
空 TIMERB0_ISR (空)

timerBOverflow++;

// Timer0_A0中断服务例程
#if defined (__TI_Compiler_version__)|| Defined (__IAR_systems_ICC__)
#pragma vector = TIMER0_A0_vector
_interrupt void Timer0_A0_ISR (void)
#Elif defined (_GNU_)
void __attribute__((中断(TIMER0_A0_Vector)) Timer0_A0_ISR (void)
其他
错误编译器不受支持!
#endif

if (timerAComp<101)

compTime[timerAComp]= TB0R;
timerAComp++;

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    [引用 user="Bret Bronner">我遇到的困难是、我用来计算溢出的变量在其第一个++上跳到3332、然后开始计数通常以每2秒1次的速度上升。 我可以重复一下、使用 CCS 6.1.3和 TI v16.9.0.LTS 编译器编译您的示例。

    启动调试会话后、程序在 main 处停止、为写入 timerBOverflow 变量设置一个"观察点(读取或写入)":

    下面显示了首次写入 timerBOverflow 时的观察点被触发的情况:

    问题是 compTime 数组的大小为100、即索引为0到99、但 Timer0_A0_ISR 已写入 compTime 索引100、该索引不在 compTime 数组末尾、因此会覆盖 compTime 数组后立即存储器中的 timerBOverflow 变量。 此外、在覆盖 TB0R 的点、TB0R 包含值3332、这是写入 timerBOverflow 的错误值。

    因此、 需要更改 Timer0_A0_ISR 以向 COMPTime 数组写入一个更少的值。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    切斯特、谢谢! 出色的分析和验证。 感谢您的帮助。 程序工作和代码已应用到更大的项目中。

    此致