簡體   English   中英

帶有計時器的STM32閃爍LED

[英]STM32 Blinking LEDs with a Timer

我正在嘗試使用計時器中斷以不同的頻率閃爍4個LED。

我想出了這段代碼

/*********** Includes  ****************/
#include "stm32f4xx.h"
#include "stm32f4_discovery.h"


/*********** Defines  *****************/
#define TIM3_CK_CNT 50000


/*********** Declarations *************/
/*------ Function prototypes ---------*/
void TimerConfiguration(void);


/* ----- Global variables ----------- */
volatile uint16_t CCR1_Val = 50000;
volatile uint16_t CCR2_Val = 40000;
volatile uint16_t CCR3_Val = 30000;
volatile uint16_t CCR4_Val = 20000;

 /************ Main *********************/
int main(void)
{

// LED initialization
STM_EVAL_LEDInit(LED3);     // Orange
STM_EVAL_LEDInit(LED4);     // Green
STM_EVAL_LEDInit(LED5);     // Red
STM_EVAL_LEDInit(LED6);     // Blue

/* TIM3 Configuration */
TimerConfiguration();



while (1);
}



/*********** Functions *****************/

/**
  * @brief  Configure the TIM3 TIMER.
  * @param  None
  * @retval None
  */
void TimerConfiguration(void)
{
uint16_t PrescalerValue = 0;
TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
TIM_OCInitTypeDef  TIM_OCInitStructure;
NVIC_InitTypeDef NVIC_InitStructure;

/* TIM3 clock enable */
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);

/* Time base configuration */
TIM_TimeBaseStructure.TIM_Period = 65535;
TIM_TimeBaseStructure.TIM_Prescaler = 0;
TIM_TimeBaseStructure.TIM_ClockDivision = 0;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);

/* Prescaler configuration */
PrescalerValue = (uint16_t) ((SystemCoreClock / 2) / TIM3_CK_CNT) - 1;
TIM_PrescalerConfig(TIM3, PrescalerValue, TIM_PSCReloadMode_Immediate);

/* Output Compare Timing Mode configuration: Channel1 */
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_Timing;
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_Pulse = CCR1_Val;
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
TIM_OC1Init(TIM3, &TIM_OCInitStructure);
TIM_OC1PreloadConfig(TIM3, TIM_OCPreload_Disable);
/*Channel2 */
TIM_OCInitStructure.TIM_Pulse = CCR2_Val;
TIM_OC2Init(TIM3, &TIM_OCInitStructure);
/*Channel3 */
TIM_OCInitStructure.TIM_Pulse = CCR3_Val;
TIM_OC3Init(TIM3, &TIM_OCInitStructure);
/*Channel4 */
TIM_OCInitStructure.TIM_Pulse = CCR4_Val;
TIM_OC4Init(TIM3, &TIM_OCInitStructure);

/* Configure the TIM3 gloabal Interrupt */
NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);

/* TIM Interrupts enable */
TIM_ITConfig(TIM3, TIM_IT_CC1, ENABLE);
TIM_ITConfig(TIM3, TIM_IT_CC2, ENABLE);
TIM_ITConfig(TIM3, TIM_IT_CC3, ENABLE);
TIM_ITConfig(TIM3, TIM_IT_CC4, ENABLE);
/* TIM3 counter enable */
TIM_Cmd(TIM3, ENABLE);



}


int LedCount6 = 0;
int LedCount5 = 0;
int LedCount4 = 0;
int LedCount3 = 0;

/************ Interrupt Handlers *************/

/**
* @brief  This function handles TIM3 global interrupt request.
* @param  None
* @retval None
*/

