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.

[参考译文] MSP430F5529:MSP430F5529 RTC

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

https://e2e.ti.com/support/microcontrollers/msp-low-power-microcontrollers-group/msp430/f/msp-low-power-microcontroller-forum/1004479/msp430f5529-msp430f5529-rtc

器件型号:MSP430F5529
主题中讨论的其他器件: MSP430FG4618

大家好、

我正在尝试运行下面的程序、但 RTC 运行不好:

您能告诉我并告诉我我我我是否出错了吗?

此致、

Anderson。

//****************************************************************************//
// Definições e Inicialização do RTC Interno do MSP430 do Data Logger         //
//****************************************************************************//
void initRTC(void)
{
   // Configura o Relógio de Tempo Real RTC
   RTCCTL01 = RTCMODE + RTCBCD + RTCHOLD + RTCTEV_3; 
      
   RTCCTL01 |= RTCRDYIE + RTCTEVIE;                                               // Enable interrupt
    
   RTCPS0CTL = RT0PSDIV_7;                                                      // Set RTPS0 to /256
   RTCPS1CTL = RT1IP_6 + RT1PSIE + RT1SSEL_3;                                   // Set RT1IP to /4, enable
                                                                                // RT1PS interrupt and select
                                                                                // RTOPS output as clock
   // Desabilita a Interrupção de Alarme
   RTCCTL0 &= ~RTCAIE;                                                          // disable alarm interrupt
   RTCCTL0 &= ~RTCAIFG;                                                         // clear alarm interrupt flag
   
   // Rotinas para Inicialização dos Registradores do RTC  
   RTCSEC = 0x00;                                                               // Carrega com Zero o Registrador do RTCSEC
   RTCMIN = 0x00;                                                               // Carrega com Zero o Registrador do RTCMIN
   RTCHOUR = 0x00;                                                              // Carrega com Zero o Registrador do RTCHOUR
   RTCDOW = 0x01;                                                               // Carrega a Semana
   RTCDAY = 0x01;                                                               // Carrega o Dia 01
   RTCMON = 0x01;                                                               // Carrega o Mes 01
   RTCYEAR = 0x2020;                                                            // Carrega o Ano 2020
   
   // Programação do Inicio e Término das Coletas de Dados             
   Inic_Dia_Logger = 0x01;                                                            
   Inic_Mes_Logger = 0x01;                      
   Inic_Ano_Logger = 0x20;
   Inic_Hou_Logger = 0x00;
   Inic_Min_Logger = 0x00;
   Inic_Seg_Logger = 0x00;
  
   Term_Dia_Logger = 0x01;
   Term_Mes_Logger = 0x01;
   Term_Ano_Logger = 0x20;
   Term_Hou_Logger = 0x00;
   Term_Min_Logger = 0x00;
   Term_Seg_Logger = 0x00;
  
   // Programação do Inicio e Término das Transmissões de Dados             
   Inic_Dia_Lora = 0x01;                                                            
   Inic_Mes_Lora = 0x01;                      
   Inic_Ano_Lora = 0x20;
   Inic_Hou_Lora = 0x00;
   Inic_Min_Lora = 0x00;
   Inic_Seg_Lora = 0x00;
  
   Term_Dia_Lora = 0x01;
   Term_Mes_Lora = 0x01;
   Term_Ano_Lora = 0x20;
   Term_Hou_Lora = 0x00;
   Term_Min_Lora = 0x00;
   Term_Seg_Lora = 0x00;
}

