三、Stm32学习-PWM输出_引脚重映射

实践是检验真理的唯一标准。

输出比较常用来输出PWM波形,常用在电流控制,电机控制等

1.输出比较

输出比较其实就是对比CNT与CRR寄存器值,然后对输出电平置高或置低。可以用于输出一定频率和占空比得PWM波。

当计数值CNT(Pulse值)比CRR寄存器值(ARR值)小的时候输出高电平或低电平。输出的是高电平还是低电平由你选择的PWM输出模式决定。

 2.参数计算

PWM频率:Freq = CLK_PSC / (PSC+1)/ (ARR+1)

PWM占空比:Duty = CRR / (ARR+1)

PWM分辨率:Reso = 1/(ARR+1)

分辨率就是占空比增加的步进,可以是0.1,或者1等。

3.死区生成和互补输出

互补输出是输出两路互补的PWM波形,即电平相反。一般用于控制MOS管的开关断。所以 如果在上面的开关管关断的一瞬间,但是因为器件不是理想的,可能没有完全关断。这时候下面的开关管又合上,那么很可能造成这一瞬间的瞬接,造成开关管发热。所以需要生成死区,让上面的开关管关断后延迟一会再打开下面的MOS管。

4.为什么配置GPIO输出时候需要复用推挽输出

阅读手册,需要选择复用功能输出,因为PWM来自片上外设。转交推挽输出的控制权。

5.引脚重映射

一个引脚可以复用很多种功能,比如PA4引脚可以有USART1_RX,TIM2_CH1输出,IIC2等,但是一个引脚使用的时候只能用一种功能。如果我现在既想用USART1_RX,又想用TIM2_CH1,那么就可以去查查手册,看看有没有引脚重映射。把想要的功能重新映射到另外一个引脚。这就是引脚重新映射。

6.配置

(1)使能时钟

(2)配置对应的GPIO

(3)配置对应的时钟源

(4)时基单元初始化

(5)输出比较初始化

这边要注意先初始化一下所有结构体的变量,不然有些变量没有初始化,也没有调用,可能会有bug,影响使用。

TIM_OCStructInit(&TIM_OCInitStructure);							//结构体初始化,若结构体没有完整赋值
																	//则最好执行此函数,给结构体所有成员都赋一个默认值
																	//避免结构体初值不确定的问题

 接着配置输出比较模式,输出的极性,输出使能和初始的CCR(Pulse值)

(6)最终使能定时器

(7)完整配置

void Timer_Init(void)
{
	
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);			//开启TIM2的时钟
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);			//开启GPIOA的时钟
	
		/*GPIO重映射*/
//	RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);			//开启AFIO的时钟,重映射必须先开启AFIO的时钟
//	GPIO_PinRemapConfig(GPIO_PartialRemap1_TIM2, ENABLE);			//将TIM2的引脚部分重映射,具体的映射方案需查看参考手册
//	GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable, ENABLE);		//将JTAG引脚失能,作为普通GPIO引脚使用
	
	/*GPIO初始化*/
	GPIO_InitTypeDef GPIO_InitStructure;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;  
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOA, &GPIO_InitStructure);		

	/*配置时钟源*/
	TIM_InternalClockConfig(TIM2);		//选择TIM2为内部时钟,若不调用此函数,TIM默认也为内部时钟
	
	/*时基单元初始化*/  //72MHZ  f = clk/Psc/Period
	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_TimeBaseInit,配置TIM2的时基单元	
	
	/*输出比较初始化*/
	TIM_OCInitTypeDef TIM_OCInitStructure;							//定义结构体变量
	TIM_OCStructInit(&TIM_OCInitStructure);							//结构体初始化,若结构体没有完整赋值
																	//则最好执行此函数,给结构体所有成员都赋一个默认值
																	//避免结构体初值不确定的问题
	TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;				//输出比较模式,选择PWM模式1
	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_OC1Init,配置TIM2的输出比较通道1
	
	/*TIM使能*/
	TIM_Cmd(TIM2, ENABLE);			//使能TIM2,定时器开始运行
}

  • 10
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是一个使用部分重映射的例程,将STM32定时器3的通道1和通道2配置为PWM输出: ```c #include "stm32f4xx.h" void TIM3_PWM_Init(void) { // 启用定时器3时钟 RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); // 定时器初始化结构体 TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct; TIM_OCInitTypeDef TIM_OCInitStruct; // 初始化定时器3的时基配置 TIM_TimeBaseInitStruct.TIM_Prescaler = 0; // 不分频 TIM_TimeBaseInitStruct.TIM_CounterMode = TIM_CounterMode_Up; // 上计数模式 TIM_TimeBaseInitStruct.TIM_Period = 999; // 设置ARR为999,频率为1kHz TIM_TimeBaseInitStruct.TIM_ClockDivision = TIM_CKD_DIV1; // 时钟分频为1 TIM_TimeBaseInit(TIM3, &TIM_TimeBaseInitStruct); // 配置定时器3的通道1和通道2作为PWM输出 TIM_OCInitStruct.TIM_OCMode = TIM_OCMode_PWM1; // PWM模式1 TIM_OCInitStruct.TIM_OutputState = TIM_OutputState_Enable; // 输出使能 TIM_OCInitStruct.TIM_OCPolarity = TIM_OCPolarity_High; // 输出极性为高 TIM_OCInitStruct.TIM_Pulse = 0; // 初始占空比为0 TIM_OC1Init(TIM3, &TIM_OCInitStruct); TIM_OC2Init(TIM3, &TIM_OCInitStruct); // 配置定时器3通道1和通道2的GPIO引脚 GPIO_InitTypeDef GPIO_InitStruct; RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE); // 启用GPIOB时钟 GPIO_PinAFConfig(GPIOB, GPIO_PinSource4, GPIO_AF_TIM3); // 将PB4引脚映射到定时器3通道1 GPIO_PinAFConfig(GPIOB, GPIO_PinSource5, GPIO_AF_TIM3); // 将PB5引脚映射到定时器3通道2 GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF; // 复用模式 GPIO_InitStruct.GPIO_OType = GPIO_OType_PP; // 推挽输出 GPIO_InitStruct.GPIO_Pin = GPIO_Pin_4 | GPIO_Pin_5; // PB4和PB5 GPIO_InitStruct.GPIO_Speed = GPIO_Speed_100MHz; // 100MHz输出速度 GPIO_Init(GPIOB, &GPIO_InitStruct); // 启动定时器3 TIM_Cmd(TIM3, ENABLE); } ``` 这个例程将定时器3配置为1kHz的PWM输出,占空比初始值为0。你可以根据需要修改TIM_TimeBaseInitStruct.TIM_Period的值来调节PWM的频率。使用GPIO_PinAFConfig函数将PB4和PB5引脚映射到定时器3的通道1和通道2。最后,通过调用TIM_Cmd函数启动定时器3。 请注意,这只是一个简单的例程,你可能需要根据你的具体需求进行更多的配置和调整。请参考STM32的相关文档以获取更多详细信息。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值