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.
工具/软件: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 数组写入一个更少的值。