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.

[参考译文] MSP430FR5994:MSP430FR5994:使用内置函数时计时器不工作

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

https://e2e.ti.com/support/microcontrollers/msp-low-power-microcontrollers-group/msp430/f/msp-low-power-microcontroller-forum/977669/msp430fr5994-msp430fr5994-timer-not-working-using-inbuilt-functions

器件型号:MSP430FR5994

大家好、团队成员
我使用的是 MSP430FR5994 Launchpad 套件。 我正在尝试使用函数"timer_delay (delay);"初始化计时器、但我没有收到任何中断。
我能够使 LED 闪烁并使用其他代码访问开关输入。 要访问开关、我必须按照 E2E 论坛中的规定更新 MSP430FR5994.h 文件。
下面随附了我使用的代码。 请查看。

e2e.ti.com/.../New-Text-Document_5F00_clock_5F00_timer.txt

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

    1)  

    >#pragma vector=TIMER0_A0_vector

    您使用的是 TIMER_A1、因此这应该是:

    >#pragma vector=Timer1_A0_vector

    2) 2) DELAY_FLAG 应声明为"volatile"

    3) 3)您应该在停止计时器后设置 DELAY_FLAG=0。

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

    你(们)好

    根据建议更新了代码、但仍然无法正常工作。 我还更新了行 initContParam.clockSourceDivider= timer_A_CLOCKSOURCE_divider; 更新为 initContParam.clockSourceDivider= timer_A_CLOCKSOURCE_divider;16;

    在上述情况下,使用中的代码初始化时钟

    IE,SMCLK 将为16MHz。 因此、使用 TIMER_A_CLOCKSOURCE_DEVIDER_16将时钟源设置为1MHz。

    代码的目的是生成1秒的延迟。 因此、我设置 initCompParam.compareValue= 0xF4240;启用中断以检测比较器达到0xF4240。 到达后、应调用 ISR 并将延迟设置为1、从而结束循环。  

    当调用 timer_delay()时,延迟被分配为0。

    请对使用的代码和方法进行评论。

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

    什么(精确)不起作用?

    不能使用 compareValue 0xF4240、因为 compareValue (和 TA1CCR0)仅为16位。 我很惊讶编译器没有就此向您发出警告。

    您可以将输入时钟除以最高8*8=64,因此使用 SMCLK=16MHz 时,您可以得到一个(65536/(16MHz/64))=~0.262秒的周期。 如果您想使用 SMCLK、我建议您将延迟分解为较小的单位、例如250ms 或可能10ms。

    在另一个线程中、您的电路板上似乎有一个32kHz 晶体。 ACLK 可以很容易地计数1秒(compareValue=CCR0=32768U-1)。

    未经请求:对于延迟、您可能会发现向上计数模式比连续模式更方便。

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

    你(们)好

    按照建议,我使用向上计数模式和时钟源 ACLK/64 (32.768kHz)更新了代码。 因此、为了获得1s 延迟、我将 initContParam.timerPeriod=0x0200设置为等于1秒的周期。 我创建了两个函数   timer_init ()和 timer_delay (uint32_t delay)。 使用 timer_delay()我想创建启动计时器,在计时器使用中断例程到达0x200时检查 DELAY_FLAG 是否设置为1,然后停止计时器,返回主函数。

    目前,代码卡在 timer_delay()内的 while 循环中,LED 停止闪烁。

    请检查更新后的代码并告诉我问题是什么。

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

    你(们)好

    代码如下。



    #include "./MSP430FR5xx_6xx/driverlib.h"
    #include
    //#include


    void initClock (void);
    void timer_init (void);
    void timer_delay (uint32_t);

    int Flag1 = 0、flag2 = 0;
    volatile int delay_flag = 0;
    INT 计数= 0;
    int SW1_state=1、SW2_state=1;

    int main (空)


       volatile uint32_t i;
       volatile uint8_t SW1、SW2;
       volatile uint16_t SW1_INTERRUPT=1、SW2_INTERRUPT=1、SW1_INTERRUPT_PRE、SW2_INTERRUPT_PRE;
       volatile uint16_t timer_value=0;
       volatile uint32_t delay = 0;

       计数= 0;

       //停止看门狗计时器
       WDT_A_HOLD (WDT_A_base);

       //initClock();

       timer_init();

       GPIO_setAsOutputPin (GPIO_PORT_P1、GPIO_PIN0);        //设置红色 LED 输出
       GPIO_setOutputLowOnPin (GPIO_PORT_P1、GPIO_PIN0);     //红色 LED 关闭
       GPIO_setAsOutputPin (GPIO_PORT_P1、GPIO_PIN1);        //设置绿色 LED 输出
       GPIO_setOutputLowOnPin (GPIO_PORT_P1、GPIO_PIN1);     //绿色 LED 关闭

       GPIO_setAsInputPinWithPullUpResistor (GPIO_PORT_P5、GPIO_PIN6);                     // S1 P5.6:PxDIR、PxOUT 和 PxREN 寄存器
       GPIO_selectInterruptEdge (GPIO_PORT_P5、GPIO_PIN6、GPIO_HIGH_TO_LOW_TRANSITION);     // S1 P5.6:PxIES 寄存器

       GPIO_setAsInputPinWithPullUpResistor (GPIO_PORT_P5、GPIO_PIN5);                     // S2 P5.5:PxDIR、PxOUT 和 PxREN 寄存器
       GPIO_selectInterruptEdge (GPIO_PORT_P5、GPIO_PIN5、GPIO_HIGH_TO_LOW_TRANSITION);     // S2 P5.5:PxIES 寄存器


       SW1 = GPIO_getInputPinValue (GPIO_PORT_P5、GPIO_PIN6);

       SW2 = GPIO_getInputPinValue (GPIO_PORT_P5、GPIO_PIN5);





       //SW1_STstate = SW1和0x08;

       //禁用 GPIO 上电默认高阻抗模式以激活先前配置的端口设置
       PMM_unlockLPM5 ();

       //将所有 P5IFG 设为零
       P5IFG = 0x00;

       //将所有 P5IFG 设为零
       //TAIFG = 0x00;


       GPIO_enableInterrupt (GPIO_PORT_P5、GPIO_PIN5);
       GPIO_enableInterrupt (GPIO_PORT_P5、GPIO_PIN6);

       _bis_SR_register (GIE); //启用所有中断

       //*
       //启用开关中断
       GPIO_clearInterrupt (GPIO_PORT_P5、GPIO_PIN5);
       GPIO_clearInterrupt (GPIO_PORT_P5、GPIO_PIN6);

       //*/

       SW1_INTERRUPT_PR= GPIO_getInterruptStatus (GPIO_PORT_P5、GPIO_PIN6);
       SW2_INTERRUPT_PR= GPIO_getInterruptStatus (GPIO_PORT_P5、GPIO_PIN5);

       while (1)
       {


           if (SW1_INTERRUPT_PRE!= GPIO_getInterruptStatus (GPIO_PORT_P5、GPIO_PIN6))
           {
               如果(SW1_INTERRUPT = 1)
               {
                   SW1_INTERRUPT = 0;
               }
               其他
               {
                   SW1_INTERRUPT = 1;
               }

               GPIO_clearInterrupt (GPIO_PORT_P5、GPIO_PIN6);
           }
           if (SW2_INTERRUPT_PRE!= GPIO_getInterruptStatus (GPIO_PORT_P5、GPIO_PIN5))
           {
               如果(SW2_INTERRUPT = 1)
               {
                   SW2_INTERRUPT = 0;
               }
               其他
               {
                   SW2_INTERRUPT = 1;
               }
               GPIO_clearInterrupt (GPIO_PORT_P5、GPIO_PIN5);
           }

           SW1 = GPIO_getInputPinValue (GPIO_PORT_P5、
                                 GPIO_PIN6);

           SW2 = GPIO_getInputPinValue (GPIO_PORT_P5、
                                     GPIO_PIN5);

           // if (GPIO_getInputPinValue (GPIO_PORT_P5、GPIO_PIN6)=GPIO_INPUT_PIN_HIGH)
           如果(SW2_STACLE = 1)
           {
               IF (Flag1 = 0)
               {
                   Flag1 = 10;
                   GPIO_toggleOutputOnPin (GPIO_PORT_P1、GPIO_PIN1);
               }
               其他
               {
                   Flag1 = Flag1--;

               }
           }


           if (GPIO_getInputPinValue (GPIO_PORT_P5、GPIO_PIN6)=GPIO_INPUT_PIN_HIGH)
           {
               如果(标志2 = 0)
               {
                   标志2 = 4;
                   GPIO_toggleOutputOnPin (GPIO_PORT_P1、GPIO_PIN0);
               }
               其他
               {
                   flag2 = flag2--;

               }
           }



           //延迟
           for (i=100000;i>0;i--);
           延迟= 0xFFFFFFF;
           Timer_delay (延迟);

           //timer_value = Timer_A_getCounterValue (timer_A1_base);
           //timer_delay (delay);
           //timer_delay (delay);
           //_delay_cycles (16000000);//等待160000个 CPU 周期
       }




    void timer_init()


       //启动定时器_A
       //Timer_A_initContinuousModeParam initContParam ={0};
       Timer_A_initUpModeParam initContParam ={0};
       initContParam.clockSource= TIMER_A_CLOCKSOURCE_ACLK;
       initContactParam.clockSourceDivider= timer_A_CLOCKSOURCE_divider;
       initContParam.timerPeriod=0x0200;
       initContParam.timerInterruptEnable_TAIE= TIMER_A_TAIE_INTERRUPT_ENABLE;
       initContParam.captureCompareInterruptEnable_CCR0_CCIE = TIMER_A_CCIE_CCR0_INTERRUPT_DISABLE;
       initContParam.timerClear = timer_a_do _clear;
       initContParam.startTimer=false;

       Timer_A_initUpMode (timer_A1_base、&initContParam);   // Timer_A_initContinuousMode






    void timer_delay (uint32_t delay)


       DELAY_FLAG = 0;

       Timer_A_clear (timer_A1_base);
       Timer_A_startCounter (timer_A1_base、timer_A_up_mode);


       while (!delay_flag)
       {
           
       }


       Timer_A_stop (timer_A1_base);
       Timer_A_clearTimerInterrupt (timer_A1_base);



       //Enter LPM0
       //_bis_SR_register (LPM0_bits);
       //用于调试器
       //__no_operation();





    #pragma vector=TIMER0_A1_vector
    _interrupt void TIMER0_A1_ISR (void)
    //void __attribute__((interrupt (TIMER0_A0_vector)) TIMER0_A0_ISR (void)


       DELAY_FLAG = 1;





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

    > #pragma vector=TIMER0_A1_vector

    您使用的是 timer_A1_base、因此这应该是:

    >#pragma vector=Timer1_A1_vector

    --------

    在 ISR 内部的某个位置,您需要使用以下内容来显式清除 TAIFG:

    > Timer_A_clearTimerInterrupt (timer_A1_base);

    否则、中断将仅保持触发状态。 (CCR0不需要这种情况、即 Timer1_A0_vector。)  [参考用户指南(SLAU367P)第25.2.6节]

    --------

    >  GPIO_enableInterrupt (GPIO_PORT_P5、GPIO_PIN5);
    >  GPIO_enableInterrupt (GPIO_PORT_P5、GPIO_PIN6);

    您正在启用这些引脚中断、但我看不到它们的 ISR (PORT5_vector)。 其余代码似乎正在轮询中断状态、因此您可能应该只删除这些行。

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

    你(们)好

    1.是否可以使用 Timer_A_clear (timer_A1_base);重置计时器,以便在调用 timer_delay ()时它从零开始。 或者,无论何时调用 Timer_a_startCounter(),它都会自动从零开始计时器?

    2.是定时器 A CCR0被称为 Timer0_A0_vector,CCR1作为 Timer0_A1_vector,... 定时器 B CCR0被称为 Timer1_A0_vector、CCR1被称为 Timer1_A1_vector、…… 请确认。

    代码修改如下:添加了 ISR (PORT5_vector)。 此外、Timer_A_clearTimerInterrupt (timer_A1_base);已添加到 ISR 内部。

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

    1) 1)是的、实际上您应该这样做。 Timer_A_stop 和 Timer_A_startCounter 都不会清除计数器。

    2)主要是。 UG 章节25.2.6描述了每个定时器的两个不同的 IRQ -一个用于 CCR0、另一个用于所有其它定时器(包括 TAIFG)。 对于 TA0、这些是(如您所说) TIMER0_A0_VECTOR 和 TIMER0_A1_VECTOR。 对于 TA1、它们是 Timer1_A0_vector 和 Timer1_A1_vector。 对于 TB2、它们是 TIMER2_B0_vector 和 TIMER2_B1_vector。 这需要一点实践、但有一个系统。

    那么、您的程序现在做什么呢?

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

    您好、Bruce、

    感谢您的支持。 代码现在工作。

    此致、

    Bivin