void TIM3_IRQHandler(void)
{
uint16_t capture = 0;
LedCount6++;
LedCount5++;
LedCount4++;
LedCount3++;

if ((TIM_GetITStatus(TIM3, TIM_IT_CC2)  != RESET) && (TIM_GetITStatus(TIM3, TIM_IT_CC1)  != RESET) && (TIM_GetITStatus(TIM3, TIM_IT_CC3)  != RESET) && (TIM_GetITStatus(TIM3, TIM_IT_CC4)  != RESET))
{
    TIM_ClearITPendingBit(TIM3, TIM_IT_CC1);
    TIM_ClearITPendingBit(TIM3, TIM_IT_CC2);
    TIM_ClearITPendingBit(TIM3, TIM_IT_CC3);
    TIM_ClearITPendingBit(TIM3, TIM_IT_CC4);

    int val6 = 100000;
    int val5 = 70000;
    int val4 = 60000;
    int val3 = 50000;





    if (LedCount6 >= val6 ) {
    /* LED6 toggling */
    STM_EVAL_LEDToggle(LED6);

    LedCount6 = 0;

    /* Update CH1 OCR */
    capture = TIM_GetCapture1(TIM3);
    TIM_SetCompare1(TIM3, capture + CCR1_Val);}


    if (LedCount5 >= val5) {

    /* LED5 toggling */
    STM_EVAL_LEDToggle(LED5);

    LedCount5 = 0;

    /* Update CH2 OCR */
    capture = TIM_GetCapture2(TIM3);
    TIM_SetCompare2(TIM3, capture + CCR2_Val);}

    if (LedCount4 >= val4) {

    /* LED4 toggling */
    STM_EVAL_LEDToggle(LED4);

    LedCount4 = 0;

    /* Update CH3 OCR */
    capture = TIM_GetCapture3(TIM3);
    TIM_SetCompare3(TIM3, capture + CCR3_Val);}

    if (LedCount3 >= val3 ) {

    /* LED3 toggling */
    STM_EVAL_LEDToggle(LED3);

    LedCount3 = 0;

    /* Update CH4 OCR */
    capture = TIM_GetCapture4(TIM3);
    TIM_SetCompare4(TIM3, capture + CCR4_Val);}
}


}

現在,所有使4個LED閃爍的代碼都在中斷處理程序內(void TIM3_IRQHandler(void))。 4個LED閃爍,但同時全部閃爍,如何更改它們的頻率以使其完全不同?

更改TIM3_CK_CNT值將更改所有4的頻率,但是由於這是一個定義,因此我無法通過代碼來操縱它以更改每個led的頻率。

TIMER(TIM3)有4個通道,所有通道均可引起中斷,但所有通道的中斷處理程序都相同。

像這樣替換您的IRQ處理程序(根據需要更改LED切換開關):

void TIM3_IRQHandler(void)
{

    uint16_t capture = 0;

    if (TIM_GetITStatus(TIM3, TIM_IT_CC2)  != RESET)
    {
        TIM_ClearITPendingBit(TIM3, TIM_IT_CC2);
       /* LED6 toggling */
       STM_EVAL_LEDToggle(LED6);


       /* Update CH1 OCR */
       capture = TIM_GetCapture1(TIM3);
       TIM_SetCompare1(TIM3, capture + CCR1_Val);
    } 
    else if (TIM_GetITStatus(TIM3, TIM_IT_CC1)  != RESET)
    {
        TIM_ClearITPendingBit(TIM3, TIM_IT_CC1);
        /* LED5 toggling */
        STM_EVAL_LEDToggle(LED5);


        /* Update CH2 OCR */
        capture = TIM_GetCapture2(TIM3);
        TIM_SetCompare2(TIM3, capture + CCR2_Val);
    }
    else if (TIM_GetITStatus(TIM3, TIM_IT_CC3)  != RESET)
    {
        TIM_ClearITPendingBit(TIM3, TIM_IT_CC3);
        /* LED4 toggling */
        STM_EVAL_LEDToggle(LED4);


        /* Update CH3 OCR */
        capture = TIM_GetCapture3(TIM3);
        TIM_SetCompare3(TIM3, capture + CCR3_Val);

    }
    else if (TIM_GetITStatus(TIM3, TIM_IT_CC4)  != RESET)
    {

        TIM_ClearITPendingBit(TIM3, TIM_IT_CC4);
        /* LED3 toggling */
        STM_EVAL_LEDToggle(LED3);


        /* Update CH4 OCR */
        capture = TIM_GetCapture4(TIM3);
        TIM_SetCompare4(TIM3, capture + CCR4_Val);

    }
}

進行此更改后,LED將針對每個通道中斷進行切換。 即每個中斷只有一個LED閃爍。 為了以不同的頻率閃爍,您需要查看數據表,如何為不同的LED通道配置不同的頻率。

代碼太大,無法在此處放置。

這是我的解決方案: https : //www.diymat.co.uk/arm-blinking-led-driver/

任何數量的LED,任何頻率(關閉和打開時間可以不同),任何數量的閃爍(+連續)和序列結束時的回調。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM