STM32输出PWM信号(库函数版本)

6 篇文章 0 订阅
5 篇文章 0 订阅

什么是PWM信号?

官方解释:PWM信号一般指脉冲宽度调制。脉冲宽度调制是一种模拟控制方式,根据相应载荷的变化来调制晶体管基极或MOS管栅极的偏置,来实现晶体管或MOS管导通时间的改变,从而实现开关稳压电源输出的改变。这种方式能使电源的输出电压在工作条件变化时保持恒定,是利用微处理器的数字信号对模拟电路进行控制的一种非常有效的技术。

相信大家都会很努力的看完它吧。作为一个学习糟糕的大学生,我一般都不看这种官方的解释,我认为的PWM信号就是一种占空比可调的方波,什么又是占空比呢?不知道就去百度吧。懒得百度我也可以告诉你,占空比就是在一个脉冲周期内,高电平持续的时间占总时间的比例。嗯,这下应该知道PWM是什么了吧。

STM32输出PWM信号

STM32 的定时器除了 TIM6 和 7。其他的定时器都可以用来产生 PWM 输出。其中高级定
时器 TIM1 和 TIM8 可以同时产生多达 7 路的 PWM 输出。而通用定时器也能同时产生多达 4
路的 PWM 输出,这样,STM32 最多可以同时产生 30 路 PWM 输出!(cope过来的)由于资源和时间有限,所以我这里拿STM32F103来做这个信号的输出。emmmm,这边我用TM3的CH2输出一路PWM。

首先说的是控制寄存器 1(TIMx_CR1),它的样子大概是这样的:

TIMx_CR1
在这里插入图片描述在这里插入图片描述
位15:10:是6个保留位,始终读为0。
CKD[1:0]:定时器时钟频率在数字滤波器使用的采样频率之间的分频比例。(总的来说就是分频系数)。
ARPE:自动重装载预装载的允许位。
CMS:选择中央对齐模式。
DIR:控制计数器的计算方向。
OPM:单脉冲模式。
URS:更新请求源位。
UDIS:禁止(允许)更新位。
CEN:禁止(使能)计数器。

接着是第二个寄存器:状态寄存器(TIMx_SR),该寄存器用来标记当前与定时
器相关的各种事件/中断是否发生。

在这里插入图片描述
CC4OF:捕获/比较4重复捕获标记。
CC3OF:捕获/比较3重复捕获标记。
CC2OF:捕获/比较2重复捕获标记。
CC1OF:捕获/比较1重复捕获标记,仅当相应的通道被配置为输入捕获时,该标记可由硬件置’1’。写’0’可清除该位。
TIF:触发器中断标记,当发生触发事件(当从模式控制器处于除门控模式外的其它模式时,在TRGI输入端检测到有效边沿,或门控模式下的任一边沿)时由硬件对该位置’1’。它由软件清’0’。
CC4IF:捕获/比较4 中断标记。
CC3IF:捕获/比较3 中断标记。
CC2IF:捕获/比较2 中断标记。
CC1IF:捕获/比较1 中断标记。
UIF:更新中断标记。

这个寄存器前面那些什么标记啊什么都不用管,这里主要是了解UIF这一位,当产生更新事件时该位由硬件置’1’。它由软件清’0’。也就是说它为0时是无中断产生的。

了解了上面寄存器的配置就可以对定时器进行配置了,但要想实现PWM的输出,还有另外几个寄存器需要配置。

第一个是是捕获/比较模式寄存器(TIMx_CCMR1/2),该寄存器总共有 2 个,TIMx _CCMR1
和 TIMx _CCMR2。TIMx_CCMR1 控制 CH1 和 CH2 ,而 TIMx_CCMR2 控制 CH3 和 CH4 。

TIMx_CCMR1/2

他有两个模式,所以在不同模式下同一个位可能会有不同的作用。这里我们只需要配置OCxM(至于是1还是2就要看你使用的PWM模式是1还2了)。我们使用的是 PWM 模式,所以这 3 位必须设置为 110/111。这两种主要就是输出极性相反。

