PWM脉冲宽调点灯
前言
对于灯等来说有很多种方法,前面介绍了一些基础的点灯方法,比如直接点灯,按键控制点灯,按键中断点灯,但都是比较简单的一些方法也很基础,要问我有没有什么高级点的点灯方法,答案是有的,在这我要介绍一种高级点灯的方法就是使用PWM进行点灯。
1.什么是PWM
PWM是脉冲宽度调制,简称脉冲宽调。它利用微处理器的数字输出来对模拟电路进行控制的一种非常有效的技术。
PWM一般用在测量、通讯、功率控制雨转换,电动机控制、调光、开关电源,但是在这我们只研究点灯,点灯才是重中之重。
2.PWM的实现
PWM是基于定时器来进行实现的,但并不是所有的定时器都能实现PWM的,比如说基本定时器就没有办法实现PWM,所以下面的PWM是用通用定时器和高级定时器来进行实现的。
其实PWM的实现是非常的简单,其实和定时器一样,定时器到0或者是到设置的最大值就会触发中断,PWM也是,只不过它并不是到达最大值,也不触发中断,它是到达你设置的那个比较值后就进行翻转电平,例如我的PWM的自动重载值为2000,比较值为1000
当计数到1000的时候PWM就会进行一次电平的翻转,比如你一开始设置的电平是高电平,那等到到比较值的时候就会变成低电平。
3.PWM实现步骤(通用定时器)
前面说了,PWM和定时器一样,所以开启PWM的方式前面和打开定时器的方式一样,但是有一点不同的是PWM要使用到所对应的端口上,所以需要加上一般就是设置端口:
-
打开定时器时钟
-
配置端口
-
配置TIM定时器
-
使能TIM外设
按照上面的步骤完成后就得开始配置PWM了,配置的方法如下:
- 配置PWM
- 使能预装寄存器
这样就可以让PWM进行使用了,现在来一个一个的介绍打开的步骤。
3.1 打开定时器的时钟
打开时钟这个是必须要的内容,而在打开时钟的时候需要注意你使用的定时器,如果你使用的是通用定时器,一般都是打开APB1的时钟,而高级定时器一般是APB2,这个需要考虑一下。
如果我这是使用的TIM3的定时器,那么打开的时钟代码如下:
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
如果这里使用TIM1,代码如下:
RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE);
3.2 配置端口
配置端口的步骤和之前配置端口的步骤一致,只不过需要注意一下这个端口的模式需要使用GPIO_Mode_AF_PP
复用推挽输出的方式,因为有些端口是使用重映射到这个端口的,此时这个端口是属于复用功能输出,所以这里需要使用到复用的方式。
那什么时候需要使用到重映射呢?这里需要知道一下,我们现在使用的PWM是PWM的输出模式,所以需要知道开启这个PWM定时器的输出端口。
下面的表说明了通用定时器和高级定时器通道输出所对应的端口:
TIM2定时器 | 未重映射 | 部分重映射 |
---|---|---|
TIM2_CH1 | PA0 | PA15 |
TIM2_CH2 | PA1 | PB3 |
TIM2_CH3 | PA2 | PB10 |
TIM2_CH4 | PA3 | PB11 |
TIM3定时器 | 未重映射 | 部分重映射 | 重映射 |
---|---|---|---|
TIM3_CH1 | PA6 | PB4 | PC6 |
TIM3_CH2 | PA7 | PB5 | PC7 |
TIM3_CH3 | PB0 | PB0 | PC8 |
TIM3_CH4 | PB1 | PB1 | PC9 |
TIM4定时器 | 未重映射 | 重映射 |
---|---|---|
TIM4_CH1 | PB6 | PD12 |
TIM4_CH2 | PB7 | PD13 |
TIM4_CH3 | PB8 | PD14 |
TIM4_CH4 | PB9 | PD15 |
TIM5定时器 | 未重映射 | 重映射 |
---|---|---|
TIM5_CH4 | PA3 | LSI内部时钟连至TIM5_CH4的输入作为校准使用 |
TIM1定时器 | 未重映射 | 部分重映射 | 重映射 |
---|---|---|---|
TIM1_ETR | PA12 | PA12 | PE7 |
TIM1_CH1 | PA8 | PA8 | PE9 |
TIM1_CH2 | PA9 | PA9 | PE11 |
TIM1_CH3 | PA10 | PA10 | PE13 |
TIM1_CH4 | PA11 | PA11 | PE14 |
上面只介绍了部分定时器输出的重映射,更多的大家可以翻阅一下手册,上面的只是一个简单的参考。
知道了定时器输出引脚后我们需要选择定时器然后配置定时器所对应的输出引脚。
这里我使用的是PA6这个引脚,所以使用的是TIM3
这个定时器,配置的代码如下:
GPIO_InitTypeDef GPIO_InitStruct = {0};
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); // 打开GPIOA的时钟
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP; // 设置复用推挽输出
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_6;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStruct);
3.3 设置定时器
设置完端口后就可以开始设置定时器了,设置定时器的方法和之前打开基本定时器的方法一样。
TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct = {0};
TIM_TimeBaseInitStruct.TIM_CounterMode = TIM_CountterMode_Up; // 设置定时器计数模式为上拉
TIM_TimeBaseInitStruct.TIM_Period = 20000 - 1; // 自动重装值为20000
TIM_TimeBaseInitStruct.TIM_Prescaler = 7200 - 1; // 预分系数,72MHz/7200
TIM_TimeBaseInitStruct.TIM_ClockDivision = 0; // 时钟分割
TIM_TimeBaseInit(TIM3, &TIM_TimeBaseInitStruct);
3.4 设置PWM
前面设置完TIM3定时器了,现在就是想要配置一下PWM了。
TIM_OCInitTypeDef TIM_OCInitStruct = {0};
TIM_OCInitStruct.TIM_OCMode = TIM_OCMode_PWM1; // 打开PWM通道1 因为这里使用的是TIM3的通道一作为PWM
TIM_OCInitStruct.TIM_OutputState = TIM_OutputState_ENABLE; // PWM输出使能
TIM_OCInitStruct.TIM_OCPolarity = TIM_OCNPolarity_Low; // 一开始输出的电平,如果为低,那到达比较值后就为高。
T