[STM32F1官方例程讲解1] TIM外设输出PWM波 您所在的位置:网站首页 stm32输出PWN波的引脚 [STM32F1官方例程讲解1] TIM外设输出PWM波

[STM32F1官方例程讲解1] TIM外设输出PWM波

2024-07-17 18:29| 来源: 网络整理| 查看: 265

[STM32F1官方例程讲解1] TIM外设输出PWM波 第一章 PWM波1.1 PWM波的主要参数1.2 STM32F1平台的PWM外设1.2.1 PWM外设映射关系1.2.2 PWM外设的寄存器的配置过程 第二章 相关函数配置2.1 时钟配置2.2 GPIO配置2.3 定时器配置 第三章 实现效果

第一章 PWM波

PWM的全称为Pulse-width modulation,是一种通过有效地将电信号切成离散部分来降低电信号传递的平均功率的方法。通过快速打开和关闭电源和负载之间的开关,可以控制进入负载的电压(和电流)的平均值。与关闭时间相比,开关打开的时间越长,提供给负载的总功率就越高。PWM常用于控制惯性负载(例如电机)。PWM的主要优点是开关器件的功耗非常低。当开关断开时,几乎没有电流,而当开关导通且功率正在传递到负载时,开关两端几乎没有压降。因此,作为电压和电流的乘积的功率损耗在两种情况下都接近于零。PWM还可以与数字控件配合使用,由于其开/关特性,可以轻松设置所需的占空比,进而完成控制任务。PWM在Boost-buck电路,电机控制,开关切换,呼吸灯中都有着极其重要的地位。本文基于stm32f10x_stdperiph_lib_um.chm文档中的TIM_PWM_Output章节编写。

1.1 PWM波的主要参数

在这里插入图片描述

参数定义周期T一次高低电平结束的时间频率f1/T占空比Duty Cycle在一个脉冲循环内,通电时间(高电平)占周期的比例。 1.2 STM32F1平台的PWM外设 1.2.1 PWM外设映射关系

在STM32F1平台上,PWM外设隶属于TIMER外设。以STM32F103C8T6芯片为例,通过查阅数据手册,确定TIMER外设在引脚上的映射关系。

引脚默认映射重映射PA0TIM2_CH1_ETR无PA1TIM2_CH2无PA2TIM2_CH3无PA3TIM2_CH4无PA6TIM3_CH1TIM1_CH1_BKINPA7TIM3_CH2TIM1_CH1_CH1NPA8TIM1_CH1无PA9TIM1_CH2无PA10TIM1_CH3无PA11TIM1_CH4无PA12TIM1_ETR无PA15无TIM2_CH1_ETRPB0TIM3_CH3TIM1_CH2NPB1TIM3_CH4TIM1_CH3NPB3无TIM2_CH2PB4无TIM2_CH3PB5无TIM2_CH4PB6TIM4_CH1无PB7TIM4_CH2无PB8TIM4_CH3无PB9TIM4_CH4无PB10无TIM2_CH3PB11无TIM2_CH4

其中,TIM1属于高级定时器(advanced-control timer),一些带后缀的功能不在这里讨论(如ETR,互补输出CHxN等)。后面程序中选用的是通用定时器(general -purpose timer)TIM3的CH1~CH4作为PWM波的输出口。

1.2.2 PWM外设的寄存器的配置过程

在这里插入图片描述 首先,对于一个外设而言,最重要的就是时钟的使能与配置,相关操作见2.1 时钟配置。查阅参考手册的相应章节,可知时钟可由外部输入产生,也可通过使能内部RCC(Reset and clock control)上的TIM外设来利用系统的时钟CK_INT(STM32F103为72MHz)。在这里我们选择的是后一种方法。 在这里插入图片描述 在产生了CK_INT内部TIM时钟信号后,先进入PSC Prescaler寄存器进行预分频(由TIM_Prescaler +1决定,定时器实际获得的计数频率为 f C K _ C N T = f C K _ I N T / ( T I M _ P r e s c a l e r + 1 ) f_{CK\_CNT} = f_{CK\_INT}/(TIM\_Prescaler +1) fCK_CNT​=fCK_INT​/(TIM_Prescaler+1))。而后,APR寄存器的值(由TIM_Period决定)决定了PWM波的周期。外设以 f C K _ C N T f_{CK\_CNT} fCK_CNT​ 的频率计数,并存储在CNT counter寄存器内,这部分内容详见2.3 定时器配置中的TIM_TimeBaseInit()函数。当CNT counter寄存器内的值与APR寄存器的值相等时,产生中断(在此例子中未用到),并置零CNT counter寄存器(根据设置)。此外,CNT counter寄存器内的值还与Capture/Compare x register内的值(由TIM_Pulse决定)进行比对,可分别设置大于/小于时的输出电平。

综上,可得PWM波的频率为 f P W M f_{PWM} fPWM​ :

f P W M = f C K _ I N T / ( T I M _ P r e s c a l e r + 1 ) / ( T I M _ P e r i o d + 1 ) f_{PWM}=f_{CK\_INT}/(TIM\_Prescaler+1)/(TIM\_Period+1) fPWM​=fCK_INT​/(TIM_Prescaler+1)/(TIM_Period+1)

占空比(假设CNT counter寄存器内的值比Capture/Compare x register内的值小时输出高电平)为:

D u t y C y c l e = ( T I M _ P u l s e + 1 ) / ( T I M _ P e r i o d + 1 ) Duty Cycle=(TIM\_Pulse+1)/(TIM\_Period+1) DutyCycle=(TIM_Pulse+1)/(TIM_Period+1)

同样的,可以看出对于同一个TIM外设,4通道的PWM波输出周期是相同的,而占空比是可分别调节的。

第二章 相关函数配置 2.1 时钟配置

需要使能挂载在APB1上的TIM3时钟,与挂载在APB2上的GPIOA,GPIOB的时钟。具体如下所示:

void RCC_Configuration(void) { /* TIM3 clock enable */ RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); /* GPIOA and GPIOB clock enable */ RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB, ENABLE); } 2.2 GPIO配置

STM32F103C8T6属于的类型是STM32F10X_MD,中等存储容量Medium-density的STM32F10X系列产品,进入的是下半部分的程序(即else之后的代码)。

void GPIO_Configuration(void) { GPIO_InitTypeDef GPIO_InitStructure; #ifdef STM32F10X_CL /*GPIOB Configuration: TIM3 channel1, 2, 3 and 4 */ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7 | GPIO_Pin_8 | GPIO_Pin_9; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOC, &GPIO_InitStructure); GPIO_PinRemapConfig(GPIO_FullRemap_TIM3, ENABLE); #else /* GPIOA Configuration:TIM3 Channel1, 2, 3 and 4 as alternate function push-pull */ 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); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1; GPIO_Init(GPIOB, &GPIO_InitStructure); #endif }

上述代码使能了STM32F103C8T6的PA6, PA7, PB0, PB1引脚(分别对应TIM3的CH1~CH4),并将其设置为复用推挽模式。

2.3 定时器配置 void TIM_Configuration(void) { TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; TIM_OCInitTypeDef TIM_OCInitStructure; uint16_t CCR1_Val = 333; uint16_t CCR2_Val = 249; uint16_t CCR3_Val = 166; uint16_t CCR4_Val = 83; uint16_t PrescalerValue = 0; PrescalerValue = (uint16_t) (SystemCoreClock / 24000000) - 1; /* ----------------------------------------------------------------------- TIM3 Configuration: generate 4 PWM signals with 4 different duty cycles: The TIM3CLK frequency is set to SystemCoreClock (Hz), to get TIM3 counter clock at 24 MHz the Prescaler is computed as following: - Prescaler = (TIM3CLK / TIM3 counter clock) - 1 SystemCoreClock is set to 72 MHz for Low-density, Medium-density, High-density and Connectivity line devices and to 24 MHz for Low-Density Value line and Medium-Density Value line devices The TIM3 is running at 36 KHz: TIM3 Frequency = TIM3 counter clock/(ARR + 1) = 24 MHz / 666 = 36 KHz TIM3 Channel1 duty cycle = (TIM3_CCR1/ TIM3_ARR)* 100 = 50% TIM3 Channel2 duty cycle = (TIM3_CCR2/ TIM3_ARR)* 100 = 37.5% TIM3 Channel3 duty cycle = (TIM3_CCR3/ TIM3_ARR)* 100 = 25% TIM3 Channel4 duty cycle = (TIM3_CCR4/ TIM3_ARR)* 100 = 12.5% ----------------------------------------------------------------------- /* Time base configuration */ TIM_TimeBaseStructure.TIM_Period = 665; //装载入ARR中的系数 TIM_TimeBaseStructure.TIM_Prescaler = PrescalerValue; //预分频系数 TIM_TimeBaseStructure.TIM_ClockDivision = 0; //外部输入分频,在PWM输出时无作用效果 TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;//向上计数 TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); /* PWM1 Mode configuration: Channel1 */ TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_Pulse = CCR1_Val; TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; TIM_OC1Init(TIM3, &TIM_OCInitStructure); TIM_OC1PreloadConfig(TIM3, TIM_OCPreload_Enable); /* PWM1 Mode configuration: Channel2 */ TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_Pulse = CCR2_Val; TIM_OC2Init(TIM3, &TIM_OCInitStructure); TIM_OC2PreloadConfig(TIM3, TIM_OCPreload_Enable); /* PWM1 Mode configuration: Channel3 */ TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_Pulse = CCR3_Val; TIM_OC3Init(TIM3, &TIM_OCInitStructure); TIM_OC3PreloadConfig(TIM3, TIM_OCPreload_Enable); /* PWM1 Mode configuration: Channel4 */ TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_Pulse = CCR4_Val; TIM_OC4Init(TIM3, &TIM_OCInitStructure); TIM_OC4PreloadConfig(TIM3, TIM_OCPreload_Enable); TIM_ARRPreloadConfig(TIM3, ENABLE); /* TIM3 enable counter */ TIM_Cmd(TIM3, ENABLE); //使能TIM3 }

在如上配置下,可以通过计算得到PWM波的频率: f P W M = f C K _ I N T / ( T I M _ P r e s c a l e r + 1 ) / ( T I M _ P e r i o d + 1 ) = 72 M H z / ( 2 + 1 ) / ( 665 + 1 ) = 36.04 k H z f_{PWM}=f_{CK\_INT}/(TIM\_Prescaler+1)/(TIM\_Period+1)=72MHz/(2+1)/(665+1)=36.04kHz fPWM​=fCK_INT​/(TIM_Prescaler+1)/(TIM_Period+1)=72MHz/(2+1)/(665+1)=36.04kHz

各通道的占空比Duty Cycle为:

通道引脚占空比CH1PA650%CH2PA737.5%CH3PB025%CH4PB125%

上述代码的程序已上传。

第三章 实现效果

采用便携式示波器测试,结果如下,能够很好地与前文所述的设置匹配上。 在这里插入图片描述 之后,我有时间的话会把STM32官方库的所有例程讲解一遍,敬请期待



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

      专题文章
        CopyRight 2018-2019 实验室设备网 版权所有