在本次项目中,限于空间要求咱们选用了STM32F030F4做为控制芯片。这款MCU不但封装紧凑,并且自带的Flash空间也很是有限,因此咱们选择了LL库实现。本文咱们将说明如何经过LL库实现PWM信号的输出。编程
1、概述函数
咱们知道STM32的TIM计时器能够输出PWM信号,这测咱们也采用STM32F030F4中的TIM3通用计时器来实现咱们想要的功能。TIM3通用计时器由一个16位的自动从新加载计数器组成,由一个可编程的预约标器驱动。其结构以下图所示:spa
它能够用于各类目的,包括测量输入信号的脉冲长度(输入捕获)或生成输出波形(输出比较和PWM)。使用定时器预标量和RCC时钟控制器预标量,输出的PWM脉冲长度和波形周期能够调整从几微秒到几毫秒。咱们这里实现一个占空比0%到100%可调,频率为200Hz的PWM波形。blog
2、TIM配置it
咱们在使用TIM3输出PWM波,咱们必须对其进行相应的配置。关于TIM3的配置咱们须要关注:TIM3控制寄存器1 (TIM3_CR1)、TIM3预置寄存器(TIM3_PSC)、TIM3自动重载寄存器(TIM3_ARR)以及对应通道的捕获比较寄存器。io
首先来看一看TIM3控制寄存器1 (TIM3_CR1),这个寄存器用于配置TIM计时器。其结构以下:ast
对于TIM3控制寄存器1 (TIM3_CR1)咱们主要须要说一下计数器使能(CEN)位。而其它的位经过初始化函数设置就能够了。软件
TIM3预置寄存器(TIM3_PSC)用以配置TIM计数器的工做频率,这个工做频率的计算是:psc的工做频率/(psc的值+1)。其结构以下:配置
TIM3自动重载寄存器(TIM3_ARR)用以配置输出PWM波的频率或者说周期。由于这个值就是计数器的计数周期。其结构以下:下载
咱们设置了技术器的时钟频率,计数的周期,要想获得PWM波,咱们还须要告诉TIM一个占空比。关于占空比其实是在捕获比较寄存器中设置的。
3、PWM实现
咱们已经如何经过配置TIM获得PWM波形输出,咱们接下来就是经过软件来实现咱们的想法。其配置代码以下:
/* TIM3 初始化配置 */
static void TIM3_Init_Configuration(void)
{
LL_TIM_InitTypeDef TIM_InitStruct = {0};
LL_TIM_OC_InitTypeDef TIM_OC_InitStruct = {0};
LL_GPIO_InitTypeDef GPIO_InitStruct = {0};
/* TIM3时钟使能 */
LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_TIM3);
/* TIM3初始化配置 */
TIM_InitStruct.Prescaler = 47;
TIM_InitStruct.CounterMode = LL_TIM_COUNTERMODE_UP;
TIM_InitStruct.Autoreload = TIMPERIOD;
TIM_InitStruct.ClockDivision = LL_TIM_CLOCKDIVISION_DIV1;
LL_TIM_Init(TIM3, &TIM_InitStruct);
LL_TIM_DisableARRPreload(TIM3);
LL_TIM_OC_EnablePreload(TIM3, LL_TIM_CHANNEL_CH4);
TIM_OC_InitStruct.OCMode = LL_TIM_OCMODE_PWM1;
TIM_OC_InitStruct.OCState = LL_TIM_OCSTATE_DISABLE;
TIM_OC_InitStruct.OCNState = LL_TIM_OCSTATE_DISABLE;
TIM_OC_InitStruct.CompareValue = 0;
TIM_OC_InitStruct.OCPolarity = LL_TIM_OCPOLARITY_HIGH;
LL_TIM_OC_Init(TIM3, LL_TIM_CHANNEL_CH4, &TIM_OC_InitStruct);
LL_TIM_OC_DisableFast(TIM3, LL_TIM_CHANNEL_CH4);
LL_TIM_SetTriggerOutput(TIM3, LL_TIM_TRGO_RESET);
LL_TIM_DisableMasterSlaveMode(TIM3);
/* TIM使用GPIO时钟使能 */
LL_AHB1_GRP1_EnableClock(LL_AHB1_GRP1_PERIPH_GPIOB);
/* TIM3 GPIO配置:PB1 ------> TIM3_CH4 */
GPIO_InitStruct.Pin = LL_GPIO_PIN_1;
GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE;
GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_LOW;
GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL;
GPIO_InitStruct.Pull = LL_GPIO_PULL_NO;
GPIO_InitStruct.Alternate = LL_GPIO_AF_1;
LL_GPIO_Init(GPIOB, &GPIO_InitStruct);
LL_TIM_CC_EnableChannel(TIM3,LL_TIM_CHANNEL_CH4);
LL_TIM_EnableCounter(TIM3);
}
在这段配置代码中,有几个值须要说一下。Prescaler 值咱们设为47,因此在48MHz的系统时钟下,TIM计数器的工做频率就是1MHz。Autoreload 的值咱们设为了5000,因此能够获得PWM的频率为200Hz。CompareValue值设为了0,因此咱们只能获得占空比为0%的PWM。若咱们想要获得占空比为50%的PWM,则CompareValue值应设为2500才行。配置完成后各寄存器的值以下图所示:
这要获得的只是固定占空比的PWM波,若想动态修改占空比则须要修改捕获比较寄存器的值。使用函数LL_TIM_OC_SetCompareCH4(TIM3,pulse)就能够了,其中pulse是处于0到Autoreload 的值的整数。
4、总结
咱们经过上述操做,就实现了基于LL库的PWM波的输出。咱们将代码下载到目标板,并修改占空比和监视器波形输出。
上图是占空比为50%的波形图。
上图是占空比为20%的波形图。
上图是占空比为80%的波形图。
欢迎关注: