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.

[参考译文] MSP430FR2155:MSP430FR2155

Guru**** 2511985 points


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

https://e2e.ti.com/support/microcontrollers/msp-low-power-microcontrollers-group/msp430/f/msp-low-power-microcontroller-forum/1121289/msp430fr2155-msp430fr2155

器件型号:MSP430FR2155

你(们)好  

我有另一个关于计时器的问题。

我将 CCR0设置为239、但计时器似乎会启动 223个时钟周期、有些时钟周期会启动240个时钟周期。

我如何才能在每次计时器启动时都保持一致的时钟周期。

(我还确保没有其他服务例程中断计时器)

谢谢

#if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
#pragma vector = TIMER0_B0_VECTOR
__interrupt void TIMER0_B0_ISR(void)
#elif defined(__GNUC__)
void __attribute__ ((interrupt(USCI_B0_VECTOR))) TIMER0_B0_ISR (void)
#else
#error Compiler not supported!
#endif
{

    delta[count] = RTCCNT - pre_rtc;
    pre_rtc = RTCCNT;
    count++;

    if (count>=120)
    {
           HWREG16(TIMER_B0_BASE + OFS_TBxCTL) &=  ~MC;
           // process data



           HWREG16(TIMER_B0_BASE + OFS_TBxCTL) |=  MC__UP;


    }
}

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

    您好、

    那么、您似乎在按照设置 TimerB0的时间间隔读取 RTC 计数器-正确吗?

    您能否提供 RTC 和 TimerB0的设置代码?

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

    尊敬的 Dennis:

    是的,它是 TimerB0和 RTC。

    void RTCInit()
    {
        HWREG16(RTC_BASE + OFS_RTCCTL) &= ~(RTCSS_3 | RTCPS_7);
        HWREG16(RTC_BASE + OFS_RTCMOD) = 32767;
        RTC_start(RTC_BASE,  RTCSS_1);
    }
    
    void InitTimer()
    {
        HWREG16(TIMER_B0_BASE + OFS_TBxCTL) = TBSSEL__SMCLK;
        HWREG16(TIMER_B0_BASE + OFS_TBxCCR0) = 239;
        HWREG16(TIMER_B0_BASE + OFS_TBxCCTL0) |= CCIE
    
        HWREG16(TIMER_B0_BASE + OFS_TBxCTL) |=  MC__UP; 
    }
    
    

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

    您好、

    好的、看起来不错、但我忘记问什么是 SMCLK 频率?

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

    尊敬的 Dennis:

    SMCLK 为24MHz

    谢谢

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

    您好、

    好的、那么您使用以24MHz 运行的 SMCLK 为 RTC 和 TimerB 计时-到目前为止是正确的吗?

    您没有提到 CPU 的运行速度、因此我假设采用相同的24MHz、在这种情况下、FRAM 等待状态是否为2?

    下面是一些尝试帮助缩小问题范围的实验。

    1.将代码从 delt[count]= RTCCNT - pre-RTC 更改为 delt[count]= RTCCNT - 239。  你看到什么?

    2.保持 CPU 运行在24MHz、但将 SMCLK 分频至4MHz。  你看到什么?

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

    尊敬的 Dennis:

    是的、FRAM 被设定 为 NWAITS_2。

    1>我更改为  deltation[count]= RTCCNT - 240

       在大多数时间内,增量更改为 F0。

       将结果附在以下位置。

       这也是一个问题、只要指令不超过240个时钟周期、无论在两个定时器启动之间写入任何代码、结果都应该为240。  为什么 它只是通过更改一行代码就像这样工作?  (实际上、我确实看到过类似的情况、这是最简单的例子)

       

    2>4MHz 对我们来说并不是一个真正的选择、但是 、如果确实有必要、我可以稍后再试、看看结果。

    谢谢

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

    您好、

    让我来看看这个。

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

    您好、

    好的、这里有一些不正确的地方。  我返回并再次查看您的 RTC 初始化。 根据您的初始化代码、您将清除 RTCSS 位、该位选择"无时钟"。  您打算将什么时钟源用于 RTC?  

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

    尊敬的 Dennis:

    它对 RTC 使用 smclk。

    它是 RTC_START()的库调用 ,用于设置时钟源

    我在此附上代码。

    谢谢

    void RTC_start(uint16_t baseAddress,
                   uint16_t clockSource)
    {
        HWREG16(baseAddress + OFS_RTCCTL) &= ~RTCSS_3;
    
    #ifdef RTCCKSEL
        HWREG16(SYS_BASE + OFS_SYSCFG2) &= ~RTCCKSEL;
        if(clockSource == RTC_CLOCKSOURCE_ACLK)
        {
            HWREG16(SYS_BASE + OFS_SYSCFG2) |= RTCCKSEL;
            HWREG16(baseAddress + OFS_RTCCTL) |= RTCSS_1;
        }
        else
        {
            HWREG16(baseAddress + OFS_RTCCTL) |= clockSource;
        }
    #else
        HWREG16(baseAddress + OFS_RTCCTL) |= clockSource;
    #endif
    
        HWREG16(baseAddress + OFS_RTCCTL) |= RTCSR;
    }
    

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

    感谢 ming 对此进行了澄清。

    那么、您以24MHz 运行 RTC、TimerB 和 CPU、对吧?  这意味着对于每个 SMCLK、RTC 和 TimerB 都将提前一个计数。 那么、在理论上、当 TimerB 计数首次匹配 CCR0时、RTCCNT 将等于 TimerB 计数、对吧?

    然后 TimerB 生成一个中断并将计数复位为0。 与此同时、CPU 检测中断、入栈指针并执行几条指令来读取 RTCCNT 寄存器。  但是、从中断的那一刻起、直到 CPU 读取 RTCCNT 寄存器、SMCLK 继续增加 RTC 和 TimerB 计数。 因此、如果 CPU 花费20个时钟周期(作为一个示例)来执行导致读取 RTCCNT 寄存器的代码、RTCCNT 和 TimerB 将从中断发生时开始计数+20。  这意味着您不仅可以从 RTCCNT 中减去239、还需要考虑 CPU 时间、在本例中为 RTCCNT - 239 - 20。

    我能否询问尝试使用 TimerB 读取 RTCCNT 的目的?

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

    尊敬的 Dennis:

    与我的理解只有一个不同之处。 只要指令小于240个周期、两次启动之间的定时器间隔应为240个周期。  

    电路板是从端口1接口读取/写入数据。   

    当计时器可以启动固定间隔240时、它会起作用。  

    我们从 TI 获得的参考板没有用于该流量的控制器。  

    谢谢

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

    您好、

    很遗憾、我前面没有 FR2155可用于编程和尝试代码、但您可以尝试快速实验吗?

    在 ISR 中、修改代码以读取 TimerB 计数寄存器(TB0R)、并将这些值写入数组、然后向我展示您捕获的内容、而不是读取 RTCCNT 值并写入数组。

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

    尊敬的 Dennis:

    我用两种不同的情况进行测试。 一个具有 RTC 累积样式、另一个具有 RTC 增量样式编码。 请参考图像、并相应地显示两个结果。

    第一种情况是 TB0R 计数器0x21、第二种情况是 TB0R 计数器值0x38。

    第一种情况是 RTC 计数器240 、第二种情况是 RTC 计数器220。

    指令未超过240个时钟周期、但 RTC 计数器应相同、对吧?

    但是 、它具有 不同的 RTC 值、我们希望了解如何解决此问题。

    谢谢

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

    您好、

    好的、TB0R 相当一致、这正是我所期望的。 我不确定 RTC 计数为何没有意义。  明天我将可以访问 FR2155、并运行您的代码以查看是否可以复制。

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

    您好、

    我使用您的原始代码设置了我的项目、它看起来工作正常。  每次在 ISR 中、我都会得到223的增量。

    我已附上源代码供您尝试。  请注意、我必须使用具有相同外设的同一系列中的 FR2355。

    #include <msp430.h>
    #include "driverlib/MSP430FR2xx_4xx/inc/hw_memmap.h"
    #include "stdint.h"
    
    
    #define RTC_CLOCKSOURCE_SMCLK       RTCSS__SMCLK
    #define RTC_CLOCKSOURCE_ACLK        RTCSS__XT1CLK
    
    void RTC_start(uint16_t, uint16_t);
    
    void RTCInit()
    {
        HWREG16(RTC_BASE + OFS_RTCCTL) &= ~(RTCSS_3 | RTCPS_7);
        HWREG16(RTC_BASE + OFS_RTCMOD) = 32767;
        RTC_start(RTC_BASE,  RTCSS_1);
    }
    
    void InitTimer()
    {
        HWREG16(TIMER_B0_BASE + OFS_TBxCTL) = TBSSEL__SMCLK;
        HWREG16(TIMER_B0_BASE + OFS_TBxCCR0) = 239;
        HWREG16(TIMER_B0_BASE + OFS_TBxCCTL0) |= CCIE;
    
        HWREG16(TIMER_B0_BASE + OFS_TBxCTL) |=  MC__UP;
    }
    
    void RTC_start(uint16_t baseAddress, uint16_t clockSource)
    {
        HWREG16(baseAddress + OFS_RTCCTL) &= ~RTCSS_3;
    
    #ifdef RTCCKSEL
        HWREG16(SYS_BASE + OFS_SYSCFG2) &= ~RTCCKSEL;
    
        if(clockSource == RTC_CLOCKSOURCE_ACLK)
        {
            HWREG16(SYS_BASE + OFS_SYSCFG2) |= RTCCKSEL;
            HWREG16(baseAddress + OFS_RTCCTL) |= RTCSS_1;
        }
        else
        {
            HWREG16(baseAddress + OFS_RTCCTL) |= clockSource;
        }
    #else
        HWREG16(baseAddress + OFS_RTCCTL) |= clockSource;
    #endif
    
        HWREG16(baseAddress + OFS_RTCCTL) |= RTCSR;
    }
    
    int main(void)
    {
        WDTCTL = WDTPW | WDTHOLD;                    // Stop watchdog timer
    
        // Configure two FRAM waitstate as required by the device datasheet for MCLK
        // operation at 24MHz(beyond 8MHz) _before_ configuring the clock system.
        FRCTL0 = FRCTLPW | NWAITS_2 ;
    
        P2SEL1 |= BIT6 | BIT7;                       // P2.6~P2.7: crystal pins
        do
        {
            CSCTL7 &= ~(XT1OFFG | DCOFFG);           // Clear XT1 and DCO fault flag
            SFRIFG1 &= ~OFIFG;
        } while (SFRIFG1 & OFIFG);                   // Test oscillator fault flag
    
        __bis_SR_register(SCG0);                     // disable FLL
        CSCTL3 |= SELREF__XT1CLK;                    // Set XT1 as FLL reference source
        CSCTL0 = 0;                                  // clear DCO and MOD registers
        CSCTL1 |= DCORSEL_7;                         // Set DCO = 24MHz
        CSCTL2 = FLLD_0 + 731;                       // DCOCLKDIV = 24MHz
        __delay_cycles(3);
        __bic_SR_register(SCG0);                     // enable FLL
        while(CSCTL7 & (FLLUNLOCK0 | FLLUNLOCK1));   // FLL locked
    
        CSCTL4 = SELMS__DCOCLKDIV | SELA__XT1CLK;   // set XT1 (~32768Hz) as ACLK source, ACLK = 32768Hz
                                                     // default DCOCLKDIV as MCLK and SMCLK source
    
        P1DIR |= BIT0 | BIT1 | BIT2;                 // set ACLK SMCLK and LED pin as output
        P1SEL1 |= BIT0 | BIT1;                       // set ACLK and  SMCLK pin as second function
    
        PM5CTL0 &= ~LOCKLPM5;                        // Disable the GPIO power-on default high-impedance mode
                                                     // to activate previously configured port settings
    
        RTCInit();
        InitTimer();
        _enable_interrupts();
    
    
        while(1)
        {
            LPM0;
        }
    }
    uint16_t delta[128];
    uint16_t count, pre_rtc;
    
    #pragma vector = TIMER0_B0_VECTOR
    __interrupt void TIMER0_B0_ISR(void)
    {
    
        delta[count] = RTCCNT - pre_rtc;
        pre_rtc = RTCCNT;
        count++;
    
        if (count>=120)
        {
               HWREG16(TIMER_B0_BASE + OFS_TBxCTL) &=  ~MC;
    
               /* set a break point on nop() */
               _nop();
    
               HWREG16(TIMER_B0_BASE + OFS_TBxCTL) |=  MC__UP;
    
    
        }
    }