STM32带定时器的LED闪烁

时间:2018-04-26 10:20:16

标签: c timer stm32 led stm32f4discovery

我尝试使用不同频率的定时器中断使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个通道,都可以导致中断,但中断处理程序对所有通道都是相同的。

2 个答案:

答案 0 :(得分:1)

像这样更换你的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通道配置不同的频率。

答案 1 :(得分:0)

代码太大,无法放在这里。

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

任意数量的LED,任何频率(关闭和开启时间可能不同)任意数量的闪烁(+连续)和序列末尾的回调。