• STM32 PWM配置及呼吸灯


            PWM的英文全称是"Pulse Width Modulation"中文翻译为"脉冲宽度调制"

            在PWM中可以调节的其实只有两个东西一个叫做可调周期(调频率)另一个叫做占空比(高电平/周期)。

            而呼吸灯其实就是改变流经二极管的平均电流也就是说当周期一定的情况下流经二极管的高电平发生改变。

            反之,倒回去,灯就会由暗变亮。 

            由此可以看出其周期不需要改变,只需要改变其占空比。

            我们假设LED灯在PA1上,那么我们需要配置两个东西,一个是GPIO_PA1一个是TIM2_PWM。所以我们要注意PA口的时钟,和TIM2挂在哪个总线上,需要先把这两个外设时钟打开。

            查看STM32F103xx performance line block diagram(性能线路框图)

             可以看到GPIOA挂到了APB2上,TIM2挂到了APB1上。所以我们做的第一件事就是开启GPIOA和TIM2的时钟。

            打开库函数手册

     

     //1.打开外设时钟

    1. void TIM2_PWM_Configarution(void)
    2. {
    3. RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
    4. RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
    5. }

            从STM32F103xx pin definitions可以看到PA1有个复用功能TIM2_CH2。我们要把GPIOA_Pin_1配置成复用功能。

     //2.配置GPIO口

    1. void TIM2_PWM_Configarution(void)
    2. {
    3. GPIO_InitTypeDef GPIO_InitStructure;
    4. RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
    5. RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
    6. GPIO_InitStructure.GPIO_Pin=GPIO_Pin_1;
    7. GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
    8. GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP;
    9. GPIO_Init(GPIOA,&GPIO_InitStructure);
    10. }

    //3.设置周期

    1. void TIM2_PWM_Configarution(void)
    2. {
    3. RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
    4. RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
    5. GPIO_InitTypeDef GPIO_InitStructure;
    6. TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
    7. GPIO_InitStructure.GPIO_Pin=GPIO_Pin_1;
    8. GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
    9. GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP;
    10. GPIO_Init(GPIOA,&GPIO_InitStructure);
    11. TIM_TimeBaseStructure.TIM_Period = 19999;
    12. TIM_TimeBaseStructure.TIM_Prescaler = 71;
    13. //TIM_TimeBaseStructure.TIM_ClockDivision = 0x0;
    14. TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
    15. TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);
    16. }

            PWM工作的时候,有一个中间的比较值,例如PWM的计数是从0~100,设置中间比较值为50。假设现在值是1,它就会和50比较,因为它是向上计数,所以1++变为2,当增加到比较值的时候,电平会发生改变。而模式1和模式2就是决定初始的电平。

    如果是PWM1模式

    a)如果设置TIM_OCPolarity_High:

    TIMx_CNT

    TIMx_CNT>TIMx_CCR输出为低电平

    b)如果设置TIM_OCPolarity_Low:

    TIMx_CNT

    TIMx_CNT>TIMx_CCR输出为高电平

    如果是PWM2模式

    a)如果设置TIM_OCPolarity_High:

    TIMx_CNT

    TIMx_CNT>TIMx_CCR输出为高电平

    b)如果设置TIM_OCPolarity_Low:

    TIMx_CNT

    TIMx_CNT>TIMx_CCR输出为低电平

    //4.输出比较功能 

    1. void TIM2_PWM_Configarution(void)
    2. {
    3. RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
    4. RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
    5. GPIO_InitTypeDef GPIO_InitStructure;
    6. TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
    7. TIM_OCInitTypeDef TIM_OCInitStructure;
    8. GPIO_InitStructure.GPIO_Pin=GPIO_Pin_1;
    9. GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
    10. GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP;
    11. GPIO_Init(GPIOA,&GPIO_InitStructure);
    12. TIM_TimeBaseStructure.TIM_Period = 19999;
    13. TIM_TimeBaseStructure.TIM_Prescaler = 71; //71+1= 72·ÖƵ
    14. //TIM_TimeBaseStructure.TIM_ClockDivision = 0x0;
    15. TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
    16. TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);
    17. TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
    18. TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
    19. TIM_OCInitStructure.TIM_OutputState = TIM_OutputNState_Enable;
    20. TIM_OC2Init(TIM2, & TIM_OCInitStructure);
    21. TIM_Cmd(TIM2, ENABLE);
    22. }

     main.c

    1. #include "bsp_SysTick.h"
    2. #include "bsp_tim2.h"
    3. int main(void)
    4. {
    5. int i;
    6. SysTick_Configuration();
    7. TIM2_PWM_Configuration();
    8. while(1)
    9. {
    10. for(i = 0; i < 20000; i++)
    11. {
    12. TIM_SetCompare2(TIM2, i);
    13. Delay_us(50);
    14. }
    15. for(i = 20000; i>0; i--)
    16. {
    17. TIM_SetCompare2(TIM2, i);
    18. Delay_us(50);
    19. }
    20. }
    21. }

  • 相关阅读:
    lombok的介绍
    正则表达式
    存内计算技术在边缘计算、物联网设备中的应用及前景
    ArduinoUNO实战-第二十一章-通过调整电位器来改变9克舵机的角度
    go-zero微服务实战系列(四、CRUD热热身)
    使用跨平台的visual studio code 进行python 开发
    [附源码]计算机毕业设计JAVA基于新高考模式下的排课系统
    软件项目质量管理体系,软件评审,资质认证,安全建设及项目管理匹配资料(原件参考)
    高德地图 web js端 出现 INVALID_USER_SCODE 10008 MD5安全码未通过验证
    P1058 [NOIP2008 普及组] 立体图
  • 原文地址:https://blog.csdn.net/m0_73671341/article/details/134023968