stm32f103c8t6外设——通用定时器PWM模式及IO复用实现呼吸灯

一、通用定时器

通用计数器可以实现输入捕获、输出捕获、定时器级联(一个定时器作为另一个定时器的预分频器)、中断等。

本实验通过输出捕获实现PWM波,PWM1与PWM2模式输出相反(本文以PWM1模式为例)。

二、PWM模式配置

本实验将PB5重映射为TIM3_CH2(IO复用)。

1、gtim.h文件

(1)初始化TIM3为向上计数模式

TIM_HandleTypeDef g_timx_pwm_chy_handle;

/* 通用定时器PWM输出初始化函数 */

void gtim_timx_pwm_chy_init(uint16_t psc,uint16_t arr)

{

    g_timx_pwm_chy_handle.Instance = TIM3;

    g_timx_pwm_chy_handle.Init.Prescaler = psc;

    g_timx_pwm_chy_handle.Init.Period = arr;

g_timx_pwm_chy_handle.Init.CounterMode = TIM_COUNTERMODE_UP;    /* 向上计数模式 */

}

(2)定时器输出PWM MSP初始化函数

/* 定时器输出PWM MSP初始化函数 */

/* 1、使能TIM时钟;2、使能IO时钟及引脚复用. */

void HAL_TIM_PWM_MspInit(TIM_HandleTypeDef *htim)

{

    if(htim->Instance == TIM3)

    {

        GPIO_InitTypeDef g_init_struct;

   

        __HAL_RCC_GPIOB_CLK_ENABLE();

        __HAL_RCC_TIM3_CLK_ENABLE();

       

        g_init_struct.Pin = GPIO_PIN_5;

        g_init_struct.Mode = GPIO_MODE_AF_PP;               /* 推挽复用功能 */

        g_init_struct.Pull = GPIO_PULLUP;                   /* 上拉 */

        g_init_struct.Speed = GPIO_SPEED_FREQ_HIGH;         /* 高速 */

        HAL_GPIO_Init(GPIOB, &g_init_struct);

       

        __HAL_RCC_AFIO_CLK_ENABLE();                        /* 复用IO时钟使能 */

        __HAL_AFIO_REMAP_TIM3_PARTIAL();                    /* 部分复用使能 */

    }

}

__HAL_AFIO_REMAP_TIM3_PARTIAL();                    /* 部分复用使能 */

(3)在(1)函数体中继续配置PWM模式、比较值(初始占空比)及极性,配置TIM3通道2,开启对应PWM通道。

void gtim_timx_pwm_chy_init(uint16_t psc,uint16_t arr)

{

TIM_OC_InitTypeDef timx_oc_pwm_chy;



    timx_oc_pwm_chy.OCMode = TIM_OCMODE_PWM1;                       /* 模式选择PWM1 */

    timx_oc_pwm_chy.Pulse = arr / 2;                                /* 设置比较值CCRx,此值用来确定占空比 */

                                                                    /* 这里默认设置比较值为自动重装载值的一半,即占空比为50% */

    timx_oc_pwm_chy.OCPolarity = TIM_OCPOLARITY_LOW;                /* 设定CCxP的值,低电平有效 */

    HAL_TIM_PWM_ConfigChannel(&g_timx_pwm_chy_handle,&timx_oc_pwm_chy, TIM_CHANNEL_2);   /* 配置TIM3通道2 */

    HAL_TIM_PWM_Start(&g_timx_pwm_chy_handle, TIM_CHANNEL_2);       /* 开启对应PWM通道 */





}

2、main.c文件

(1) __HAL_TIM_SET_COMPARE()修改比较值控制占空比。

#include "./SYSTEM/sys/sys.h"
#include "./SYSTEM/usart/usart.h"
#include "./SYSTEM/delay/delay.h"
#include "./BSP/LED/led.h"
#include "./BSP/KEY/key.h"
#include "./BSP/TIMER/gtim.h"

extern TIM_HandleTypeDef g_timx_pwm_chy_handle;

int main(void)
{
    uint32_t ledpwmval = 0;
    uint8_t dir = 1;
    
    HAL_Init();                                             /* 初始化HAL库 */
    sys_stm32_clock_init(RCC_PLL_MUL9);                     /* 设置时钟, 72Mhz */
    delay_init(72);                                         /* 延时初始化 */
    usart_init(115200);                                     /* 初始化串口 */
    gtim_timx_pwm_chy_init(72 - 1, 500 - 1);

    printf("程序开始:
");
    while(1)
    { 
        delay_ms(10);
        
        /* 根据方向修改ledpwmval */
        if (dir == 1)
        {
            ledpwmval++;
        }
        else
        {
            ledpwmval--;
        }
        
        /* 当ledpwmval大于500时,方向改为递减 */
        if (ledpwmval > 500)
        {
            dir = 0;
        }
        
        /* 当ledpwmval等于0时,方向改为递增 */
        if (ledpwmval == 0)
        {
            dir = 1;
        }

        /* 修改比较值控制占空比 */
        __HAL_TIM_SET_COMPARE(&g_timx_pwm_chy_handle, TIM_CHANNEL_2, ledpwmval);
    }
}

三、PWM为什么能控制led灯或者电机的速度?

        原因是,PWM波形是具有一定占空比的矩形波,呈现高低电平交替的状态,频率较高,即波形周期较小。在高速变化过程中,led灯会呈现出一个平均亮度(人眼看出来的状态),通过不断改变PWM波的占空比,高低电平交替的速度会发生变化,此时这个平均亮度也会发生变化,故就可以通过改变PWM波的占空比以改变led灯的亮度,实现呼吸灯的效果。电机也相同,不再赘述。