stm32输出PWM

开发板:野火霸道V1
芯片:stm32f103ZET6
定时器:TIM3
输出通道:CH3
GPIO:PB0

PWM

PWM即脉冲宽度调制,是利用微处理器的数字输出来对模拟电路进行控制的
一种非常有效的技术,广泛应用在从测量、通信到功率控制与变换的许多领
域中。

在stm32中,除了基本定时器TIM6、TIM7,其他的都可以用来产生PWM输出。其中高级定时器TIM1、TIM8可以产生7路的PWM输出;而通用定时器TIM2~TIM5可以产生4路的PWM输出。

频率

F = 72M / ((ARR+1)*(PSC+1))

单位:Hz

占空比

Duty_Cycle = ((TIMx->CCRx) / ARR)*100

单位:%

下面的试验是通过调节PWM占空比来观察LED小灯的亮度变化

LED小灯电路
在这里插入图片描述

TIM3通道对应的GPIO

通道GPIO
CH1PA6
CH2PA7
CH3PB0
CH4PB1

由于小灯连接到了PB0 所以使用TIM3的通道3

输出比较

输出比较模式由寄存器 CCMRx 的位 OCxM[2:0] 配置

在这里插入图片描述

PWM模式有2种

在这里插入图片描述

输出比较结构体

typedef struct {
	uint16_t TIM_OCMode; // 比较输出模式
	uint16_t TIM_OutputState; // 比较输出使能
	uint16_t TIM_OutputNState; // 比较互补输出使能
	uint32_t TIM_Pulse; // 脉冲宽度
	uint16_t TIM_OCPolarity; // 输出极性
	uint16_t TIM_OCNPolarity; // 互补输出极性
	uint16_t TIM_OCIdleState; // 空闲状态下比较输出状态
	uint16_t TIM_OCNIdleState; // 空闲状态下比较互补输出状态
} TIM_OCInitTypeDef; 

通用定时器输出PWM只需配置部分成员即可

1、TIM_OCMode:比较输出模式选择,总共有八种,常用的为 PWM1/PWM2。它设定 CCMRx 寄存器 OCxM[2:0] 位的值

2、TIM_OutputState:比较输出使能,决定最终的输出比较信号 OCx 是否通过外部引脚输出。它设定 TIMx_CCER 寄存器 CCxE/CCxNE 位的值

3、TIM_OCPolarity:比较输出极性,可选 OCx 为高电平有效或低电平有效。它决定着定时器通道有效电平。它设定 CCER 寄存器的 CCxP 位的值

时基单元结构体

typedef struct 
{
	uint16_t TIM_Prescaler; // 预分频器
	uint16_t TIM_CounterMode; // 计数模式
	uint32_t TIM_Period; // 定时器周期
	uint16_t TIM_ClockDivision; // 时钟分频
	uint8_t TIM_RepetitionCounter; // 重复计算器
} TIM_TimeBaseInitTypeDef;

1、TIM_Prescaler:定时器预分频器设置,时钟源经该预分频器才是定时器计数时钟 CK_CNT,它设定 PSC 寄存器的值。计算公式为:计数器时钟频率 (fCK_CNT) 等于 fCK_PSC / (PSC[15:0] + 1),可实现 1 至 65536 分频。

2、TIM_CounterMode:定时器计数方式,可设置为向上计数、向下计数以及中心对齐。高级控制定时器允许选择任意一种。

3、TIM_Period:定时器周期,实际就是设定自动重载寄存器 ARR 的值, ARR 为要装载到实际自动重载寄存器(即影子寄存器)的值,可设置范围为 0 至 65535。

4、TIM_ClockDivision:时钟分频,设置定时器时钟 CK_INT 频率与死区发生器以及数字滤波器采样时钟频率分频比。可以选择 1、 2、 4 分频。

5、 TIM_RepetitionCounter:重复计数器,只有 8 位,只存在于高级定时器

TIM3复用功能重映像

在这里插入图片描述
使用到的函数

输出比较寄存器

void TIM_OC1Init(TIM_TypeDef* TIMx, TIM_OCInitTypeDef* TIM_OCInitStruct);
void TIM_OC2Init(TIM_TypeDef* TIMx, TIM_OCInitTypeDef* TIM_OCInitStruct);
void TIM_OC3Init(TIM_TypeDef* TIMx, TIM_OCInitTypeDef* TIM_OCInitStruct);
void TIM_OC4Init(TIM_TypeDef* TIMx, TIM_OCInitTypeDef* TIM_OCInitStruct);

预装载寄存器

void TIM_OC1PreloadConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPreload);
void TIM_OC2PreloadConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPreload);
void TIM_OC3PreloadConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPreload);
void TIM_OC4PreloadConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPreload);

配置的是CCMRx寄存器的OCxPE

设置占空比

//可以用于输出PWM时改变占空比
void TIM_SetCompare1(TIM_TypeDef* TIMx, uint16_t Compare1);
void TIM_SetCompare2(TIM_TypeDef* TIMx, uint16_t Compare2);
void TIM_SetCompare3(TIM_TypeDef* TIMx, uint16_t Compare3);
void TIM_SetCompare4(TIM_TypeDef* TIMx, uint16_t Compare4);

配置的是CCRx寄存器

上面的函数是与我们选择的通道相对应的
比如本次实验使用的是通道3,所以我们选择
TIM_OC3PreloadConfig()、TIM_SetCompare3()、TIM_OC3Init这三 个函数

编程步骤

  1. 初始化定时器通道的GPIO
  2. 配置时基单元
  3. 配置输出比较寄存器
  4. 使能预装寄存器
  5. 使能定时器
  6. 设置占空比

