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.

[参考译文] 如何使用 MSP432P401R 上的 Timer_A 来执行正确的延迟系统?

Guru**** 2481985 points


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

https://e2e.ti.com/support/microcontrollers/msp-low-power-microcontrollers-group/msp430/f/msp-low-power-microcontroller-forum/1269862/how-to-preform-correct-delay-system-using-timer_a-on-the-msp432p401r

大家好、  

我正在尝试建立一个基于 MSP432上计时器的延迟系统、以排除系统中的许多环路。 现在我面临一个问题、在我的系统中、我需要将函数应用到第二、毫秒和微秒。 我首先定义一个24MHz 的时钟系统、然后除以至以获得 SMCLK、这样将提供一个12MHz 的时钟。 在"timer_Initialize"函数中、我给出所需的配置、最后启用 NVIC 中断。

对于此中断定时器上的处理程序,我创建了一个开关,在这里使用所需的"enum type def",我可以使用每个情况,由 proprelly 函数调用。 这样我就可以进入期望的情况下的中断专有性。 一旦我使用一个我想要的16位定时器、每次定时器重新增加溢出时、它都会递增、直到获得所需的延迟、在这之后、它会清除计数器和所使用的函数。 下面我分享基本部分的代码与一些希望有人可以帮助我.

#include "msp432p401r.h"
#include <stdio.h>
#include "cs.h"
#include "gpio.h"


/*DEFINE ENUMERATION TIMER*/
typedef enum{ _TASK_uMICROSECOND = 0, _TASK_MILLISECONDS, _TASK_SECONDS} TIMER_;
volatile TIMER_ delayTime = _TASK_uMICROSECOND;

volatile uint32_t timerOverflow = 0;

void init_LED(void);
void TIMER_Initialize(void);
/*************SIMPLE CLOCK AND DELAY USING TIMMER**************
* Timer Period = (Clock Period * ID * IDEX * Timer Counts) - 1*
* SMCLK = 12MHz/4  = 3MHz                                    *
* CLOCK PERIOD = 1 / CLOCK SYSTEM => CLOCK PERIOD = 166,67ns  *
* Timer Period = (Clock Freq / Prescaler) / D. Interrupt Freq *
* Timer OVERFLOW < COUNT REGISTER (2^16 - 1 = 65535)          s*
*
*/
/*SMCLK = 12MHz/4  = 3MHz*/
/*T = 1/F=> 1/1MHz = 1us*/
/*TIMERClock T=4/6MHz = 666.7ns */

void  delaySeconds(int sec);
void  delayMiliseconds(int msec);
void  delayMicroseconds(int usec);

void main(void){
    WDTCTL = WDTPW + WDTHOLD;

    init_LED();

    GPIOInterface_initGPIO();

    GPIOInterface_initClocks();                           /*CLOCK SOURCE*/

    TIMER_Initialize();                                   /*TIMER INITIALIZATION FUNCTION*/

    __enable_irq();

    while(1){

        delaySeconds(5);
    }
}


void TIMER_Initialize(void){

    TIMER_A0->CCTL[0]&= ~TIMER_A_CTL_CLR;                  /*TIMER A CLEAR */

    TIMER_A0->CTL     = TIMER_A_CTL_MC__CONTINUOUS  |      /*TIMER COUNTINUOUS*/
                        TIMER_A_CTL_SSEL__SMCLK     |      /*SMCLK*/
                        TIMER_A_CTL_ID_2            ;      /*TIMER A DIVISION BY 4 (12 000 000/4 = 3 000 000)*/

    TIMER_A0->EX0    |= TIMER_A_EX0_TAIDEX_2;              /* 3 000 000/3 = 1 000 000*/

    TIMER_A0->CCTL[0] = TIMER_A_CCTLN_CCIE ;               /*LOCAL ENABLE OVERFLOW IN TIMER A0*/

    /*SET NVIC INTERRUPTION*/
    NVIC->ISER[0] = 1 << ((TA0_0_IRQn) & 31);
}

/*TIMER A0 INTERRUPT SERVICE ROUTINE*/
void TA0_0_IRQHandler(void){
    timerOverflow++;


    switch(delayTime){
        /*uMICROSECOND*/
        case 0:
        break;

        /*MILLISECOND*/
        case 1:
        break;

        /*SECOND*/
        case 2:
            P1->OUT ^= BIT0;                               /*TOOGLE LED TO SHOW */
        break;
    }

    TIMER_A0->CCTL[0] &= ~(TIMER_A_CCTLN_CCIFG);           /*CLEAR FLAG*/

}


void init_LED(void){

    P1->DIR |= BIT0;                       /*SET P1.0 TO OUTPUT*/
    P2->DIR |= BIT1;                       /*SET P2.1 TO OUTPUT*/
    P2->DIR |= BIT2;                       /*SET P2.2 TO OUTPUT*/
    P2->DIR |= BIT3;                       /*SET P2.3 TO OUTPUT*/

    P1->OUT &= ~(BIT0);                    /*SET P1.0 TO LOW*/
    P2->OUT &= ~(BIT1);                    /*SET P2.1 TO LOW*/
    P2->OUT &= ~(BIT2);                    /*SET P2.2 TO LOW*/
    P2->OUT &= ~(BIT3);                    /*SET P2.3 TO LOW*/
}

    void  delaySeconds(int sec){}
    void  delayMiliseconds(int msec){}
    void  delayMicroseconds(int usec){}

提前感谢

我尝试实施代码、希望对延迟函数更改 while 循环有所帮助

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

    您好!

     此器件已停产(已停产)已一段时间、因此不提供技术支持。 我将建议您参考 SDK 中的各种计时器示例。  

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

    我建议 SysTick 执行此类操作。 这是相当容易实施 Arduino "米利斯"函数:

    //配置 SysTick
       MAP_SysTick _enableModule();
       // 48M = 1秒、4.8M = 100ms、480000 = 10ms……
       MAP_SysTick _setPeriod (48000);//每1ms
       Map_Systick _enableInterrupt();

    空 Tick_Handler (空)
    {
       millis++;



    uint32_t GetMillis ()
    {
       uint32_t tmp;

       MAP_SysTick disableInterrupt();
       tmp = Millis;
       Map_Systick _enableInterrupt();

       返回 tmp;



    空延迟(int msec){
       //忙等待毫秒 ms
       volatile int ii;
       int starttime = GetMillis();

       while ((GetMillis ()- starttime)< msec)
       {
           用于(ii=0;ii<10000;ii++);
       }