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/MSP430FR2433:使用 SMCLK 的 timerA 的结果不符合预期。

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

https://e2e.ti.com/support/microcontrollers/msp-low-power-microcontrollers-group/msp430/f/msp-low-power-microcontroller-forum/949913/ccs-msp430fr2433-result-of-timera-using-smclk-is-not-as-expected

器件型号:MSP430FR2433

工具/软件:Code Composer Studio

我正在尝试使用 SMCLK 通过 timerA 测量 SPI 从器件的运行时间。

但 timerA 的结果是怪异的。

它的工作频率为400Hz。 我测量了它、但精度非常高。

我只需要200个数据、因此它只需0.5秒即可工作。


SMCLK (=MCLK)为16MHz、输入分频器为8、所以...
预期结果为1M。

16M/8/2=1,000,000

但实际结果是930、000 ~ 950、000。

我没有更改 LPM 模式。
SPI 从器件运行时、使用中断和 SPI 通信。
FLL 被使能。 如果禁用、结果约为77、000。

为什么会发生这种情况?

此代码是我的 timerA 设置。

void init_timerA()

//启动计时器。 用户指南第370页
// TAIE - Timer_A 中断使能。 该位启用 TAIFG 中断请求

// Timer_A 时钟源选择10b = SMCLK
// InputDivider。 0xC0 =/8
// ID。 输入分压器。 00b =/1、11b =/8。
// ID_3 (3*0x40u)// Timer A 输入分频器:3-/8 */
// TASSEL1 = 10b = SMCLK\
// TASSEL0 = 01b = ACLK。

TA0CTL |= TASSEL1 + ID_3 + TAIE;//+ 0xC0;

//CM0 = 0x4000、10b =下降沿上的捕捉
//CCIS_3 (3*0x1000u)/*捕获输入选择:3- Vcc */
//cap (0x0100)//捕获模式:1 /比较模式:0 */
TA0CCTL0 = CM0 + CCIS_3;//

// 1. 向 TACLR 位写入1 (TACLR = 1)来清零 TAxR、时钟分频器状态和计数器方向。
TA0CTL |= TACLR;//+ TAIE;// Timer_A 清零。 将该位置位将复位 TAxR、定时器时钟分频器逻辑(分频器设置保持不变)和计数方向。
// 2. 如有必要、将初始计数器值写入 TAxR。
TA0R = 0;
// 3. 初始化 TAxCCRn。
TA0CCR0 = 50000;
// 16M / 8 (div)/ 400 (Hz)= 5000。
// 4. 对 TAxIV、TAIDEX 和 TAxCCTLn 应用所需的配置。

// 5. 对 TAxCTL 应用所需的配置、包括对 MC 位。
//模式控制
//00b =停止模式:定时器暂停
//01b = MC0 =向上计数模式:定时器向上计数到 TAxCCR0
//10b = MC1 =连续模式:定时器计数到0FFFFh
//11b =向上/向下计数模式:定时器向上计数至 TAxCCR0、然后向下计数至0000h

