STM32F103C8T6定时器产生PWM

概述:

        这里我们来了解一下何为PWM,PWM是Pulse Width Modulation 的缩写,中文意思就是脉冲宽度调制,简称脉宽调制。它是利用微处理器的数字输出来对模拟电路进行控制的一种非常有效的技术,其控制简单、灵活和动态响应好等优点而成为电力电子技术最广泛应用的控制方式。

        在实际项目应用中最常见的有 使用PWM驱动舵机转动到固定的角度 或是 通过PWM调节直流电机实得到想要的转速 ,还有我们常见大多设备上的呼吸灯

        我们生产PWM有常见的两种的方法,分别是:(1)定时器中断变量累加比较、(2)定时器自身的3个寄存器通过通道输出PWM。

        这里我用常见的呼吸灯项目来为大家讲解如何用 定时器自身的3个寄存器通过通道输出PWM。

硬件介绍:

主控板采用的是:STM32F103C8T6

         

 呼吸灯这里采用LED小灯珠,因为该主控芯片的IO输出电压只用3.3V,所以无需加装电阻;

        

软件部分:

   1.寄存器:

         在编写软件前,我们先来了解一些重要的东西。在stm32f103c8t6中一共有4个定时器,其中TIM1为高级定时器。这里我使用是TIM4_CH2作为PWM比较输出通道;

我们这里用到的6个寄存器分别为:

(1)TIMx_ARR:自动装载 寄存器

(2)TIMx_CNT:计数器 寄存器

(3)TIMx_PSC:预分频器 寄存器

(4)TIMX_CCR1~4:通道1~4 捕获/比较 寄存器

(5)TIMx_CCER: 捕获/比较使能寄存器(设置输出/输入模式)

(6)TIMx_CCMR1/2: 捕获/比较模式寄存器(设置输入/输出通道为1,2/3,4)

这些寄存器中有3个寄存器带有影子寄存器,他们分别是:       

(1)TIMx_PSC:由于该控制寄存器具有缓冲功能,因此可对预分频器进行实时更改。而新的预分频比将在下一更新事件发生时被采用。

(2)TIMx_ARR:预装载寄存器的内容既可以直接传送到影子寄存器,也可以在每次发生更新事件(UEV)时传送到影子寄存器,这取决于TIMx_CR1 寄存器中的自动重载预装载使能位(ARPE)。也就是TIMx_CR1的ARPE位决定了预装寄存器数据传入影子寄存器的时间先后顺序。

(3)TIMX_CCR1~4:通过软件将TIMx_CR1寄存器中的UDIS位置1可禁止更新事件UEV事件。这可避免向预装载寄存器写入新值时更新影子寄存器。也就是TIMx_CR1寄存器中UDIS位间接决定了预装寄存器数据是否传入影子寄存器。

        如果想具体了解可以参考:STM32 影子寄存器 - 知乎 (zhihu.com)

PWM信号产生过程:

        初始化时,我们先对 TIMx_ARR(自动装载 寄存器)TIMx_PSC(预分频器 寄存器) 和 TIMX_CCR2(通道2 捕获/比较 寄存器)、TIMx_CCER(捕获/比较使能寄存器) 、TIMx_CCMR1 (捕获/比较模式寄存器)进行配置,然后对定时器进行使能。这时TIMx_CNT(计数器 寄存器)开始工作,TIMx_PSC(预分频器 寄存器)、 TIMx_ARR(自动装载 寄存器)和 TIMx_CCMR1 (捕获/比较模式寄存器)将 预装载的数值 拷贝到他们各自的 影子寄存器中,当计数值(CNT)大于或等于 TIMX_CCR2(通道2 捕获/比较 寄存器)中的比较数值时,IO口输出有效电平,当计数值(CNT)等于 TIMx_ARR 预装载数值时计数值(CNT)被清0,产生更新事件(UVE);进入下一次定时器计数的次循环,产生的波形近似为正弦波,实现过程如下图所示:

       

代码部分

PWM.C

#include "PWM.h"



