STM32——TIM定时器输出pwm波

  1. 输出比较(OC)功能介绍
  2. pwm的介绍
  3. 输出比较通道的基本结构,以及pwm实现步骤
  4. 相关函数介绍
  5. 目标及代码

一、输出比较(OC)功能介绍

1.介绍:OCOutput Compare)输出比较通过比较CNTCCR寄存器值的关系,来对输出电平进行置1、置0或翻转的操作,用于输出一定频率和占空比的PWM波形(需要使用此功能输出pwm波)

2.资源说明:每个高级定时器和通用定时器都拥有4个输出比较通道,高级定时器的前3个通道额外拥有死区生成和互补输出的功能


二、pwm的基本结构,以及实现步骤

1.介绍:pwm(脉宽调制)利用微处理器的数字输出对模拟电路进行控制的一种技术,通过改变脉冲宽度改变电压的输出(改变高电平和低电平的时间,实现改变平均电压,可以控制led灯的亮度,马达转速,舵机等等)

2.pwm的相关参数

  • 频率 = 1 /T        这个不用多说就是一个周期的倒数 
  • 占空比 = T'(高电平时间)/ T        高电平的时间毕上一个周期
  • 分辨率 = 占空比变化步距        比如占空比从1%,2%...这样变化,分辨率就是1%

三、输出比较通道的基本结构,以及pwm实现步骤

1.输出比较通道的基本结构见下图

  • 大致原理是通过配置输出模式控制器,然后比较CNT与CCR的值实现电平的操纵。配置完成后信号会输出到对应的通道

  • 我们要实现pwm选择任意一个pwm模式就行(这里选择pwm模式1,向上计数。下图)

2.实现pwm的基本结构

  • 如图所示,实现pwm需要以下的步骤:RCC配置需要的时钟-->配置好开启的时基单元和需要用到的GPIO口(GPIO改成复用推挽输出,将控制权交给片上外设的通道)-->配置输出比较单元-->使用TIM_Cmd运行

3.关于pwm的参数计算

  • 如图所示,参数的计算与时基单元(上一节有介绍)有关
  • 图中CNT一直增加到ARR(99)总共计了100次数,CCR设置为30
  • 由图知pwm的频率对应着计数器更新频率
  • 在CNT<CCR是时间内为高电平可以推出占空比
  • ARR越大,CCR打范围就越大,对应的分辨率就越高


四、相关函数介绍

  • TIM_InternalClockConfig:开启对应的定时器
  • TIM_OC1Init初始化输出比较单元(需要结构体参数,配置五),因为输出比较单元有4个,所以数字1改成2、3就可以配置别的输出比较单元
  • TIM_OCStructInit:结构体初始化
  • TIM_CCxCmd与TIM_CCxNCmd:单独修改输出使能
  • TIM_SetCompare1:单独修改通道1CCR的值
  • 注:PWM的输出需要使用GPIO口,具体那个GPIO能用记得查引脚定义表

五、目标及代码

1.使用pwm配置led呼吸灯

  • 第一步,RCC配置
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);//这里用的Tim2,是APB1的外设

    /*注意pwm的输出波形输出在PA0上,这里再初始一下GPIOA*/
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);//配置PA0,让它能输出pwm波
  • 第二步,配置时基单元,和需要的GPIO口
    /*配置时基单元*/
	TIM_InternalClockConfig(TIM2);
	/*配置时基单元,上节有*/
	TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
	TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;//控制时钟分频
	TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;//计数器模式,向上计数这种
	TIM_TimeBaseInitStructure.TIM_Period = 100-1;//ARR自动重装器的值
	TIM_TimeBaseInitStructure.TIM_Prescaler = 720-1;//PSC预分频器值
	TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0;//重复计数器的值,高级计时器用的
	
	TIM_TimeBaseInit(TIM2,&TIM_TimeBaseInitStructure);//需要结构体参数,记得取地址符

    /*配置GPIO*/
	GPIO_InitTypeDef GPIO_InitStruture;
	GPIO_InitStruture.GPIO_Mode = GPIO_Mode_AF_PP;//改成复用推挽输出,将控制权交给片上外设TIM2的CH1通道
	GPIO_InitStruture.GPIO_Pin = GPIO_Pin_0;//在PA0上输出pwm波
	GPIO_InitStruture.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOA,&GPIO_InitStruture);
  • 第三步,配置输出比较单元
    /*配置结构体的时候有很多参数(带n的参数,ldleState的...)是高级定时器才用的,这里只配置了一些用的到的*/
	TIM_OCInitTypeDef TIM_OCInitStruct;
	TIM_OCStructInit(&TIM_OCInitStruct);//给结构体赋初始值,防止有的参数每赋值出现问题
	TIM_OCInitStruct.TIM_OCMode = TIM_OCMode_PWM1;//模式,pwm1
	TIM_OCInitStruct.TIM_OCPolarity = TIM_OCPolarity_High;//极性,决定有效电平是高是低
	TIM_OCInitStruct.TIM_OutputState = TIM_OutputState_Enable;//输出使能
	TIM_OCInitStruct.TIM_Pulse = 50;//CCR,如果将ARR+1配成100,那占空比就是CCR%
	TIM_OC1Init(TIM2,&TIM_OCInitStruct);
  • 第四步,Cmd运行
TIM_Cmd(TIM2,ENABLE);
  • 为了实现呼吸灯程序,还需要一个函数实现CCR值的不断改变
/**
  *@brief    更改CCR即更改pwm占空比
  *@param CCR值
  *@retval  无
  */
void PWM_SetCompare1(uint16_t Compare)
{
	TIM_SetCompare1(TIM2,Compare);//CCR更改位Compare,注意第一个参数
}
  • 主函数如下,其他.h文件前几节都有,pwm的.c文件啥的再写一下就可以了
#include "stm32f10x.h"                  // Device header
#include "Delay.h"
#include "OLED.h"
#include "pwm.h"

uint8_t i;

int main(void)
{
	pwm_Init();
	while(1)
	{
		/*占空比升高变亮*/
		for(i=0;i<=100;i++)
		{
			PWM_SetCompare1(i);
			Delay_ms(10);//防止过快不明显
		}
		/*占空下降高变暗*/
		for(i=100;i>0;i--)
		{
			PWM_SetCompare1(i);
			Delay_ms(10);
		}
	}
}

  • 13
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值