这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » 嵌入式开发 » STM32 » 【STM32WBA55CG环境检测】3、LED的多种控制模式

共2条 1/1 1 跳转至

【STM32WBA55CG环境检测】3、LED的多种控制模式

高工
2024-12-22 22:25:15     打赏

        由于我们前期的任务目标中,不做台灯,而改为环境检测了,对于PWM的应用就缺失了一部分,这样也会导致基本上没有下行的控制命令的必要的,这样可不行,所以有关PWM控制部分我们集成到板载的LED控制,来实现三个LED的多种控制模式,我们这里实现四种控制模式。

        第一种就是循环灯,三个LED循环点亮;

        第二种就是Blink,这里实现的事所有LED同亮和同灭;

        第三种是循环呼吸灯,三个LED循环呼吸点亮;

        第四个是同步呼吸灯,所有LED同频进行呼吸灯的实现;

        这里我们就要看一下芯片的资源是不是能满足我们的要求,我们这里不去看手册,在STM32CubeMX中进行查看:

                

image.png

        如上图,这样查看可以看到是不是是定时器CH口,如果可以,就能实现PWM呼吸灯的功能,LED1对应PB4,LED2对应PA9,LED3对应的是PB8,为了节约资源可以将其中PB4和PB8可以用同一个定时器(TIM1),PA9只能用定时器3了。

        咱们先初步将PB4配置为普通GPIO输出,PB8和PA9配置为PWM输出:

image.png

        上图可以看到配置为PWM输出的引脚是黄色,说明我们还没有配置完成,我们还要对对应的定时器进行配置例如PB8:

image.png

        PWM输出不需要配置中断等内容,只要配置时钟源、通道、定时基准就可以了,其他的使用默认配置就可以了。

        这里我们还添加了一个按键的控制,B1,作为还没有蓝牙控制的一个手动切换模式的控制按键:

image.png

        B1对应的按键是PC13:

image.png

        结合原理图,我们需要修改外部中断的配置,下降沿触发并且需要上拉,注意开启外部中断;

        我们先测试一下按键的效果,添加外部中断的回调函数:

void HAL_GPIO_EXTI_Falling_Callback(uint16_t GPIO_Pin)
{
  if(GPIO_Pin == B1_Pin)
  {/* KEY */
    HAL_GPIO_TogglePin(LED1_GPIO_Port, LED1_Pin);
  }
}

        LED1(蓝灯)的控制随着B1的按下进行翻转,加下来我们测试一下普通定时器16的,10ms定时功能:

void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
  if (htim->Instance == TIM16) {
    HAL_IncTick();
    LED.TIMcnt ++;
    if(LED.TIMcnt>100){
        LED.TIMcnt = 0;
        HAL_GPIO_TogglePin(LED1_GPIO_Port, LED1_Pin);
    }
  }
}

        这样就实现了和之前创建初始工程时的效果一样了,1s实现一次LED(蓝灯的翻转),这里需要注意一下,对于定时器不会自动开启,我们需要使用HAL_TIM_Base_Start_IT(&htim16);才能真正的运转起来。

        接下来我们看一下LED3(红灯)的呼吸灯效果,这也是加入定时器16的一个主要原因:

void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
  if (htim->Instance == TIM16) {
    HAL_IncTick();
    LED.TIMcnt ++;
    LED.PWMcnt ++;
    __HAL_TIM_SET_COMPARE(&htim1,TIM_CHANNEL_1,LED.PWMcnt*50);
    if(LED.PWMcnt>100)
        LED.PWMcnt = 0;
  }
}

        注意启动PWM对应的定时器,使用HAL_TIM_PWM_Start(&htim1,TIM_CHANNEL_1)效果正常;

        接下来就是一个整合了,由于我们对LED的控制分为不同的配置,这个我们是无法通过STM32CubeMX进行同步配置多以我们需要写两个不同状态的初始化程序,一个是三个LED都配置为GPIO输出:

