stm32 PWM

脉冲宽度调制是利用微处理器的数字输出来对模拟电路进行控制的一种非常有效的技术

1

高级定时器可以同时产生多达7路的PWM输出
而通用定时器也能同时产生多达4路的PWM输出

脉冲宽度调制模式可以产生一个由TIMx_ARR寄存器确定频率、由TIMx_CCRx寄存器确定占空比的信号

2

PWM边沿对齐模式
1

当TIMx_CNT小于TIMx_CCRx时PWM信号参考OCxREF为高,否则为低。如果TIMx_CCRx中的比较值大于自动重装载值(TIMx_ARR),则OCxREF保持为’1’。如果比较值为0,则OCxREF保持为’0’。 下图为TIMx_ARR=8时边沿对齐的PWM波形实例

3

3.PWM配置步骤

1.使能定时器时钟
2.使能GPIO外设时钟,并设置引脚复用
3.使能AFIO时钟,并设置引脚复用重映射
3.初始化定时器参数,预分频器的值、自动重装载的值等设定
4.初始化PWM输出参数,输出模式、输出极性等
5.开启定时器
6.使能捕获/比较模式寄存器(TIMx_CCMRx)
7.使能自动重装载寄存器(TIMx_ARR)
8.配置捕获/比较寄存器,修改占空比(TIMx_CCRx)

举例
4

typedef struct
{
    uint16_t TIM_OCMode; //输出比较模式
    uint16_t TIM_OutputState; //输入/捕获输出使能
    uint16_t TIM_OutputNState; //比较互补输出使能
    uint16_t TIM_Pulse; //配置捕获/比较寄存器值
    uint16_t TIM_OCPolarity; //输入/捕获输出极性
    uint16_t TIM_OCNPolarity; //互补比较输出极性
    uint16_t TIM_OCIdleState; //空闲状态下比较输出状态
    uint16_t TIM_OCNIdleState; //空闲状态下比较输出状态
} TIM_OCInitTypeDef;

void TIM3_PWM_init(u16 prescaler, u16 period)
{
    TIM_TimeBaseInitTypeDef tim_tb = {0};
    TIM_OCInitTypeDef tim_oc = {0};
    GPIO_InitTypeDef gpio = 
    {
        GPIO_Pin_6, //PC6
        GPIO_Speed_50MHz,
        GPIO_Mode_AF_PP //复用推挽输出
    };

    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); //使能定时器时钟

    GPIO_Init(GPIOC, &gpio); //使能GPIO外设时钟,并设置引脚复用

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE); //使能AFIO时钟

    GPIO_PinRemapConfig(GPIO_FullRemap_TIM3, ENABLE); //设置引脚复用重映射

    tim_tb.TIM_Prescaler = prescaler;
    tim_tb.TIM_CounterMode = TIM_CounterMode_Up;
    tim_tb.TIM_Period = period;
    tim_tb.TIM_ClockDivision = TIM_CKD_DIV1;
    TIM_TimeBaseInit(TIM3, &tim_tb); //初始化定时器参数

    tim_oc.TIM_OCMode = TIM_OCMode_PWM1; //PWM模式1
    tim_oc.TIM_OCPolarity = TIM_OCPolarity_Low; //低电平有效
    tim_oc.TIM_OutputState = TIM_OutputState_Enable;
    TIM_OC1Init(TIM3, &tim_oc); //初始化PWM输出参数

    TIM_Cmd(TIM3, ENABLE); //开启定时器

    TIM_OC1PreloadConfig(TIM3, TIM_OCPreload_Enable); //使能捕获/比较模式寄存器

    TIM_ARRPreloadConfig(TIM3, ENABLE); //使能自动重装载寄存器
}

int main(void)
{
    u16 i = 0;
    u8 flag = 0;

    TIM3_PWM_init(500, 72 - 1); //2k

    while(1)
    {
        if(flag == 0)
        {
            i++;
            if(i == 300)
            {
                flag = 1;
            }
        }
        else
        {
            i--;
            if(i == 0)
            {
                flag = 0;
            }
        }

        TIM_SetCompare1(TIM3, i); //配置捕获/比较寄存器,修改占空比

        delay_ms(10);
    }
}
原文地址:https://www.cnblogs.com/zhangxuechao/p/11709574.html