代码实现

#include "bsp_GeneralTimer.h"

//初始化用到的 GPIO
static void GENERALTIMER_GPIO_Config(void)
{
	GPIO_InitTypeDef   GPIO_InitStruct;

	RCC_APBxPeriphClockCmd(GENERALTIMER_CHANNEL_GPIO_CLOCK | RCC_APB2Periph_AFIO,ENABLE);  //使能GPIO外设和AFIO复用功能时钟
	
	GPIO_InitStruct.GPIO_Pin = GENERALTIMER_CHANNEL_GPIO_PIN;
	GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP;
	GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
	
	GPIO_Init(GENERALTIMER_CHANNEL_GPIO_PORT,&GPIO_InitStruct);
}

//初始化定时器模式
static void GENERALTIMER_MODE_Config(void)
{
	//时基
	TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct;
	//输出比较
	TIM_OCInitTypeDef TIM_OCInitStruct;

	GENERALTIMER_TIMx_CLOCK_FUN(GENERALTIMER_TIMx_CLOCK,ENABLE);
	
	//配置时基单元
	TIM_TimeBaseInitStruct.TIM_Prescaler = GENERALTIME_PSC;  //预分频值
	TIM_TimeBaseInitStruct.TIM_Period = GENERALTIME_Period;  //自动重装载寄存器周期的值 ARR
	TIM_TimeBaseInitStruct.TIM_CounterMode = TIM_CounterMode_Up;  //向上计数
	TIM_TimeBaseInitStruct.TIM_ClockDivision = TIM_CKD_DIV1;
	TIM_TimeBaseInitStruct.TIM_RepetitionCounter = 0;   
	
	TIM_TimeBaseInit(GENERAL_TIMEx,&TIM_TimeBaseInitStruct);
	
	//配置输出比较
	TIM_OCInitStruct.TIM_OCMode = TIM_OCMode_PWM2;           	//PWM模式配置为2
	TIM_OCInitStruct.TIM_OutputState = TIM_OutputState_Enable;  //输出使能
	TIM_OCInitStruct.TIM_OCPolarity = TIM_OCPolarity_High; //定时器通道有效电平
	
	TIM_OCxInit(GENERAL_TIMEx,&TIM_OCInitStruct);
	//使能预装载寄存器
	TIM_OCxPreloadConfig(GENERAL_TIMEx,TIM_OCPreload_Enable);
	//使能寄存器
	TIM_Cmd(GENERAL_TIMEx,ENABLE);
}

void GENERALTIME_Config(void)
{
	GENERALTIMER_GPIO_Config();
	GENERALTIMER_MODE_Config();
}

.h文件

#ifndef _BSP_GENERALTIMER_H
#define _BSP_GENERALTIMER_H

//TIM3 -> CH3   PB0

#include "stm32f10x.h"

//定时器 GPIO
#define RCC_APBxPeriphClockCmd				RCC_APB2PeriphClockCmd
#define GENERALTIMER_CHANNEL_GPIO_CLOCK     RCC_APB2Periph_GPIOB
#define GENERALTIMER_CHANNEL_GPIO_PORT   	GPIOB
#define GENERALTIMER_CHANNEL_GPIO_PIN    	GPIO_Pin_0

//定时器
#define GENERAL_TIMEx               		TIM3

#define GENERALTIMER_TIMx_CLOCK_FUN			RCC_APB1PeriphClockCmd
#define GENERALTIMER_TIMx_CLOCK     		RCC_APB1Periph_TIM3

#define GENERALTIME_PSC                     (36-1)
#define GENERALTIME_Period                  (100-1)

//PWM相关函数
#define TIM_OCxInit							TIM_OC3Init
#define TIM_OCxPreloadConfig				TIM_OC3PreloadConfig
#define TIM_SetComparex						TIM_SetCompare3


void GENERALTIME_Config(void);

#endif

在主函数中改变占空比来观察小灯的亮度变化

#include "bsp_GeneralTimer.h"


int main()
{	
	GENERALTIME_Config();
	
	while (1)
	{
		TIM_SetComparex(TIM3,10);
	}
}

由占空比计算公式得知此时占空比为:10%

  • 11
    点赞
  • 67
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
stm32tim1ch1npwmSTM32系列芯片中的一个定时器通道,用于实现PWM输出。在实现stm32tim1ch1npwm输出的过程中,需要进行一系列的配置和初始化操作。 首先,需要使能定时器(TIM1)和GPIO的时钟。这可以通过调用相应的函数来完成。 然后,需要调用HAL_TIM_PWM_Init函数初始化定时器(TIM1)的基础工作参数,例如自动重载值(ARR)和预分频值(PSC)等。 接下来,需要初始化定时器输出通道对应的GPIO引脚,用于连接到外部设备。 然后,调用HAL_TIM_PWM_ConfigChannel函数来设置PWM模式以及比较值等参数。 在配置完成后,需要对中断进行初始化,包括抢占优先级、响应优先级和开启中断。 最后,需要使能更新中断和使能通道输出。 以上是实现stm32tim1ch1npwm输出的一般步骤。具体的配置和初始化代码可以参考引用中的atim_timx_npwm_chy_init函数的代码。 综上所述,要实现stm32tim1ch1npwm输出,需要进行相关的定时器配置、GPIO初始化、中断配置和使能等操作。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* [STM32F103采用通用定时器方法输出PWM波形](https://blog.csdn.net/clyrjj/article/details/112408117)[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^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *3* [正点原子STM32(基于HAL库)3](https://blog.csdn.net/zhuguanlin121/article/details/128713657)[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^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

点灯大师~

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

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

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

打赏作者

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

抵扣说明:

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

余额充值