void LED_GPIO_init(void)
{
    GPIO_InitTypeDef GPIO_InitStruct = {0};

    /* GPIO Ports Clock Enable */
    __HAL_RCC_GPIOB_CLK_ENABLE();
    __HAL_RCC_GPIOA_CLK_ENABLE();
    __HAL_RCC_GPIOC_CLK_ENABLE();

    /*Configure GPIO pin : PtPin */
    GPIO_InitStruct.Pin = LED1_Pin;
    GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
    GPIO_InitStruct.Pull = GPIO_PULLUP;
    HAL_GPIO_Init(LED1_GPIO_Port, &GPIO_InitStruct);

    GPIO_InitStruct.Pin = LED2_Pin;
    GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
    GPIO_InitStruct.Pull = GPIO_PULLUP;
    HAL_GPIO_Init(LED2_GPIO_Port, &GPIO_InitStruct);

    GPIO_InitStruct.Pin = LED3_Pin;
    GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
    GPIO_InitStruct.Pull = GPIO_PULLUP;
    HAL_GPIO_Init(LED3_GPIO_Port, &GPIO_InitStruct);
}

        另外一种模式就是PWM控制模式的初始化,这一部分我们是通过STM32CubeMX生成的,切换模式的时候直接使用系统生成的函数就可以,注意一点就是STM32CubeMX对引脚配置只能是一种,所以要想切换只能手动写一下。

        接下来就是模式的切换,通过外部中断实现:

void HAL_GPIO_EXTI_Falling_Callback(uint16_t GPIO_Pin)
{
  if(GPIO_Pin == B1_Pin)
  {/* KEY */
      LED.Mode_Dis++;
      if(LED.Mode_Dis>=4)
          LED.Mode_Dis = 0;
  }
}

        重点是在定时器中对LED中间太的控制:

void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
  if (htim->Instance == TIM16) {
    HAL_IncTick();

    switch(LED.Mode_OidDis)
    {
        case 0:
            LED.TIMcnt++;
            if(LED.TIMcnt>100){
                LED.TIMcnt = 0;
                LEDRed_off;
                LEDBlue_off;
                LEDGreen_off;
                LED.state ++;
                switch(LED.state%3){
                    case 0:
                        LEDRed_on;
                        break;
                    case 1:
                        LEDBlue_on;
                        break;
                    case 2:
                        LEDGreen_on;
                        break;
                    default:
                        break;
                }
            }
            break;

        case 1:
            LED.TIMcnt++;
            if(LED.TIMcnt>100){
                LED.TIMcnt = 0;
                LEDRed_Toggle;
                LEDBlue_Toggle;
                LEDGreen_Toggle;
            }
            break;

        case 2:
            LED.PWMcnt ++;
            if(LED.PWMcnt<100){
                __HAL_TIM_SET_COMPARE(&htim1,TIM_CHANNEL_1,LED.PWMcnt*50);
                __HAL_TIM_SET_COMPARE(&htim1,TIM_CHANNEL_3,LED.PWMcnt*50);
                __HAL_TIM_SET_COMPARE(&htim3,TIM_CHANNEL_2,LED.PWMcnt*50);
            }
            else if(LED.PWMcnt>=100 && LED.PWMcnt<200){
                __HAL_TIM_SET_COMPARE(&htim1,TIM_CHANNEL_1,(200-LED.PWMcnt)*50);
                __HAL_TIM_SET_COMPARE(&htim1,TIM_CHANNEL_3,(200-LED.PWMcnt)*50);
                __HAL_TIM_SET_COMPARE(&htim3,TIM_CHANNEL_2,(200-LED.PWMcnt)*50);
            }
            else
                LED.PWMcnt = 0;

            break;

        case 3:
            LED.PWMcnt ++;
            if(LED.PWMcnt<100){
                __HAL_TIM_SET_COMPARE(&htim1,TIM_CHANNEL_1,LED.PWMcnt*50);
            }
            else if(LED.PWMcnt>=100 && LED.PWMcnt<200){
                __HAL_TIM_SET_COMPARE(&htim1,TIM_CHANNEL_1,(200-LED.PWMcnt)*50);
            }
            else if(LED.PWMcnt>=200 && LED.PWMcnt<300){
                __HAL_TIM_SET_COMPARE(&htim1,TIM_CHANNEL_3,(LED.PWMcnt-200)*50);
            }
            else if(LED.PWMcnt>=300 && LED.PWMcnt<400){
                __HAL_TIM_SET_COMPARE(&htim1,TIM_CHANNEL_3,(400-LED.PWMcnt)*50);
            }
            else if(LED.PWMcnt>=400 && LED.PWMcnt<500){
                __HAL_TIM_SET_COMPARE(&htim3,TIM_CHANNEL_2,(LED.PWMcnt-400)*50);
            }
            else if(LED.PWMcnt>=500 && LED.PWMcnt<600){
                __HAL_TIM_SET_COMPARE(&htim3,TIM_CHANNEL_2,(600-LED.PWMcnt)*50);
            }
            else
                LED.PWMcnt = 0;
            break;

        default:
            break;
    }
  }
}

        效果如下:

板载LED多样模式控制.gif




关键词: STM32WBA55CG     PWM     LED    

专家
2024-12-23 08:42:15     打赏
2楼

谢谢分享


共2条 1/1 1 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]