STM32 TIM_OC输出比较篇(PWM

        OC (Output Compare) 输出比较,可以通过比较CNT与CCR寄存器值的关系,来对输出电平进行置1、置0或翻转的操作,用于输出一定频率和占空比的PWM波形;每个高级定时器和通用定时器都拥有4个输出比较通道,高级定时器的前3个通道额外拥有死区生成和互补输出的功能。

捕获/比较寄存器是输入捕获喝输出比较公用的

        在输出比较中,电路会比较CNT和CCR的值,CNT计数自增,CCR为给定值,两个值比较后输出PWM波形至对应TIMx_CHx口

PWM (Pulse Width Modulation)脉冲宽度调制

具有惯性的系统中,可以通过对一系列脉冲的宽度进行调制,来等效地获得所需要的模拟参量,常应用于电机控速等领域

PWM参数:        频率=1/Ts        占空比 = ToN/Ts        分辨率 =占空比变化步距

        当CNT>CCR或者CNT=CCR1时,输出模式控制器会改变它输出OC1REF的高低电平,随后REF信号可前往主模式控制器,映射至TRGO的输出;也可往下走,至极性选择寄存器,可选择是否进行电平翻转;接着通过输出使能电路到达OC1引脚

输出模式控制器:

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

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

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

配置步骤:

        1、RCC开启始终,将需要使用的TIM外设和GPIO外设时钟打开

        2、配置时基单元,包括时钟源选择

        3、配置输出比较单元,包括CCR值、输出比较模式、极性选择、输出使能等

        4、配置GPIO,将PWM对应的GPIO口初始化为复用推挽输出模式

        5、运行控制,启动计数器,即可输出PWM

相关库函数:

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_OCStructInit(TIM_OCInitTypeDef* TIM_OCInitStruct);

void TIM_CtrlPWMOutputs(TIM_TypeDef* TIMx, FunctionalState NewState);

void TIM_ForcedOC1Config(TIM_TypeDef* TIMx, uint16_t TIM_ForcedAction);
void TIM_ForcedOC2Config(TIM_TypeDef* TIMx, uint16_t TIM_ForcedAction);
void TIM_ForcedOC3Config(TIM_TypeDef* TIMx, uint16_t TIM_ForcedAction);
void TIM_ForcedOC4Config(TIM_TypeDef* TIMx, uint16_t TIM_ForcedAction);

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);

void TIM_OC1FastConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCFast);
void TIM_OC2FastConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCFast);
void TIM_OC3FastConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCFast);
void TIM_OC4FastConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCFast);

void TIM_ClearOC1Ref(TIM_TypeDef* TIMx, uint16_t TIM_OCClear);
void TIM_ClearOC2Ref(TIM_TypeDef* TIMx, uint16_t TIM_OCClear);
void TIM_ClearOC3Ref(TIM_TypeDef* TIMx, uint16_t TIM_OCClear);
void TIM_ClearOC4Ref(TIM_TypeDef* TIMx, uint16_t TIM_OCClear);

void TIM_OC1PolarityConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPolarity);
void TIM_OC1NPolarityConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCNPolarity);
void TIM_OC2PolarityConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPolarity);
void TIM_OC2NPolarityConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCNPolarity);
void TIM_OC3PolarityConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPolarity);
void TIM_OC3NPolarityConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCNPolarity);
void TIM_OC4PolarityConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPolarity);

