蓝桥杯嵌入式——PWM模式

如何把定时器设置成PWM模式,从而产生相应频率,相应占空比的PWM波

蓝桥杯主要考的定时器也就三个TIM1TIM2TIM3

TIM3如何配置PWM

PA6对应通道一,PA7对应通道2

//pwm.h

#ifndef __PWM_H
#define __PWM_H

#include "stm32f10x.h"

void TIM3_PWM_Init(u16 pwm_fre,u8 ch1_duty,u8 ch2_duty);

#endif
#include "pwm.h"

void TIM3_PWM_Init(u16 pwm_fre,u8 ch1_duty,u8 ch2_duty)
{
	u16 arr;
	TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
	TIM_OCInitTypeDef  TIM_OCInitStructure;
	GPIO_InitTypeDef GPIO_InitStructure;
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
	
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7;
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;		复用推挽输出
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOA, &GPIO_InitStructure);
	
	arr=1000000/pwm_fre;
	TIM_TimeBaseStructure.TIM_Period = arr-1;		//计数值
        TIM_TimeBaseStructure.TIM_Prescaler = 72-1;		//分频系数 72分频
        TIM_TimeBaseStructure.TIM_ClockDivision = 0x0;		//向上计数
        TIM_TimeBaseStructure.TIM_CounterMode = 0x0;		//不分频
	TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);
	
	TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2;
        TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
        TIM_OCInitStructure.TIM_Pulse = (arr-1)*ch1_duty/100;
        TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low;
        TIM_OC1Init(TIM3, &TIM_OCInitStructure);
	
	TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2;
        TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
        TIM_OCInitStructure.TIM_Pulse = (arr-1)*ch2_duty/100;
        TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low;
        TIM_OC2Init(TIM3, &TIM_OCInitStructure);
	
	TIM_CtrlPWMOutputs(TIM3,ENABLE);
	TIM_Cmd(TIM3, ENABLE);
}

stm32f1的主频是72MHZ,那么在我们不分频的情况下,TIM3的主频也是72M,那么72M的计数速度我们觉得太快了,同时也不方面我们进行计算,所以让TIM3的时钟进行72分频,那么分频系数就是72 - 1。分频后我们的定时器将以1M的速度进行计数,那么这个计数值是非常方面计算的。能换算一下,1MHZ的计数频率,我们换算成周期那么就是1us,也就是说我们的计数值是每过1us加一。我们在初始化函数里传入一个入口参数代表我们设定的频率值(单位是HZ),我们把频率值换算成计数值,也就是1000000/pwm_fre

TIM_Pulse则代表的是你的电平翻转值

 

我们画一个简图,假设我们的计数值为2000,pulse为1000

当我们的计数值到2000后就会清零不断的进行向上计数,假如当前计数值小于pulse,那么输出的为高电平,假如当前技术值大于pulse,那么输出就为低电平,这样的能够实现50%占空比的PWM波了。                       

就简单的来说,pulse就是用来设置你的占空比的,我们只需要把pulse设置成 计数值x 占空比就可以了

 

我们先把频率设置成1000HZ,PA6产生40%占空比的方波,PA7产生80%占空比的方波

那么再来设置成5000HZ,PA6产生10%占空比的方波,PA7产生30%占空比的方波

//main.c

#include "stm32f10x.h"
#include "lcd.h"
#include "pwm.h"

u32 TimingDelay = 0;

void Delay_Ms(u32 nTime);

//Main Body
int main(void)
{
	STM3210B_LCD_Init();
	LCD_Clear(Blue);
	LCD_SetBackColor(Blue);
	LCD_SetTextColor(White);
	
	SysTick_Config(SystemCoreClock/1000);
	
	TIM3_PWM_Init(5000,10,30);

	while(1)
	{
			
	}
}

//
void Delay_Ms(u32 nTime)
{
	TimingDelay = nTime;
	while(TimingDelay != 0);	
}