//****************************************************************************//
// Rotina Principal do Data Logger                                            //
//****************************************************************************//
void main(void)
{
  volatile unsigned int j;                                                      // Variável de Inicialização da Frequencia do Cristal Oscilador

  WDTCTL = WDTPW + WDTHOLD;                                                     // Desabilita o WDT
  
  P5SEL |= BIT4+BIT5;                       // Port select XT1
  UCSCTL6 &= ~(XT1OFF);                     // XT1 On
  UCSCTL6 |= XCAP_3;                        // Internal load cap
  
  // Loop until XT1 fault flag is cleared
  do
  {
    UCSCTL7 &= ~XT1LFOFFG;                  // Clear XT1 fault flags
  }while (UCSCTL7&XT1LFOFFG);               // Test XT1 fault flag

  // Initialize DCO to 1.998MHz
  __bis_SR_register(SCG0);                  // Disable the FLL control loop
  UCSCTL0 = 0x0000;                         // Set lowest possible DCOx, MODx
  UCSCTL1 = DCORSEL_3;                      // Set RSELx for DCO = 4.9 MHz
  UCSCTL2 = FLLD_1 + 60;                    // Set DCO Multiplier for 1.998MHz
                                            // (N + 1) * FLLRef = Fdco
                                            // (60 + 1) * 32768 = 1.998MHz
                                            // Set FLL Div = fDCOCLK/2
  __bic_SR_register(SCG0);                  // Enable the FLL control loop

  
  // Loop until XT1,XT2 & DCO fault flag is cleared
  do
  {
    UCSCTL7 &= ~(XT2OFFG + XT1LFOFFG + DCOFFG);
                                            // Clear XT2,XT1,DCO fault flags
    SFRIFG1 &= ~OFIFG;                      // Clear fault flags
  }while (SFRIFG1&OFIFG);                   // Test oscillator fault flag
  
  .....
  
  // Habilita os Periféricos RTC e BT
  RTCCTL01 &= ~RTCHOLD;                                                         // Habilita o RTC
  
  // Rotina Principal do Loop
  do                                            
    {
       __bis_SR_register(LPM3_bits + GIE);                                      // Entra em LPM3 (Modo de Baixo Consumo)
       __no_operation ();                                                       // Não Faz Nada    
    }
  while (1);                                                                    // Enquanto While Igual a 1, Garante o LPM3
  }
  
  //****************************************************************************//
