stm32f4xx-PWM输出
文章目录
- 一、STM32PWM工作过程
- 二、库函数
- 1、GPIO引脚映射
- 2、定时器通道1配置
- 3、定时器通道1比较值
- 三、PWM1和PWM2模式
- 1、定义
- 2、PWM输出配置步骤:
- 四、test
一、STM32PWM工作过程
PWM(pulse width modulation)脉冲宽度调制
脉冲:方波,频率
宽度:高电平的宽度,占空比
占空比:0% 高电平一点都不占
占空比:25% 占1/4
占空比:50% 占1/2
占空比:75% 占3/4
占空比:100%
CCR1:捕获比较(值)寄存器(x=1,2,3,4):设置比较值。
CCMR1: OC1M[2:0]位:对于PWM方式下,用于设置PWM模式1【110】或者PWM模式2【111】
CCER:CC1P位:输入/捕获1输出极性。0:高电平有效,1:低电平有效。
CCER:CC1E位:输入/捕获1输出使能。0:关闭,1:打开。
二、库函数
1、GPIO引脚映射
2、定时器通道1配置
注意:
通道1:TIM_OC1Init(TIM_TypeDef* TIMx, TIM_OCInitTypeDef* TIM_OCInitStruct);
通道2:TIM_OC2Init(TIM_TypeDef* TIMx, TIM_OCInitTypeDef* TIM_OCInitStruct);
通道3:TIM_OC3Init(TIM_TypeDef* TIMx, TIM_OCInitTypeDef* TIM_OCInitStruct);
通道4:TIM_OC4Init(TIM_TypeDef* TIMx, TIM_OCInitTypeDef* TIM_OCInitStruct);
3、定时器通道1比较值
注意:
通道1:TIM_SetCompare1(TIM_TypeDef* TIMx, uint32_t Compare1);
通道2:TIM_SetCompare2(TIM_TypeDef* TIMx, uint32_t Compare2);
通道3:TIM_SetCompare3(TIM_TypeDef* TIMx, uint32_t Compare3);
通道4:TIM_SetCompare4(TIM_TypeDef* TIMx, uint32_t Compare4);
三、PWM1和PWM2模式
《STM32f4xx中文参考手册.pdf》477页
1、定义
PWM 模式 1——只要 TIMx_CNT(计数值)< TIMx_CCR1(捕获/比较值),通道 1 便为有效状态,否则为无效状态。
PWM 模式 2——只要 TIMx_CNT (计数值)< TIMx_CCR1(捕获/比较值),通道 1 便为无效状态,否则为有效状态
TIMx_CNT由TIM_TimeBaseStructure.TIM_Period决定
TIMx_CCR1由TIM_SetComparex(x:1 2 3 4);函数决定
有效状态由TIM_OCInitStructure.TIM_OCPolarity决定
频率值:由计数值决定
占空比:由比较值决定
2、PWM输出配置步骤:
四、test
呼吸灯
注意:高级定时器 tim1要TIM_CtrlPWMOutputs()使能
#include "stm32f4xx.h"
//e 13 tim1_ch3 14 tim1_ch4
void TIM1_UP_init(uint32_t arr,uint32_t psc)
{
#if 1
GPIO_InitTypeDef GPIO_InitStructure;
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_OCInitTypeDef TIM_OCInitStructure;
//使能GPIOE的硬件时钟
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOE , ENABLE);
//使能TIM1的硬件时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE);
GPIO_PinAFConfig(GPIOE,GPIO_PinSource13,GPIO_AF_TIM1);//GPIOE 13 复用为定时器1
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13 ; //GPIOE 13
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; //复用功能
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; //速度100MHz
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; //推挽复用输出
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; //上拉
GPIO_Init(GPIOE,&GPIO_InitStructure); //初始化GPIOE 13
TIM_TimeBaseStructure.TIM_Prescaler=psc; //定时器分频
//TIM_TimeBaseStructure.TIM_Period = (10000/100)-1; //计数值100hz/
//TIM_TimeBaseStructure.TIM_Prescaler = 16800-1; //预分频值 16800-1 + 1 = 16800
TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up; //向上计数模式
TIM_TimeBaseStructure.TIM_Period=arr; //自动重装载值
TIM_TimeBaseStructure.TIM_ClockDivision=TIM_CKD_DIV1;
TIM_TimeBaseInit(TIM1,&TIM_TimeBaseStructure);//初始化定时器1
//初始化TIM1 Channel3 PWM模式
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; //选择定时器模式:TIM脉冲宽度调制模式1
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比较输出使能
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low; //输出极性:TIM输出比较极性低
//TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //高电平有效状态,无效状态则为低电平
//TIM_OCInitStructure.TIM_Pulse = 250; //比较值
TIM_OC3Init(TIM1, &TIM_OCInitStructure); //根据T指定的参数初始化外设TIM1 OC1
TIM_OC3PreloadConfig(TIM1, TIM_OCPreload_Enable); //使能TIM1在CCR1上的预装载寄存器
TIM_ARRPreloadConfig(TIM1,ENABLE);//ARPE使能
TIM_CtrlPWMOutputs(TIM1, ENABLE);//tim1 pwm使能 ---------------------------------
//使能定时器1工作
TIM_Cmd(TIM1, ENABLE);
#else
//此部分需手动修改IO口设置
GPIO_InitTypeDef GPIO_InitStructure;
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_OCInitTypeDef TIM_OCInitStructure;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM14,ENABLE); //TIM14时钟使能
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOF, ENABLE); //使能PORTF时钟
GPIO_PinAFConfig(GPIOF,GPIO_PinSource9,GPIO_AF_TIM14); //GPIOF9复用为定时器14
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; //GPIOF9
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; //复用功能
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; //速度100MHz
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; //推挽复用输出
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; //上拉
GPIO_Init(GPIOF,&GPIO_InitStructure); //初始化PF9
TIM_TimeBaseStructure.TIM_Prescaler=psc; //定时器分频
TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up; //向上计数模式
TIM_TimeBaseStructure.TIM_Period=arr; //自动重装载值
TIM_TimeBaseStructure.TIM_ClockDivision=TIM_CKD_DIV1;
TIM_TimeBaseInit(TIM14,&TIM_TimeBaseStructure);//初始化定时器14
//初始化TIM14 Channel1 PWM模式
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; //选择定时器模式:TIM脉冲宽度调制模式2
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比较输出使能
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low; //输出极性:TIM输出比较极性低
TIM_OC1Init(TIM14, &TIM_OCInitStructure); //根据T指定的参数初始化外设TIM1 4OC1
TIM_OC1PreloadConfig(TIM14, TIM_OCPreload_Enable); //使能TIM14在CCR1上的预装载寄存器
TIM_ARRPreloadConfig(TIM14,ENABLE);//ARPE使能
TIM_Cmd(TIM14, ENABLE); //使能TIM14
#endif
}
int main(void)
{
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置系统中断优先级分组2
#if 1
TIM1_UP_init(500-1,168-1);//168M/168=1Mhz的计数频率,重装载值500,所以PWM频率为 1M/500=2Khz.
#else
TIM1_UP_init(500-1,84-1);//84M/84=1Mhz的计数频率,重装载值500,所以PWM频率为 1M/500=2Khz.
#endif
uint32_t led0pwmval=0;
uint8_t dir=1;
while(1) //实现比较值从0-300递增,到300后从300-0递减,循环
{
delay_xms(10);
if(dir)led0pwmval++;//dir==1 led0pwmval递增
else led0pwmval--; //dir==0 led0pwmval递减
if(led0pwmval>300)dir=0;//led0pwmval到达300后,方向为递减
if(led0pwmval==0)dir=1; //led0pwmval递减到0后,方向改为递增
#if 1
TIM_SetCompare3(TIM1,led0pwmval); //修改比较值,修改占空比
#else
TIM_SetCompare1(TIM14,led0pwmval); //修改比较值,修改占空比
#endif
}
}