TA0CTL |= MC0;

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

    我将主时钟更改为4MHz 并重试。

    结果是205、000。

    它没有发生太大变化。

    和。

    我在测量时间之前添加了此代码。

    while (WDTcount < 10){
    WDTcount++;
    MCU_lpm_enter (4);

     。 + init_timerA ();+测量时间。

    结果是291、400。

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

    为什么选择 CCIS_3? 否设置 CAP=1?  

    SPI 信号频率是多少? 即、您使用 SMCLK 2MHz 测量的周期是多少?  

    是否启用中断以读出计时器计数值? 如果没有、如何保证立即读取计时器数据? 您是否已经捕获了很多次、并使用2个相邻的捕捉定时器值计算时钟计数?  

    谢谢、  

    Lixin  

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

    您好、Lixin、

    1、CCIS、CAP。 没有具体原因。
    已0~2 CCIS Δ I 和 CAP、但结果未更改。

    2. SPI 信号频率
    UCB0CTLW0 |= UCSSEL_SMCLK;// SMCLK
    UCB0BR0 = 0x10;

    使用 SMCLK 2MHz 测量的周期是多少?
    我想测量以400Hz 频率运行的器件运行200次的时间。
    500ms 是完美的、497.5 ~ 502.5ms 是安全的。 否则表明出现了问题、需要重新启动。

    2MHz?
    由于其他原因、我不得不降低时钟以降低功耗。


    4.是否启用中断以读出计时器计数值?

    我使用类似这样的中断。
    定时器计数达到50000、它返回0并产生溢出中断。

    #pragma vector=TIMER0_A1_vector
    _interrupt void TIMER0_A1_ISR (void){
    int _= TA0IV;
    TimerAmount ++;

    如果 TimerAcount = 5、ticksave = 40000、
    结果为29、000。

    5.您是否已经捕获了很多次并使用2个相邻的捕获定时器值计算时钟计数?

    仅捕获2次。 前后。 这是我的代码。

    tickstart = TA0R;
    startOF = TimerAcount;
    while (savednum < 200){//获取200次。 中断。 在0.5秒内
    
    if (readflag){// LIS 中断
    readflag = false;
    LIS_GET_xyz_saveto (savednum);
    
    savednum++;
    }
    }
    
    end_timerA ();// TA0CTL = 0;
    ticksave = TA0R;
    endof = TimerAmount; 

    如果禁用 FLL、结果约为206、000
    如果启用 FLL、则重用大约291000。


    谢谢、

    :KH

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

    FLL 可确保您的 DCO (SMCLK)以您认为的速度运行。 关闭它通常不有用。 如果必须将其关闭、至少要先等待锁定;理论上、这可能需要大约0.5秒。

    未经请求:按此方式进行定时容易受到翻转干扰的影响。 考虑使用 TA0EX0 (或可能是 ACLK)进一步降低定时器的速度、这样定时器在您的计时期间不会(正常情况下)发生回绕。

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


    感谢您的建议。

    我更改了设置并重试。

    MCLK、SMCLK = 4MHz、输入分频器= 64、运行时间= 0.5秒。
    预期理想节拍= 31、250 +- 156.25


    这次我保存了每次传输的节拍数。

    [0]无符号 short 100 0x0024B0
    [1]无符号短整型230 0x0024B2
    [2]无符号短整型360 0x0024B4
    [3]无符号短整型490 0x0024B6
    [4]无符号短整型621 0x0024B8

    (笑声)

    [98]无符号短整型15137 0x002574
    [99]无符号短整型15322 0x002576
    [100]无符号短整型15507 0x002578
    [101]无符号短整型15693 0x00257A

    前半部分测量结果不好。
    15693 * 64 = 1、004、352。

    [155]无符号短整型26876 0x0025E6
    [156]无符号短整型27092 0x0025E8
    [157]无符号短整型27309 0x0025EA
    [158]无符号短整型27525 0x0025EC

    [197]无符号短整型35971 0x00263A
    [198]无符号短整型36188 0x00263C
    [199]无符号短整型36405 0x00263E

    但在后半部分、上升增加、结果完全错误。

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

    1) 1)也许您可以解释我们所看到的内容。 哪些数字"完全错误"、您如何辨别?

    2) 2)您如何进行测量? 您是每次清除计时器、还是捕获开始+停止并减去? 当我执行此操作时、我通常会让连续模式计时器保持运行并捕获开始+停止、因为这使得算术变得简单。

    3) 3)您的具体时间是什么? 您之前发布的片段主要由条件(if))决定,因此它在不同条件下的行为似乎有所不同。

    4) 4)开始试用之前、您是否等待 FLL 锁定? 您可以在该范围内执行其他操作、但在开始测量时确实需要锁定 FLL (一致的时钟)。

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


    您好、Bruce、

    1.很抱歉,我是说。 结果(36000)不是我所期望的结果(31250)。


    2.检查2次。 前后。

    启动 timerA、
    检查计时器、
    我想知道的有关运行时间的信息、
    停止计时器(可能无用?)、
    检查计时器。

    3.操作和捕获

    P1OUT &=!BIT4; 
    tickstart = TA0R; startOF = TimerAcount; while (savednum < 200){//获取200次。 中断。 在0.5秒内 if (readflag){// LIS readflag 的中断= false; P1OUT |= BIT5;//切换引脚1.5 lis_get_xyz_saveto (savednum); P1OUT &=!BIT4;//切换引脚1.5 tickarr[savednum]= TA0R; savednum++; } end_timerr = tickr; }= tickr;timercount (timerr = tickr;}= tickr = tickr;}= tickr = tickr;timerr =


    我使用 GPIO (使用示波器)进行了测试、并确认操作正常。

    4、我现在没有触摸 FLL、等待1.25秒。
    我应该等待多长时间?

    这是程序流程。

    初始化 MSP430FR2433。
    更改 init MSP 和其他器件的配置。
    初始化看门狗定时器。

    while (WDTcount < 5){
    WDTcount++;
    MCU_lpm_enter (4);

    等待1.25秒。

    初始化 timerA。

    测量时间。

    (笑声)

    我尝试在等待序列之前移动 init_timerA、但结果没有不同。

    谢谢。

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

    1) 1)好的、所以第二个数字是 tickr[]的内容、并且由于您不是每次清除 TA0R、所以它会单调增加。 (我并不一定建议清除计时器、我只是在描述。)

    那么、有趣的是连续线之间的差值。 这确实在逐步增加,从第一组中的大约130个增加到最后一组中的217个。

    3) 3)您要测量的内容主要由 if ()决定、我怀疑该 if ()会检查 ISR 中的变量集。 请记住、(a) ISR 速率可能与代码不协调、因此您要测量 ISR 之间的旋转、(b)您还需要测量 ISR 的成本。

    具体而言(a):如果 ISR 周期比代码稍长、它将向前漂移、并且由于额外的旋转、测量值将逐渐增加。 我建议您将开始/停止捕捉放在 if()内。

    4)通常、FLL 应在不到0.5秒的时间内锁定(使用 REFO、我希望您是这样)。 您是否相当确定该环路真正等待1.25秒?

    如果您想确定、可以插入:

    > while (CSCTL7 &(FLLUNLOCK0 | FLLUNLOCK1));//轮询直到 FLL 锁定

    [从示例 msp430fr243x_CS_07.c 中删除、此处:

    https://dev.ti.com/tirex/explore/node?node=AJXSKLubovap2pQl1MpHeA__IOGqZri__LATEST

    ]

    未经请求:

    P1OUT &= !BIT5; // toggle pin 1.5

    这相当于"P1OUT = 0;"。 我怀疑您想要:

    P1OUT &= ~BIT5; // toggle pin 1.5

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

    您好、Bruce、

    ISR 是否是问题的原因? 但是。 此程序不能在没有中断的情况下运行。

    从器件接收就绪信号是中断、SPI 事务使用中断。


    将开始/停止捕捉放置在 if()内?
    我无法理解。

    if (readflag){
    继续执行 timerA
    P1OUT 引脚1.5 =高电平
    执行 SPI 操作
    P1OUT 引脚1.5 =低电平
    挂起时间 A

    此代码只能测量脉冲为高电平时的时间。 并不是一整天。

    FLL 可能有一个大问题。

    void init_clocks ()
    {
    //根据器件数据表的要求为 MCLK 配置一个 FRAM 等待状态
    //在8MHz 之前运行配置时钟系统。
    FRCTL0 = FRCTLPW | NWAITS_1;
    
    _ bis_SR_register (SCG0);//禁用 FLL
    
    CSCTL3 |= SELREF_REFOLCLK;//将 REFO 设置为 FLL 基准源
    CSCTL0 = 0;//清除 DCO 和寄存
    器 CSCTL1 &=~(DCOSEL); //清除 DCO 频率选择位优先
    
    // DCORSEL_3 = 0x011 -> 8MHz
    // DCORSEL_0 = 0x000 -> 1MHz
    // DCORSEL_1 = 0x001 -> 2MHz
    // DCORSEL_2 = 0x010 -> 4Mhz
    // DCORSEL_5 = 0x101 -> 16MHz。 默认值。
    CSCTL1 |= DCORSEL_2;//设置 DCO
    CSCTL2 = FLLD_0 + 487;// DCOCLKDIV = DCO
    _ DELAY_CYCLLES (3);
    __BIC_SR_register (SCG0);//启用 FLL
    
    while (CSCTL7 &(FLLUNLOCK0 | FLLUNSCLMCL_);//直到锁定 FLLCSCL_ DCLK4);// DCLLMCL_ DLL_轮询= FLL_CLK4
    
    ;//直到 CLOCLKLMS_CLLMS_LMS_被锁定 //将默认 REFO (~32768Hz)设置为 ACLK 源,ACLK = 32768Hz
    //默认 DCOCLKDIV 设置为 MCLK 和 SMCLK 源
    CSCTL6 &=~(XT1AUTOOFF);
    
    } 

    在该代码中、在这里进行了调试。 'while (CSCTL7 &(FLLUNLOCK0 | FLLUNLOCK1));'。


    我发表意见  

    CSCTL1 &= ~(DCORSEL_7); // Clear DCO frequency select bits first

    并尝试将 CSCTL1更改为

    CSCTL1 = DCOFTRIMEN | DCOFTRIM0 | DCOFTRIM1 | DCORSEL_0、2、3;

    但仍在实现 while ()。


    我是否应该发布有关此问题的新问题?


    非常感谢。

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

    3) 3)如果您的目标是捕获 ISR 的时间、则应执行此操作。 但请记住、您正在测量之间的空闲时间、这两个时间(这些事件是异步的)可能会有所不同。

    4) 4)简短回答:尝试 DCORSEL=5。 复位值为=1。 [参考用户指南(SLAU445I)表3-5和数据表(SLASE59D)表5-6 ]

    稍长:"487"指定绝对速度(487*32768Hz=~16MHz)。 如果该速度不在 RSEL 范围内、FLL 将把 CSCTL0:DCO 推至其范围的一端或另一端并保持在该端(饱和)、无法锁定。

    我希望这种情况下的结果是恒定(虽然不正确) DCO 速度、这本身不会解释逐渐的计时漂移。

    如果您尚未查看示例 msp430fr243x_CS_03.c、请点击此处:

    https://dev.ti.com/tirex/explore/node?node=AHMHa7q.qkFTrXXRnRPsug__IOGqZri__LATEST

    您可能只需复制/粘贴相关部分。 (这是我通常所做的。)

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

    您好、Bruce、

    当 MCLK 为4MHz 时、
    CSCTL2 = FLLD_0 + 122;
    此代码运行良好! 谢谢你。


    我以前不了解 FLLN。


    通过这种出色的 FLLN、TimerA 变得更加精确。 但它似乎还不完美。

    我使用4个不同的电路板进行了测量。

    结果:
    1.31038、31153、31074、31112、31079
    2.31737、31745、31772、31748
    3. 31926、31955、31958、31933
    4. 31248、31252、31243、31246

    最佳结果是31250 +- 156。

    1号有点小、2、3号太大。


    谢谢。