// Rotina de Tratamento das Coletas de Dados via Memória Interna do Data Logger //
//****************************************************************************//
#if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
#pragma vector=RTC_VECTOR
__interrupt
#elif defined(__GNUC__)
__attribute__((interrupt(RTC_VECTOR)))
#endif
void RTC_A_ISR (void)
{
   switch (__even_in_range(RTCIV,16))
     {
        case 0: break;  //Sem interrupção
        case 2:         //RTCRDYIFG
            //Interrupção a cada segundo
            Temporiza_RTC = Temporiza_RTC + 1;
            break;
        case 4:         //RTCEVIFG
            //Interrupção a cada minuto
            break;
        case 6:         //RTCAIFG
            //Interrupts 5:00pm on 5th day of week
            break;
        case 8: break;  //RT0PSIFG
        case 10: break; //RT1PSIFG
        case 12: break; //Reserved
        case 14: break; //Reserved
        case 16: break; //Reserved
        default: break;
     }

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

    尊敬的 Anderson:

    我建议您从 Resource Explorer 中为此器件提供的 RTC 示例之一开始:

    https://dev.ti.com/tirex/explore/node?node=ANgONtNncVD8cPVos4dglQ__IOGqZri__LATEST&search=MSP430F5529

    您使用的是5529 Launchpad 吗?  当您说"工作不好"时、这到底意味着什么?

    BR、
    Leo

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

    您好、Leo、

    感谢您的关注!

    我需要将处理速度从1MHz 提高到2MHz 或4MHz、这是理想情况、因为有此需要。

    当我按如下方式编译和仿真固件时、一切都运行得很好:

    //****************************************************************************//
    // Rotina Principal do Data Logger                                            //
    //****************************************************************************//
    void main(void)
    {
      volatile unsigned int j;                                                      // Variável de Inicialização da Frequencia do Cristal Oscilador
    
      WDTCTL = WDTPW + WDTHOLD;                                                     // Desabilita o WDT
         
      // Set up XT1
      P5SEL |= BIT4+BIT5;                                                           // Select XT1
      UCSCTL6 &= ~(XT1OFF);                                                         // XT1 On
      UCSCTL6 |= XCAP_3;                                                            // Internal load cap
       
      // Loop until XT1,XT2 & DCO stabilizes - In this case loop until XT1 and DCo settle
      do
      {
        UCSCTL7 &= ~(XT2OFFG + XT1LFOFFG + DCOFFG);
                                                                                    // Clear XT2,XT1,DCO fault flags
        SFRIFG1 &= ~OFIFG;                                                          // Clear fault flags
      }while (SFRIFG1&OFIFG);                                                       // Test oscillator fault flag
      
      UCSCTL6 &= ~(XT1DRIVE_3);                                                     // Xtal is now stable, reduce drive strength
    
      UCSCTL4 |= SELA_0;                                                            // ACLK = LFTX1 (by default)
    
    
    .......

    当我在 MSP430F5529上将 FLL 配置为2MHz 或4MHz 时、RTC 会工作并递增和更新变量、但我不会看到它中断以与1MHz 时相同的方式执行例程。

    我还为 MSP430FG4618做了其他示例、它根据我们的以下需求完美工作:

    //****************************************************************************//
    // Definições e Inicialização do RTC Interno do MSP430 do Data Logger         //
    //****************************************************************************//
    void initRTC(void)
    {
       RTCCTL = RTCBCD + RTCHOLD + RTCMODE_3;
       // Rotinas para Inicialização dos Registradores do RTC  
       RTCSEC = 0x00;                                                                // Carrega com Zero o Registrador do RTCSEC
       RTCMIN = 0x00;                                                                // Carrega com Zero o Registrador do RTCMIN
       RTCHOUR = 0x00;                                                               // Carrega com Zero o Registrador do RTCHOUR
       RTCDOW = 0x00;                                                                // Carrega a Semana
       RTCDAY = 0x01;                                                                // Carrega o Dia 01
       RTCMON = 0x01;                                                                // Carrega o Mes 01
       RTCYEAR = 0x2020;                                                             // Carrega o Ano 2020
      
       // Programação do Inicio e Término das Coletas de Dados             
       Inic_Dia_Logger = 0x01;                                                            
       Inic_Mes_Logger = 0x01;                      
       Inic_Ano_Logger = 0x20;
       Inic_Hou_Logger = 0x00;
       Inic_Min_Logger = 0x00;
       Inic_Seg_Logger = 0x00;
      
       Term_Dia_Logger = 0x01;
       Term_Mes_Logger = 0x01;
       Term_Ano_Logger = 0x20;
       Term_Hou_Logger = 0x00;
       Term_Min_Logger = 0x00;
       Term_Seg_Logger = 0x00;
    }
    
    //****************************************************************************//
    // Rotina Principal do Data Logger                                            //
    //****************************************************************************//
    void main(void)
    {
      volatile unsigned int j;                                                      // Variável de Inicialização da Frequencia do Cristal Oscilador
    
      WDTCTL = WDTPW + WDTHOLD;                                                     // Desabilita o WDT
      
      //FLL+ configuration 		                                                    // ACLK - 32.768 kHz 
      FLL_CTL0 |= (DCOPLUS + XCAP10PF);                                             // DCO+ set, freq = xtal x D x N+1
      SCFI0 |= FLLD_2 + FN_4;                                                       // x2 DCO freq, 4MHz nominal DCO
      SCFQCTL = 60;                                                                 // 60+1) x 32768 x 2 = 3.99 MHz
      
      // Rotina para Inicialização e Estabilização do Cristal Oscilador 32.768kHz
      do
        {
           IFG1 &= ~OFIFG;                                                          // Limpa a Flag OSCFault
           for (j = 0x47FF; j > 0; j--);                                            // Aguarda para Setar a Flag
        }
      while ((IFG1 & OFIFG));                                                       // Flag OSCFault foi Setada?
      
      // An immediate Osc Fault will occur next
      IE1 |= OFIE;                                                                  // Enable osc fault interrupt
      
      
      ......

    此致、

    Anderson。

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

    尊敬的 Anderson:

    您使用的是 Launchpad 还是您自己的硬件?

    BR、
    Leo

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

    您好、Leo、

    我正在使用自己的制作硬件。

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

    尊敬的 Anderson:

    当您说它不是以相同的方式中断时、您是意味着您看不到任何中断-还是意味着中断没有 按预期的时序发生? 您是否有两种情况下的中断逻辑/范围跟踪?

    BR、
    Leo

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

    您好、Leo、

    我刚刚使用1MHz 进行了仿真和调试、我认为存在时间差异、使用1MHz 时、时间差会在正确的时间发生。 使用2MHz 时、我不确定会发生什么情况、您是否有有关如何检查的提示?

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

    尊敬的 Anderson:

    每当触发 RTC ISR (案例2)时、您可以切换 GPIO 引脚、并在从调试器断开(或自由运行)运行程序时使用逻辑分析仪或数字示波器捕获此信号、以查看每秒发生一次。   

    BR、
    Leo

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

    您好、Leo、

    我设法找到了出错的地方!

    我没有考虑使用__delay_cycles (5000)的单个拉伸;对于1MHz 频率、随着时钟频率的增加、我没有相应地调整频率并导致例程崩溃。

    但是、根据您的建议、我能够看到我的错误发生在哪里。

    感谢您的关注!

    此致、

    Anderson。