第六篇,STM32脉冲宽度调制(PWM)编程

1.PWM概念

PWM叫脉冲宽度调制(Pulse Width Modulation),通过编程控制输出方波的频率和占空比(高低电平的比例),广泛应用在测量,通信,功率控制等领域(呼吸灯,电机)。

    PWM由定时器驱动,PWM周期就是定时器的周期,为了调节占空比,需要在定时器的基础上加上一个比较计数器,同时需要GPIO输出波形。

——————————————————————————————————————————

2.stm32中的PWM

    stm32中的PWM属于定时器功能,通过配置定时器就可以使用PWM,除了定时器的基本配置以外,还要加入一个比较计数值确定翻转电平的时机,还需要GPIO的复用功能输出PWM。

    stm32中PWM高低电平的顺序是由极性,PWM模式和计数模式共同决定。极性决定默认电平(有效电平),PWM模式指的是一个周期内有效电平和无效电平的顺序。

 

    —————————————————————————————————————————

3.使用库函数实现PWM配置D1为呼吸灯

(1)开启时钟

GPIOF时钟 TIM14时钟,函数略

(2)初始化GPIO为复用功能

GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF; GPIO_Init(...);  函数略

(3)将定时器14通道1的复用功能映射到PF9

void GPIO_PinAFConfig(GPIO_TypeDef* GPIOx, uint16_t GPIO_PinSource, uint8_t GPIO_AF); 
参数:     GPIOx - 哪一组GPIO     

           GPIO_PinSource - 哪个GPIO引脚     

           GPIO_AF - 哪个复用功能(只能映射具有的复用功能)

(4)初始化定时器

TIM_TimeBaseInit(......); 函数略

(5)初始化PWM

void TIM_OC1Init(TIM_TypeDef* TIMx, TIM_OCInitTypeDef* TIM_OCInitStruct);

      参数:     TIMx - 哪个定时器     

                TIM_OCInitStruct - 初始化结构      
typedef struct {

  uint16_t TIM_OCMode;        /*!< PWM模式 */   
  uint16_t TIM_OutputState;   /*!< 输出状态使能 */   
  uint16_t TIM_OutputNState;  /*!< 忽略  */

  uint32_t TIM_Pulse;         /*!< 比较计数值 */   

  uint16_t TIM_OCPolarity;    /*!< 极性  */   
  uint16_t TIM_OCNPolarity;   /*!< 忽略 only for TIM1 and TIM8. */   uint16_t TIM_OCIdleState;   /*!< 忽略 only for TIM1 and TIM8. */   uint16_t TIM_OCNIdleState;  /*!< 忽略 only for TIM1 and TIM8. */ 
} TIM_OCInitTypeDef;  

  

(6)使能PWM的预装载和重装载功能

TIM_OC1PreloadConfig(TIM14, TIM_OCPreload_Enable); 
TIM_ARRPreloadConfig(TIM14, ENABLE);

(7)启动定时器

TIM_Cmd(...); //高级定时器(TIM1/TIM8),还需要开启另一个开关 void TIM_CtrlPWMOutputs(TIM_TypeDef* TIMx, FunctionalState NewState);

参数:     TIMx - 哪个定时器    

           NewState - ENABLE/DISABLE

(8)运行时可调节占空比

void TIM_SetCompare1(TIM_TypeDef* TIMx, uint32_t Compare1);
 参数:     TIMx - 哪个定时器     
            Compare1 - 新的比较值 

__________________________________________________________________________________________________________________________________________________________

使用库函数配置GPIOF,通用定时器TIM14,使得D1灯呼吸闪烁,代码实现如下:

pwm.c

#include <stm32f4xx.h>
#include <pwm.h>

