STM32 定时器输出PWM 库函数

    PWM,即脉宽调制,也可称为占空比,在一个高低电平周期内,高电平所占总周期时长的比例,即为占空比。

    在单片机当中,通常使用定时器来产生所需的PWM波形。这个东西用途还是很广的,举个例子,不知道大家知不知道呼吸灯是什么,LED灯由灭慢慢增加亮度直到最亮,再慢慢降低亮度到完全熄灭,反复这一过程,即为呼吸灯效果。这里LED灯亮度的变化一般使用的就是PWM波控制,一般来讲,如果让一个LED灯以一个很快的速度进行亮灭亮灭循环,我们看到的LED就一直是亮的状态,具体有多亮,那就要看输出到LED的高电平占一个高低电平总时间的比例,这个比例就是占空比,通过调整这一比例,就可以控制LED的亮度,进而达到呼吸灯的效果。

    此外,PWM还有许多功能,例如PWM可以控制舵机的旋转角度,可以控制一些直流电机的旋转速度,以及通过PWM控制器,可以实现高效的电源转换等等功能。

    然后我们大概介绍一下定时器是怎么输出PWM波形的,定时器大家应该有所了解,定时器的主要功能就是计数,我们给定时器输入一个时钟,这个时钟每来一次,定时器里的值就加一,直到达到我们提前设置好的数值时,触发中断。当然,这只是一个最简单的描述,具体配置起来,还需要设置一些预分频值,重装值等等内容。PWM输出是定时器的一个功能,输出比较,简单来说,将定时器设置为输出比较功能后,我们需要给输出比较寄存器设置一个固定的值,这个输出比较寄存器每个定时器有四个,我们需要几个设置几个,定时器经过时钟分配后的值最终会保存到一个叫CNT的计数器中,我们通过CNT中的值与设置好的输出比较寄存器中的值进行比对,当CNT的值大于输出比较寄存器的值时,我们输出高/低电平,反之,我们输出相反的电平。这样,我们就实现了PWM输出功能。上面所写的每一步,在STM32的库函数中都有相应的函数对应。

    今天,基于此,我们简单做一个呼吸灯的案例。

    先看一下开发板,这里用的芯片是STM32F103C8T6,使用的LED引脚为PB0,通过手册,我们可以查到,PB0是TIM3的输出比较通道3引脚,所以我们配置TIM3的PWM输出功能,输出比较寄存器设置第三个寄存器,最后通过在循环中,不断改变输出比较寄存器的值,来实现呼吸灯效果。

具体代码如下:

首先是PWM初始化的.c文件。

#include "stm32f10x.h"              

void PWM_Init(void)
{
	//第一步,开启定时器时钟,定时器挂接在APB1总线上,所以调用下述函数。
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);
  //第二步,选择定时器的时钟源,这里选择内部时钟
	TIM_InternalClockConfig(TIM3);
	//第三步,设置定时器的相关配置
	TIM_TimeBaseInitTypeDef TIM_InitStructure;//初始化定时器时基结构体
	TIM_InitStructure.TIM_ClockDivision=TIM_CKD_DIV2;//这里是设置分配系数,设置为2,即2分频,则定时器输入频率为36MHz
	TIM_InitStructure.TIM_Period=100-1;//这里设置ARR的值,即CNT的极值
	TIM_InitStructure.TIM_Prescaler=360-1;//这里设置预分频系数,通过该处分频,输入CNT的频率降低为0.1MHz
	TIM_InitStructure.TIM_RepetitionCounter=0;//这个是重复计数设置,这里用不到,设为0即可
	TIM_InitStructure.TIM_CounterMode=TIM_CounterMode_Up;//这里将计数器设置为从开始递增,一直到预设值为止,也可设置为从预设值开始往下减
	TIM_TimeBaseInit(TIM3,&TIM_InitStructure);//调用初始化定时器函数
	//接下来初始化输出比较内容
	TIM_OCInitTypeDef TIM_OCStructure;//先初始化输出比较结构体
	TIM_OCStructInit(&TIM_OCStructure);//这个函数是给上面的结构体赋一个初值,后续需要改动就直接修改对应内容即可。
	TIM_OCStructure.TIM_OCPolarity=TIM_OCPolarity_High;//极性设置,若设置为低,则输出的高低电平需要取反,这里设置为高
	TIM_OCStructure.TIM_OutputState=TIM_OutputState_Enable;//使能
	TIM_OCStructure.TIM_OCMode=TIM_OCMode_PWM1;//这个是设置输出比较模式的,PWM1模式即CNT的值小于对应输出比较寄存器的值时,输出高电平
	TIM_OCStructure.TIM_Pulse=0;//设置CCR初值
	TIM_OC3Init(TIM3,&TIM_OCStructure);//初始化输出比较单元,选择输出比较通道3
	//使能TIM3
	TIM_Cmd(TIM3,ENABLE);
	//TIM3使能后,还要使能相应的引脚
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);//打开时钟,因为GPIO均挂接在APB2总线上,所以调用该函数
	//配置GPIO相关内容
	GPIO_InitTypeDef GPIO_InitSturetuct;//初始化结构体
	GPIO_InitSturetuct.GPIO_Mode=GPIO_Mode_AF_PP;//设置为复用推挽输出模式,因为用的是定时器输出
	GPIO_InitSturetuct.GPIO_Pin=GPIO_Pin_0;//选择引脚
	GPIO_InitSturetuct.GPIO_Speed=GPIO_Speed_50MHz;//选择输出频率
	GPIO_Init(GPIOB,&GPIO_InitSturetuct);//初始化
}

PWM的.h文件:

#ifndef __PWM_H
#define __PWM_H


void PWM_Init(void);


#endif

主函数:

#include "stm32f10x.h"                  
#include "Delay.h"
#include "PWM.h"


uint16_t num;
int main(void)
{
	PWM_Init();
	while (1)
	{
		for(num=0;num<100;num++)
		{
			TIM_SetCompare3(TIM3,num);//给输出比较通道3寄存器赋值
			Delay_ms(10);
		}
		for(num=0;num<100;num++)
		{
			TIM_SetCompare3(TIM3,99-num);
			Delay_ms(10);
		}
	}
}

    上面的函数都有注释,可以自己看看,最终结果显示正确。

  • 4
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值