STM32F0使用LL库实现PWM输出

在本次项目中,限于空间要求我们选用了STM32F030F4作为控制芯片。这款MCU不但封装紧凑,而且自带的Flash空间也非常有限,所以我们选择了LL库实现。本文我们将说明如何通过LL库实现PWM信号的输出。

1、概述

我们知道STM32的TIM计时器可以输出PWM信号,这测我们也采用STM32F030F4中的TIM3通用计时器来实现我们想要的功能。TIM3通用计时器由一个16位的自动重新加载计数器组成,由一个可编程的预定标器驱动。其结构如下图所示:

它可以用于各种目的,包括测量输入信号的脉冲长度(输入捕获)或生成输出波形(输出比较和PWM)。使用定时器预标量和RCC时钟控制器预标量,输出的PWM脉冲长度和波形周期可以调整从几微秒到几毫秒。我们这里实现一个占空比0%到100%可调,频率为200Hz的PWM波形。

2、TIM配置

我们在使用TIM3输出PWM波,我们必须对其进行相应的配置。关于TIM3的配置我们需要关注:TIM3控制寄存器1 (TIM3_CR1)、TIM3预置寄存器(TIM3_PSC)、TIM3自动重载寄存器(TIM3_ARR)以及对应通道的捕获比较寄存器。

首先来看一看TIM3控制寄存器1 (TIM3_CR1),这个寄存器用于配置TIM计时器。其结构如下:

对于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%的波形图。

欢迎关注:

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/499415.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

STM32F0使用LL库实现Modbus通讯

在本次项目中,限于空间要求我们选用了STM32F030F4作为控制芯片。这款MCU不但封装紧凑,而且自带的Flash空间也非常有限,所以我们选择了LL库实现。本篇将说明基于LL实现USART通讯。 1、概述 我们想要实现基于RS485的Modbus通讯实际就是基于US…

STM32基于SPI和AD7192的数据采集

在开发臭氧发生器的时,我们需要一个高分辨率的AD采集,于是选择了AD7192,选择这款ADC的原因比较简单。首先它是24位的符合我们的精度要求;其次它自带时钟,便于节省空间;第三它有4路单端或2路差分输入&#x…

Modbus协议栈实现Modbus RTU多主站支持

前面我们已经详细讲解过Modbus协议栈的开发过程,并且利用协议栈封装了Modbus RTU主站和从站,Modbus TCP服务器与客户端,Modbus ASCII主站与从站应用。但在使用过程中,我们发现一些使用不便和受限的地方,所以我们就想要…

STM32基于AD5663的UV灯电压控制

在开发臭氧发生器的时,我们使用UV灯来实现臭氧的产生。而UV灯的强度决定了臭氧产生的浓度,UV灯的光强则与其控制电压密切相关。所以我们要控制产生的臭氧的浓度就需要调节其控制电压。我们选择了AD5663这一模拟量输出模块来实现这一点。 1、AD5663简介 …

实现Modbus ASCII多主站应用

前面我们已经分析了Modbus RTU的更新设计和具体实现(如果不清楚可查看前一篇文章)。其实Modbus ASCII与Modbus RTU都是基于串行链路实现的,所以有很多的共同点,基于此,这篇文章我们只讨论与Modbus RTU所不同的部分。 …

STM32一种基于NTC的控温电路及软件实现

NTC(Negative Temperature Coefficient)是一种随温度上升时,电阻值呈指数关系减小的热敏电阻。应用广泛,最近我们就采用了NTC来控制加热并测温,并达到了预期的效果。 1、硬件设计 我们使用三极管作为加热元件&#x…

STM32利用光敏二极管实现光度测量

最近我们在开发臭氧发生器时,需要监测生成的臭氧的浓度,于是想到使用光度计来测量。因为不同浓度的臭氧对管的吸收作用是不相同的,于是检测光照强度的变化就可以得到相应的浓度数据。 1、硬件设计 此次光照度检测我们选用了S1336-5BQ光电点二…

STM32的ADC通道间干扰的问题

