做一件事情之前,我们首先肯定是要了解这个东西是什么。我们才能去对它进行开发。
一、pwm原理
PWM是Pulse Width Modulation的缩写,
中文名字是脉冲宽度调制,一种说法是它利用微处理器的数字输出来对模拟电路进行控制的一种有效的技术,其实就是使用数字信号达到一个模拟信号的效果
我们可以看一下下面这张图,就可以很好的去理解pwm,其实就是占空比。
占空比是指高电平的时间占整个周期的比例。
说白了,其实就是高电平所占的周期时间
理解了原理之后,我们要如何应用呢?
其实pwm哎我们生活中到处都是,比如风扇调速、手机充电呼吸灯等等。
二、基本控制
stm32的定时器除了TIM6和7。其他的定时器都可以用来产生PWM输出。其中高级定时器TIM1和TIM8可以同时产生7路的PWM输出。而通用定时器也能同时产生多达4路PWM输出,这样,stm32最多可以同时产生30路PWM输出;要使用STM32下的通用定时器TIMx产生PWM输出,我们会用到3个寄存器,来控制PWM的。这三个寄存器是:捕获/比较模式寄存器TIMx_CCMR1/2)、捕获/比较使能寄存器(TIMx_CCER)、捕获/比较寄存器(TIMx_CCR1~4)。注意,还有个TIMx的ARR寄存器是用来控制PWM输出频率的。
初始化设置:
void RCC_Config(void);
void GPIO_Config(void);
void TIM_Config(void);
void RCC_Config(void)
{
//使能GPIOA,TIM2
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);
}
void GPIO_Config(void)
{
//GPIO的配置,官方库有给出需要配置的一些参数,如果忘记了,参照一下即可,我这里配置的是GPIOA_Pin_1
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_1;
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_Init(GPIOA,&GPIO_InitStructure);
}
void TIM_Config(void)
{
TIM_TimeBaseInitTypeDef TIM_TImeBaseStructure;
TIM_OCInitTypeDef TIM_OCInitStructure;
//配置TIM2的时钟输出频率,以及其它相关参数初始化
TIM_TImeBaseStructure.TIM_Prescaler=360-1;//设置PWM的频率
TIM_TImeBaseStructure.TIM_CounterMode=0;
TIM_TImeBaseStructure.TIM_Period=100;
TIM_TimeBaseInit(TIM2,&TIM_TImeBaseStructure);
//设置PWM的输出方式
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2;
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Enable;
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_High;
TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Set;
TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCIdleState_Reset;
//配置占空比
TIM_OCInitStructure.TIM_Pulse=50;
TIM_OC2Init(TIM2,&TIM_OCInitStructure);
TIM_ForcedOC1Config(TIM2,TIM_ForcedAction_Active);
TIM_Cmd(TIM2,ENABLE);
TIM_CtrlPWMOutputs(TIM2,ENABLE);
}
整个mian函数:
int main()
{
RCC_Config();
GPIO_Config();
TIM_Config();
while(1)
{
;
}
}
pwm.c
#include "pwm.h"
#include "public.h"
/*******************************************************************************
* ? ? ? : pwm_init
* ???? : IO???TIM3?????
* ? ? : ?
* ? ? : ?
*******************************************************************************/
void pwm_Init()
{
GPIO_InitTypeDef GPIO_InitStructure; //?????????,?????GPIO
TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;//?????????,????????
TIM_OCInitTypeDef TIM_OCInitStructure;//??TIM_OCInitStruct???????????TIMx
/* ???? */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC,ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);
/* ??GPIO????IO? */
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_6;// PC6
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP;//??????
GPIO_Init(GPIOC,&GPIO_InitStructure);
//TIM3??????
TIM_TimeBaseInitStructure.TIM_Period = 199; //PWM ??=72000/(199+1)=36Khz//??????????????
TIM_TimeBaseInitStructure.TIM_Prescaler = 7199;//??????TIMx????????
TIM_TimeBaseInitStructure.TIM_ClockDivision = 0;//??????:TDTS = Tck_tim
TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up; //TIM??????
TIM_TimeBaseInit(TIM3,&TIM_TimeBaseInitStructure);
GPIO_PinRemapConfig(GPIO_FullRemap_TIM3,ENABLE);//????????? //pC6
//PWM??? //??TIM_OCInitStruct???????????TIMx
TIM_OCInitStructure.TIM_OCMode=TIM_OCMode_PWM1;
TIM_OCInitStructure.TIM_OutputState=TIM_OutputState_Enable;//PWM????
TIM_OCInitStructure.TIM_OCPolarity=TIM_OCPolarity_Low;
TIM_OC1Init(TIM3,&TIM_OCInitStructure);
//????????TIM_OC1Init???TIM_OCInit,??????????????????
TIM_OC1PreloadConfig(TIM3, TIM_OCPreload_Enable);//??????TIMx?CCR1????????
TIM_Cmd(TIM3,ENABLE);//??????TIMx??
}
pwm.h
#ifndef __PWM_H
#define __PWM_H
void pwm_Init(void);
#endif
自此完成基本配置,下面我将再写一篇应用开发。更新有点慢,见谅。
参考链接