void TIM4_PWM_Init(u16 arr,u16 psc)			//初始化 定时器4_PWM
{
    //宏定义 配置
	GPIO_InitTypeDef TIM4_PWM_Pin;
	TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
	TIM_OCInitTypeDef TIM4_OCInitStructure;
	
    //时钟配置
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE);	//使能定时器4时钟
 	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);   //使能GPIO外设功能模块时钟
	
	//配置PWM输出IO口
	TIM4_PWM_Pin.GPIO_Mode = GPIO_Mode_AF_PP;			    //功能模式:复用推挽输出
	TIM4_PWM_Pin.GPIO_Pin = GPIO_Pin_7;                     //IO管脚号:7
	TIM4_PWM_Pin.GPIO_Speed = GPIO_Speed_50MHz;             //传输速度:50M
	GPIO_Init(GPIOB,&TIM4_PWM_Pin);
	
	//初始化TIM4
	TIM_TimeBaseStructure.TIM_Period = arr - 1; //设置在下一个更新事件装入活动的自动重装载寄存器周期的值
	TIM_TimeBaseStructure.TIM_Prescaler =psc - 1; //设置用来作为TIMx时钟频率除数的预分频值 
	TIM_TimeBaseStructure.TIM_ClockDivision = 0; //设置时钟分割:TDTS = Tck_tim
	TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;  //TIM向上计数模式
	TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStructure); //根据TIM_TimeBaseInitStruct中指定的参数初始化TIMx的时间基数单位

	//初始化TIM4_CH2  PWM模式	 
	TIM4_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2; //选择定时器模式:TIM脉冲宽度调制模式2
 	TIM4_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比较输出使能
	TIM4_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low; //输出极性:TIM输出比较极性低
	TIM_OC2Init(TIM4, &TIM4_OCInitStructure);  //根据T指定的参数初始化外设TIM4 OC2

	TIM_OC2PreloadConfig(TIM4, TIM_OCPreload_Enable);  //使能TIM4在CCR2上的预装载寄存器
	
	TIM_Cmd(TIM4, ENABLE);  //使能TIM4
}

        注意:这里我们使用定时器4 为 IO口输出PWM,该功能是 IO口的复用功能,所以我这里的IO口模式设置为了 复用推挽输出,但是这里我没有使用 重映射管脚,所以没有使能 端口映射功能时钟如果你使用了重映射端口,就要使能该时钟。

PWM.H

#ifndef __PWM_H
#define	__PWM_H

#include "stm32f10x.h"
#include "stm32f10x_tim.h"


void TIM4_PWM_Init(u16 arr,u16 psc);			//初始化 定时器4_PWM

#endif

main.c

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

	
u8 dir=1;
u16 led0pwmval=0;




int main(void)
{
	
	SystemInit();			// 配置系统时钟为72M 	
	TIM4_PWM_Init(720,100);

	while(1)
	{

		delay_ms(10);	 
		if(dir)led0pwmval++;
		else led0pwmval--;

 		if(led0pwmval>300)dir=0;
		if(led0pwmval==0)dir=1;										 
		TIM_SetCompare2(TIM4,led0pwmval);
	}
}

实测可用,展示如下:

VID20220618190053

  • 11
    点赞
  • 117
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
STM32F103C8T6上使用TIM3输出PWM信号,可以按照以下步骤进行配置: 1. 配置TIM3时钟:使能TIM3时钟,并设置预分频器和计数器的重载值,以确定PWM输出的频率。 示例代码: ``` RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; TIM_TimeBaseStructure.TIM_Period = 999; // 重载值 TIM_TimeBaseStructure.TIM_Prescaler = 71; // 预分频器 TIM_TimeBaseStructure.TIM_ClockDivision = 0; TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); ``` 2. 配置TIM3通道:选择PWM模式,并设置占空比。 示例代码: ``` TIM_OCInitTypeDef TIM_OCInitStructure; TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_Pulse = 499; // 占空比 = TIM_Pulse / TIM_Period TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; TIM_OC2Init(TIM3, &TIM_OCInitStructure); TIM_Cmd(TIM3, ENABLE); ``` 在上述代码中,我们使用了TIM3的通道2来输出PWM信号。其中,TIM_OCInitStructure.TIM_Pulse的值决定了PWM信号的占空比,通过修改这个值可以改变PWM波形的占空比。 需要注意的是,TIM3的通道2对应的引脚是PA7,需要将PA7配置为TIM3的复用输出模式。 示例代码: ``` GPIO_InitTypeDef GPIO_InitStructure; 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); ``` 以上就是在STM32F103C8T6上使用TIM3输出PWM信号的基本步骤。根据实际需要,可以对以上代码进行调整和扩展。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值