使用PWM模式有一个缺点同一定时器中,不同的通道下,输出的频率固定,占空比可变。也就是说,假如我们通道1输出1KHZ方波,那么通道同样也是1KHZ 方波。

 

这种PWM模式在对于我们日常的控制使用上是没有问题的,但是你看蓝桥杯历年赛题的时候,会看到许多题目要你使用一个定时器,不同通道上让你产生不同频率,不同占空比的方波,甚至还有题目让你产生相位不同的方波,那么在这种情况下显然PWM模式时达不到这种效果的,我们就要换一种方式

STM32固件库v3.5\STM32F10x_StdPeriph_Lib_V3.5.0\Project\STM32F10x_StdPeriph_Examples\TIM\PWM_Output

### 蓝桥杯嵌入式开发中PWM的实现 在嵌入式开发领域,脉宽调制(Pulse Width Modulation, PWM)是一种常见的技术,用于控制电机速度、调节LED亮度以及驱动其他电子设备。以下是基于STM32微控制器及其HAL库实现PWM的方法。 #### STM32 HAL库中的TIM_PWM_Init函数 通过STM32CubeMX工具可以快速配置定时器以生成PWM信号。具体来说,在初始化阶段会设置定时器的工作模式PWM模式,并指定占空比和频率参数。以下是一个典型的PWM初始化代码片段: ```c // 定义 TIM_HandleTypeDef 结构体变量 TIM_HandleTypeDef htimX; void MX_TIMx_PWM_Init(void) { __HAL_RCC_TIMx_CLK_ENABLE(); // 启用定时器时钟 // 初始化结构体定义 TIM_OC_InitTypeDef sConfigOC; htimX.Instance = TIMx; // 设置使用的定时器实例 htimX.Init.Prescaler = 999; // 预分频器值 (假设系统时钟为10MHz,则计数频率为10KHz) htimX.Init.CounterMode = TIM_COUNTERMODE_UP; // 计数方向向上 htimX.Init.Period = 999; // 自动重装载寄存器周期值 (即PWM周期为1ms) htimX.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; // 时钟分割因子设为1 HAL_TIM_Base_Init(&htimX); // 初始化基本定时功能 sConfigOC.OCMode = TIM_OCMODE_PWM1; // 设定为PWM Mode 1 sConfigOC.Pulse = 500; // 初始占空比设定为50% sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH; // 输出极性高有效 sConfigOC.OCFastMode = TIM_OCFAST_DISABLE; // 关闭快速使能 HAL_TIM_PWM_ConfigChannel(&htimX, &sConfigOC, TIM_CHANNEL_1); // 配置通道1为PWM输出 } ``` 上述代码展示了如何利用STM32 HAL库来创建一个工作于特定频率和初始占空比下的PWM波形[^3]。 #### 动态调整PWM占空比 除了静态配置外,还可以动态改变PWM信号的占空比从而达到实时调控的目的。下面给出了一段修改占空比的例子: ```c uint32_t duty_cycle = 750; // 新的目标占空比对应数值 __HAL_TIM_SET_COMPARE(&htimX,TIM_CHANNEL_1,duty_cycle); ``` 此部分代码允许程序运行期间灵活更改输出电平的时间比例[^4]。 #### 综合应用案例——直流电机转速控制 为了更好地理解实际应用场景,这里提供了一个简单的例子说明怎样运用前面介绍的技术去操控DC马达的速度变化情况: ```c #include "stm32fxxx_hal.h" #define MOTOR_SPEED_MAX 1000U volatile uint16_t motor_speed = 0U; int main() { /* 用户自定义初始化 */ SystemClock_Config(); MX_GPIO_Init(); MX_TIMx_PWM_Init(); while (true){ if(motor_speed<MOTOR_SPEED_MAX && ButtonPressed()){ motor_speed +=10; } __HAL_TIM_SET_COMPARE(&htimX,TIM_CHANNEL_1,motor_speed); delay_ms(100); } } /* 其他辅助子例程省略...*/ ``` 以上示例演示了当检测到按键事件发生后逐步提升电动机运转速率的过程[^5]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值