void timer14_pwm_init(void)
{
	GPIO_InitTypeDef GPIO_InitStruct;
	TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct;
	TIM_OCInitTypeDef TIM_OCInitStruct;
	
	//1.开启GPIOF和TIM14时钟
	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOF,ENABLE);
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM14,ENABLE);
	
	//2.初始化PF9为复用功能
	GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF;//复用模式
	GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;//推挽输出
	GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;//高速
	GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL;//无上下拉
	GPIO_InitStruct.GPIO_Pin = GPIO_Pin_9;//PF9
	GPIO_Init(GPIOF,&GPIO_InitStruct);
	
	//3.将PF9复用映射到TIM14
	GPIO_PinAFConfig(GPIOF,GPIO_PinSource9,GPIO_AF_TIM14);
	
	//4.初始化定时器14 84M / 84 = 1MHz 1M ------ 1000 ----- 1ms
	TIM_TimeBaseInitStruct.TIM_Prescaler = 84-1;//预分频系数
	TIM_TimeBaseInitStruct.TIM_Period = 1000-1;//初始计数值
	TIM_TimeBaseInitStruct.TIM_CounterMode = TIM_CounterMode_Down;//向下计数
	TIM_TimeBaseInitStruct.TIM_ClockDivision = TIM_CKD_DIV1;//时钟因子
	TIM_TimeBaseInit(TIM14,&TIM_TimeBaseInitStruct);
	
	//5.PWM初始化
	TIM_OCInitStruct.TIM_OCMode = TIM_OCMode_PWM1;//PWM模式1
	TIM_OCInitStruct.TIM_OCPolarity = TIM_OCPolarity_Low;//低电平有效
	TIM_OCInitStruct.TIM_OutputState = TIM_OutputState_Enable;//使能
	TIM_OCInitStruct.TIM_Pulse = 800;//比较计数值
	TIM_OC1Init(TIM14,&TIM_OCInitStruct);
	
	//6.使能PWM的预装载和重装载功能
	TIM_OC1PreloadConfig(TIM14, TIM_OCPreload_Enable);
	TIM_ARRPreloadConfig(TIM14, ENABLE);
	
	//7.使能定时器14
	TIM_Cmd(TIM14,ENABLE);
}

主函数main.c

#include <stm32f4xx.h>
#include <includes.h>

int main()
{	
	u32 comp = 0;
	
	//1.中断优先级分组 2:2
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
	
	//初始化
	//led_init();
	//key_init();
	beep_init();
	exti_init();
	mq2_init();
	delay_init();
	//timer2_init();
	//timer10_init();
	timer14_pwm_init();
	
	//D1为呼吸灯
	while(1){
		//1s从最暗到最亮
		while(comp<1000){
			TIM_SetCompare1(TIM14,comp);
			comp++;
			delay_ms(1);
		}
		
		//1s从最亮到最暗
		while(comp>0){
			TIM_SetCompare1(TIM14,comp);
			comp--;
			delay_ms(1);
		}
		
		delay_ms(200);
	}
	
}

其余模块函数的实现代码看其他章节

  • 6
    点赞
  • 51
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
脉冲宽度调制PWM)是一种通过改变脉冲宽度来控制电路输出功率的技术。在STM32中,可以使用定时器来生成PWM信号。通过调整定时器的频率和占空比,可以实现对输出电压大小和频率的控制。PWM信号的占空比表示高电平占整个周期的百分比,通过改变占空比可以调节输出功率。\[3\] 在STM32中,可以使用定时器的输出比较功能来生成PWM信号。通过配置定时器的计数值和比较值,可以确定脉冲宽度和周期。同时,还可以使用死区功能来避免输出信号的交叉干扰。\[2\] 具体实现PWM功能的步骤可以参考相关的资料和示例代码,如练习STM32动态更改PWM波频率和占空比、基于STM32的2FSK调制解调器设计等。这些资料提供了关于STM32的PWM原理、定时器的配置和使用方法等详细信息,可以帮助你更好地理解和应用PWM技术。\[1\] #### 引用[.reference_title] - *1* *2* [【stm32】基于cubemx+HAL库的带死区互补频率可调PWM产生](https://blog.csdn.net/Tube_Core/article/details/116609847)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insert_down28v1,239^v3^insert_chatgpt"}} ] [.reference_item] - *3* [基于stm32F4的项目总结:控制层设计(四)直流有刷电机驱动基础知识](https://blog.csdn.net/superyang423/article/details/118732804)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insert_down28v1,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

肖爱Kun

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值