void TIM_CCxCmd(TIM_TypeDef* TIMx, uint16_t TIM_Channel, uint16_t TIM_CCx);
void TIM_CCxNCmd(TIM_TypeDef* TIMx, uint16_t TIM_Channel, uint16_t TIM_CCxN);
void TIM_SelectOCxM(TIM_TypeDef* TIMx, uint16_t TIM_Channel, uint16_t TIM_OCMode);

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);

        TIM_OC1Init:用于配置输出比较单元,参数:选择定时器,结构体

        TIM_OCStructInit:用于给输出比较结构体赋一个默认值

        TIM_CtrlPWMOutputs:仅限高级定时器输出PWM时使能使用,不用则PWM无法正常输出

        TIM_ForcedOC1Config:用于配置强制输出模式,在运行中暂停输出波形且强制输出高或低电平时使用

        TIM_OC1PreloadConfig:用于配置预装载寄存器(影子寄存器)

        TIM_OC1FastConfig:用于配置快速使能

        TIM_ClearOC1Ref:用于在外部事件是清除REF信号

        TIM_OC1PolarityConfig:用于单独设置输出比较极性

        TIM_OC1NPolarityConfig:用于单独设置输出比较极性,高级通道里互补通道的配置

        TIM_OC4PolarityConfig:OC4无互补通道,故无OC4N的函数

        TIM_CCxCmd:用于单独修改输出使能参数

        TIM_CCxNCmd:用于单独修改输出使能参数

        TIM_SelectOCxM:用于选择输出比较模式

        TIM_SetCompare1:用于单独更改CCR寄存器值的函数

代码实现(呼吸灯):

//PWM初始化代码如下
#include "stm32f10x.h"                  // Device header

void PWM_Init(void)
{
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB | RCC_APB2Periph_AFIO, ENABLE);
	
	GPIO_PinRemapConfig(GPIO_PartialRemap_TIM3, ENABLE);//使用正点原子精英板,需要对TIM3进行重映射
	
	GPIO_InitTypeDef GPIO_InitStructure;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOB, &GPIO_InitStructure);
	
	
	TIM_InternalClockConfig(TIM3); 		//这句不写也没有影响,默认使用内部时钟
	
	TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
	//TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;
	TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;
	TIM_TimeBaseInitStructure.TIM_Period = 99;
	TIM_TimeBaseInitStructure.TIM_Prescaler = 7199;
	TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0;//重复计数器,高级定时器才可使用,置0
	TIM_TimeBaseInit(TIM3, &TIM_TimeBaseInitStructure);
	
	TIM_OCInitTypeDef TIM_OCInitStructure;
	TIM_OCStructInit(&TIM_OCInitStructure); //用于给结构体中的所有变量赋初始值
											//避免使用高级定时器时因为部分变量未赋值而报错
	TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2;
	TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
	TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
	//TIM_OCInitStructure.TIM_Pulse = 50;
	TIM_OC2Init(TIM3, &TIM_OCInitStructure);
	TIM_OC2PreloadConfig(TIM3, TIM_OCPreload_Enable);  //使能TIM3在CCR2上的预装载寄存器
	TIM_Cmd(TIM3, ENABLE);

}

void PWM_SetCompare2(uint16_t Compare)
{
	TIM_SetCompare2(TIM3, Compare);
}



//main.c代码如下

#include "stm32f10x.h"                  // Device header
#include "delay.h"
#include "LED.h"
#include "KEY.h"
#include "OLED.h"
#include "PWM.h"


int main(void)
{
	//LED_Init();
	KEY_Init();
	delay_init();
	OLED_Init();
	PWM_Init();
	
	int i;
	
	while(1)
	{
		for(i=0; i<100; i++)
		{
			PWM_SetCompare2(i);
			delay_ms(10);
		}
		for(i=0; i<100; i++)
		{
			PWM_SetCompare2(100-i);
			delay_ms(10);
		}
	}
}

其中TIM3使用了复用功能重映像,根据操作手册如下,需选择部分重映射