接着是捕获/比较使能寄存器(TIMx_CCER),该寄存器控制着各个输入输出通道的开关。

TIMx_CCER

这里我们只用到了 CC2E 位,该位是输入/捕获 2 输出使能位,要想PWM 从 IO 口输出,这个位必须设置为 1,所以我们需要设置该位为 1。

最后是捕获/比较寄存器(TIMx_CCR1~4),该寄存器总共有 4 个,对应 4 个
输通道 CH1~4。我这里只有TIMx_CCR1的图,其实它里面都是一样的:

TIMx_CCR1

在输出模式下,该寄存器的值与 CNT 的值比较,根据比较结果产生相应动作。利用这点,我们通过修改这个寄存器的值,就可以控制 PWM 的输出脉宽了。

如果要用到重映射的功能还需要配置复用重映射和调试 IO 配置寄存器(AFIO_MAPR)

AFIO_MAPR

因为我不用这个功能,所以我就不配置了。

代码实现

接下来就是代码实现了,首先呢,是开启TIM3的时钟和PA7的时钟:

	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);

因为TIM3是在APB1总线上,所以TIM3的时钟初始化要使用RCC_APB1PeriphClockCmd()函数,PA7是在APB2总线上的。接着是对PA7的配置:

	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7; 
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; 
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOA, &GPIO_InitStructure);

对TIM3的配置:

	TIM_TimeBaseStructure.TIM_Period = arr;
	TIM_TimeBaseStructure.TIM_Prescaler =psc; 
	TIM_TimeBaseStructure.TIM_ClockDivision = 0; //不分频
	TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //向上计数
	TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); 

	TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2; //模式2
	TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;//输出比较使能
	TIM_OCInitStructure.TIM_Pulse = 0; //设置待装入捕获比较寄存器的脉冲值
	TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;//输出比较极性高
	TIM_OC1Init(TIM3, &TIM_OCInitStructure);  

使能输出:

	TIM_CtrlPWMOutputs(TIM3,ENABLE);	//MOE 主输出使能
	TIM_OC2PreloadConfig(TIM3, TIM_OCPreload_Enable);  //CH2预装载使能	
	TIM_ARRPreloadConfig(TIM3, ENABLE); //TIM3使能
	TIM_Cmd(TIM3, ENABLE); 

以上就配置完了PWM的输出,至于占空比的设置,这里有一个函数可以调节占空比:
void TIM_SetCompare2(TIM_TypeDef* TIMx, uint16_t Compare2)这个函数在stm32f10x_tim.c文件中,如果设置成这样TIM_SetCompare2(TIM3, 0)则会输出3.3V,好了PWM的输出就到这里了。谢谢大家的观看。

下面是完整的代码:

void TIM3_CH2_PWM_Init(u16 arr,u16 psc){
	GPIO_InitTypeDef GPIO_InitStructure;
	TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
	TIM_OCInitTypeDef  TIM_OCInitStructure;
	
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
	
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7; 
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; 
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOA, &GPIO_InitStructure);
	
	TIM_TimeBaseStructure.TIM_Period = arr;
	TIM_TimeBaseStructure.TIM_Prescaler =psc; 
	TIM_TimeBaseStructure.TIM_ClockDivision = 0; 
	TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; 
	TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); 
	
	TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2; 
	TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
	TIM_OCInitStructure.TIM_Pulse = 0; 
	TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
	TIM_OC1Init(TIM3, &TIM_OCInitStructure);  
	
	TIM_CtrlPWMOutputs(TIM3,ENABLE);	
	TIM_OC2PreloadConfig(TIM3, TIM_OCPreload_Enable);  
	TIM_ARRPreloadConfig(TIM3, ENABLE); 
	TIM_Cmd(TIM3, ENABLE); 
}
  • 14
    点赞
  • 43
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值