STM32定时器&PWM应用编程

STM32-PWM介绍
STM32-PWM是STM32系列微控制器上的一种重要外设,用于生成脉宽调制(PWM)信号。脉宽调制技术在许多应用中都起着关键作用,如电机控制、LED亮度调节、音频处理等。STM32PWM模块提供了灵活的配置选项和高精度的PWM输出能力。
PWM工作原理
PWM是一种周期性的方波信号,通过调整方波的高电平时间(占空比)来控制输出信号的特性。PWM信号的频率和占空比可以根据应用需求进行配置。在STM32PWM模块中,通过设置定时器的计数周期和比较值,可以实现不同频率和占空比的PWM输出。
STM32PWM模块
STM32PWM模块通常由一个或多个通用定时器(TIM)和相关的GPIO引脚组成。通用定时器提供了灵活的PWM配置选项,可以根据需要进行定时器和GPIO引脚的映射、预分频设置、计数周期和比较值的设定等。
PWM参数配置
为了配置和控制STM32PWM模块,我们可以使用相应的库函数或直接操作寄存器。以下是一些常用的PWM参数和配置选项:
频率设置:通过设置定时器的计数周期来控制PWM信号的频率。频率 = 定时器时钟频率 / (预分频系数 * 计数周期)
占空比设置:通过设置比较值来控制PWM信号的占空比。占空比 = (比较值 / 计数周期) * 100%
极性设置:可以选择正极性或反极性,以控制PWM信号的电平极性。
中断使能:可以选择是否使能PWM定时器的中断功能,用于触发中断任务。
根据实际需求,选择合适的定时器来实现所需的PWM功能。
示例程序
定时器的应用
实验要求
使用STM32F103的 Tim2~Tim5其一定时器的某一个通道pin(与GPIOx管脚复用,见下图),连接一个LED,用定时器计数方式,控制LED以2s的频率周期性地亮-灭。
在这里插入图片描述

代码
led.c

#include "led.h"
void LED_Config(void){	
GPIO_InitTypeDef GPIO_InitStruct;		
RCC_APB2PeriphClockCmd(
RCC_APB2Periph_GPIOB, ENABLE);		
GPIO_InitStruct.GPIO_Mode=GPIO_Mode_Out_PP;	
GPIO_InitStruct.GPIO_Pin=GPIO_Pin_0;	
GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;	
GPIO_Init(GPIOB, &GPIO_InitStruct);}
void LED_Toggle(void){	
GPIOB->ODR ^=
 GPIO_Pin_0;}

led.h

#ifndef __LED_H
#define __LED_H#include "stm32f10x.h"void LED_Config(void);void 
LED_Toggle(void);#endif

tim_timebase.c

#include "tim_timebase.h"
#include "led.h"int a = 0;static void NVIC_Config(void)
{	NVIC_InitTypeDef NVIC_InitStruct;		
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);		
NVIC_InitStruct.NVIC_IRQChannel=TIM3_IRQn;	
NVIC_InitStruct.NVIC_IRQChannelCmd=ENABLE;	
NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority=1;	
NVIC_InitStruct.NVIC_IRQChannelSubPriority=1;	
NVIC_Init(&NVIC_InitStruct);}void TIM3_Config(void){	T
IM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct;		NVIC_Config();		
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);		
TIM_TimeBaseInitStruct.TIM_Period=71;	
TIM_TimeBaseInitStruct.TIM_Prescaler=1000;//1ms	TIM_TimeBaseInit(TIM3, &TIM_TimeBaseInitStruct);		TIM_ClearFlag(TIM3, TIM_FLAG_Update);		TIM_ITConfig(TIM3, TIM_IT_Update, ENABLE);		TIM_Cmd(TIM3, ENABLE);}void TIM3_IRQHandler(void){	if(TIM_GetITStatus(TIM3, TIM_IT_Update)) a++;	if(a == 1000)	{		LED_Toggle();		a = 0;	}	TIM_ClearITPendingBit(TIM3, TIM_IT_Update);}

通过以上代码,可以实现每秒闪烁一次的LED效果。在主函数中,需要调用TIM3_Config函数进行配置,然后进入主循环等待中断触发。当TIM3的更新中断发生时,会调用TIM3_IRQHandler函数进行LED状态的切换。
tim_timebase.h

#ifndef __TIM_TIMEBASE_H
#define __TIM_TIMEBASE_H
#include "stm32f10x.h"
void TIM3_Config(void);
#endif

main.c

#include "stm32f10x.h"
#include "led.h"#include "tim_timebase.h"
int main(void){	
LED_Config();	
TIM3_Config();		
while(1)	{	
		}}

实验效果:
在这里插入图片描述

PWM的应用
实验要求
接上,采用定时器PWM模式,让 LED 以呼吸灯方式渐亮渐灭,周期为1~2秒,自己调整到一个满意效果。使用Keil虚拟示波器,观察 PWM输出波形。
代码
PWM.c

#include "stm32f10x.h"                  // Device header
void PWM_Init(void){	
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);	
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);	//	
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);//	
GPIO_PinRemapConfig(GPIO_PartialRemap1_TIM2, ENABLE);//	
GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable, ENABLE);		
GPIO_InitTypeDef GPIO_InitStructure;	
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;	
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;		//GPIO_Pin_15;	
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;	GPIO_Init(GPIOA, 
&GPIO_InitStructure);		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);		TIM_OCInitTypeDef 
TIM_OCInitStructure;	TIM_OCStructInit(&TIM_OCInitStructure);	
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;	
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;	
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;	
TIM_OCInitStructure.TIM_Pulse = 0;		//CCR	TIM_OC1Init(TIM2, 
&TIM_OCInitStructure);		TIM_Cmd(TIM2, ENABLE);}void 
PWM_SetCompare1(uint16_t Compare){	TIM_SetCompare1(TIM2, Compare);}

main.c

#include "stm32f10x.h"                  // Device header
#include "Delay.h"
#include "OLED.h"
#include "PWM.h"uint8_t i;
int main(void){	
OLED_Init();	
PWM_Init();		
while (1)	{		
for (i = 0; i <= 100; i++)		{			
PWM_SetCompare1(i);			
Delay_ms(5);		}		
for (i = 0; i <= 100; i++)		{			
PWM_SetCompare1(100 - i);			
Delay_ms(5);		}	}}

实验效果:
接线
在这里插入图片描述

烧录后的效果:
在这里插入图片描述

使用Keil虚拟示波器,观察 PWM输出波形
Keil虚拟示波器的配置见:
链接:
https://blog.csdn.net/m0_72338354/article/details/133858992
选择PA0号引脚:
在这里插入图片描述

标为bit显示,用绿色的线表示,得到的波形结果如下图所示:
在这里插入图片描述

总结:
通过本实验,我们成功地实现了STM32定时器的 PWM 应用编程,并通过实验数据验证了 PWM 的应用效果 通过本实验,我们不仅加深了对 ST M32定时器和 PWM 原理的理解,还提高了我们的编程技巧和实验技能。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值