<think> 我们正在配置定时器的输出比较模式,这里涉及两个结构体成员赋值。 在STM32 HAL库中,定时器的输出比较模式通过配置TIM_OC_InitTypeDef结构体来实现。 用户给出的两行代码实际上是相同的操作,但可能存在笔误(第二行中的TMR_OC_MODE_T可能是用户想写TIM_OC_InitTypeDef结构体的某个成员,但写错了)。 通常,我们会这样配置一个定时器的PWM输出: 步骤如下: 1. 初始化定时器时基(使用TIM_HandleTypeDef结构体)。 2. 配置输出比较通道(使用TIM_OC_InitTypeDef结构体)。 3. 调用HAL_TIM_PWM_ConfigChannel函数来配置通道。 4. 启动PWM输出。 其中,输出比较模式设置的是TIM_OC_InitTypeDef结构体的.OCMode成员。 用户给出的第一行:ocConfig.mode = TIM_OC_MODE_PWM1; 是正确的,ocConfig应该是TIM_OC_InitTypeDef类型的一个结构体变量。 第二行:TMR_OC_MODE_T = TIM_OC_MODE_PWM1; 可能是错误的,因为TMR_OC_MODE_T看起来像是一个类型(枚举类型),而不是变量。 因此,我们只需要第一行赋值即可。 下面是一个使用STM32 HAL库配置定时器PWM的示例代码。 假设我们使用TIM3的通道1(CH1)来产生PWM。 </think> 在STM32 HAL库中,这行代码用于配置定时器的输出比较模式为PWM模式1。下面是详细解释和完整实现: ### PWM模式配置详解 **输出比较模式选择**: - `TIM_OC_MODE_PWM1`:计数器向上计数时,当计数器值小于比较寄存器的值时输出有效电平(通常为高电平) - `TIM_OC_MODE_PWM2`:计数器向上计数时,当计数器值大于比较寄存器的值时输出有效电平 ```c TIM_OC_InitTypeDef ocConfig = {0}; // 定义输出比较配置结构体 // 配置PWM模式 ocConfig.OCMode = TIM_OC_MODE_PWM1; // 选择PWM模式1 ocConfig.Pulse = 100; // 设置比较值(占空比) ocConfig.OCPolarity = TIM_OCPOLARITY_HIGH; // 输出极性(高电平有效) ocConfig.OCFastMode = TIM_OCFAST_DISABLE; // 不启用快速模式 // 应用配置到通道 HAL_TIM_PWM_ConfigChannel(&htim3, &ocConfig, TIM_CHANNEL_1); // 启动PWM输出 HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_1); ``` ### 代码解析: 1. **TIM_OC_InitTypeDef结构体**: - `OCMode`:输出比较模式选择 - `Pulse`:比较寄存器值,决定占空比(计算公式:占空比 = Pulse / ARR * 100%) - `OCPolarity`:输出极性(高/低电平有效) - `OCFastMode`:快速模式开关(用于紧急更新输出状态) 2. **配置流程**: - 初始化定时器时基(设置ARR、PSC等) - 配置输出比较参数 - 启动PWM输出 3. **PWM模式对比**: | 模式 | 向上计数行为 | 向下计数行为 | 适用场景 | |------|-------------|-------------|---------| | PWM1 | CNT < CCR → 有效电平 | CNT > CCR → 有效电平 | 标准PWM | | PWM2 | CNT < CCR → 无效电平 | CNT > CCR → 无效电平 | 反向PWM | ### 完整PWM初始化示例: ```c void PWM_Init(void) { TIM_HandleTypeDef htim3; TIM_OC_InitTypeDef ocConfig = {0}; // 1. 配置时基 htim3.Instance = TIM3; htim3.Init.Prescaler = 83; // 84MHz/84 = 1MHz htim3.Init.CounterMode = TIM_COUNTERMODE_UP; htim3.Init.Period = 999; // PWM频率 = 1MHz/1000 = 1kHz htim3.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; HAL_TIM_PWM_Init(&htim3); // 2. 配置输出比较 ocConfig.OCMode = TIM_OC_MODE_PWM1; // 核心配置 ocConfig.Pulse = 500; // 50%占空比 ocConfig.OCPolarity = TIM_OCPOLARITY_HIGH; ocConfig.OCFastMode = TIM_OCFAST_DISABLE; HAL_TIM_PWM_ConfigChannel(&htim3, &ocConfig, TIM_CHANNEL_1); // 3. 启动PWM HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_1); } ``` ### 注意事项: 1. 使用前需确保: - 定时器时钟已使能(`__HAL_RCC_TIM3_CLK_ENABLE()`) - GPIO已配置为复用输出模式 - 正确映射定时器通道到引脚 2. 动态调节占空比: ```c __HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_1, new_value); // 或 TIM3->CCR1 = new_value; // 直接寄存器操作更快 ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值