最近我们在开发一个项目时,用到了MCU自带的ADC,在调试过程中发现通道之间村在相互干扰的问题。以前其实也用过好几次,但要求都不高所以没有太关注,此次因为物理量的量程较大,所以看到了变化。 首先来说明一下此次的软…

实现Modbus TCP多网段客户端应用

对于Modbus TCP来说与Modbus RTU和Modbus ASCII有比较大的区别,因为它是运行于以太网链路之上,是运行于TCP/IP协议之上的一种应用层协议。在协议栈的前两个版本中,Modbus TCP作为客户端时也存在一些局限性。我们将对这些不足作一定更新。 1、…

改进初学者的PID-介绍

最近看到了Brett Beauregard发表的有关PID的系列文章,感觉对于理解PID算法很有帮助,于是将系列文章翻译过来!在自我提高的过程中,也希望对同道中人有所帮助。作者Brett Beauregard的原文网址:http://brettb…

改进初学者的PID-采样时间

最近看到了Brett Beauregard发表的有关PID的系列文章,感觉对于理解PID算法很有帮助,于是将系列文章翻译过来!在自我提高的过程中,也希望对同道中人有所帮助。作者Brett Beauregard的原文网址:http://brettb…

改进初学者的PID-微分冲击

最近看到了Brett Beauregard发表的有关PID的系列文章,感觉对于理解PID算法很有帮助,于是将系列文章翻译过来!在自我提高的过程中,也希望对同道中人有所帮助。作者Brett Beauregard的原文网址:http://brettb…

LwIP应用开发笔记之一:LwIP无操作系统基本移植

现在,TCP/IP协议的应用无处不在。随着物联网的火爆,嵌入式领域使用TCP/IP协议进行通讯也越来越广泛。在我们的相关产品中,也都有应用,所以我们结合应用实际对相关应用作相应的总结。 1、技术准备 我们采用的开发平台是STM32F407…

改进初学者的PID-修改整定参数

最近看到了Brett Beauregard发表的有关PID的系列文章,感觉对于理解PID算法很有帮助,于是将系列文章翻译过来!在自我提高的过程中,也希望对同道中人有所帮助。作者Brett Beauregard的原文网址:http://brettb…

改进初学者的PID-积分饱和

最近看到了Brett Beauregard发表的有关PID的系列文章,感觉对于理解PID算法很有帮助,于是将系列文章翻译过来!在自我提高的过程中,也希望对同道中人有所帮助。作者Brett Beauregard的原文网址:http://brettb…

改进初学者的PID-手自动切换

最近看到了Brett Beauregard发表的有关PID的系列文章,感觉对于理解PID算法很有帮助,于是将系列文章翻译过来!在自我提高的过程中,也希望对同道中人有所帮助。作者Brett Beauregard的原文网址:http://brettb…

改进初学者的PID-初始化

最近看到了Brett Beauregard发表的有关PID的系列文章,感觉对于理解PID算法很有帮助,于是将系列文章翻译过来!在自我提高的过程中,也希望对同道中人有所帮助。作者Brett Beauregard的原文网址:http://brettb…

如何优化代码和RAM大小

如果供应商为我自己的项目提供了一个起点,那就太好了。工作blinky始终是一个伟大的首发。方便总是有代价,而且“blinky”就是夸大“切换GPIO引脚”的代码大小。对于具有少量RAM和FLASH的设备,这可能会引起关注:如果blinky占用那么…

改进初学者的PID-正反作用

最近看到了Brett Beauregard发表的有关PID的系列文章,感觉对于理解PID算法很有帮助,于是将系列文章翻译过来!在自我提高的过程中,也希望对同道中人有所帮助。作者Brett Beauregard的原文网址:http://brettb…

改进初学者的PID-测量的比例介绍

最近看到了Brett Beauregard发表的有关PID的系列文章,感觉对于理解PID算法很有帮助,于是将系列文章翻译过来!在自我提高的过程中,也希望对同道中人有所帮助。作者Brett Beauregard的原文网址:http://brettb…