第二篇 STM32F030输出PWM波形

2019-07-20 23:38发布

PWM这个名词相信搞电子的并不陌生,废话不说了,直接开工

运行平台、编译环境、基础代码均来自http://www.openedv.com/thread-74004-1-1.html

一、要输出PWM就要找到有定时器功能的管脚,打开硬件参考手册,找到Pin列表
1.png
本次利用定时器3的通道1输出PWM
二、打开工程,新建文件hal_timer,c和h文件分别建立并添加到工程
2.png
2.1 打开c文件,开始编写代码,建立初始化函数
3.png
2.2 要输出PWM,第一步就是打开对应的时钟了,TIM3-CH1在PA6端口,所以打开GPIOA时钟和TIM3时钟,打开编程参考手册,找到时钟篇
4.png
找到GPIOA所在总线
5.png
定时器3所在的总线
6.png
编写代码如下
7.png
这样就可以打开GPIOA和TIM3的时钟了
2.3 配置IO端口,找到GPIO相关的寄存器
8.png
看下寄存器列表,配置时涉及到的寄存器有四个MODER、OTYPER、OSPEEDR、PUPDR寄存器,先将这几个寄存器对应PA6管脚位清零
10.png
接下来将PA6配置成复用推挽输出模式,代码如下(至于为什么是这样,大家自行研究)
11.png
2.4 端口配置完成,是不是认为就OK了呢???别着急,还要打开复用才行,GPIO复用寄存器如下
12.png
对照硬件手册Pin列表最后部分,看到一个管脚复用的详细列表(GPIOA部分,其他的自行查看)
13.png
对应的代码
14.png
三、GPIO初始化完成了,接下来初始化定时器部分了,同样,在编程参考手册中找到TIM3部分
15.png
上图列出了TIM3所涉及到的寄存器,不同于F1系列的,大家对比一下区别即可
3.1 首先配置定时器的分频与计数,初始化函数引入两个形参,用于设置定时器的分频系数和计数值的,详细代码如下(具体作用请参考相关寄存器说明)
16.png
首先将自动重装值(计数值)放入ARR寄存器(auto-reload register),将分频值放入PSC寄存器(prescaler)
查看控制寄存器CR1设置相关部分,本次采用时钟总线不分频处理
17.png
设置计数方向,向上(或者向下)
18.png
注意看Bits 6:5 CMS: Center-aligned mode selection的说明,别设置错了
使能自动重装
3.2 配置PWM部分,也就是比较输出部分,代码如下,就不一一解释了,大家自行查看相关寄存器
19.png
四、在main函数中添加头文件hal_timer.h,while循环之前初始化PWM输出
20.png
也许大家的疑惑来了,第二个形参为什么是480-1呢???这个就是定时器3所在总线的频率,前面我们设置的总线不分频的,所以这里填写的值就是总线的值,在编程参考手册中,找到时钟树
21.png
看到时钟来源,或许还可以打开system_stm32f0xx.c文件,开头注释的地方也有说明
22.png
由此可见,频率就是系统主频48MHz,又或者直接调用库函数void RCC_GetClocksFreq(RCC_ClocksTypeDef* RCC_Clocks)直接获取
所以得到定时器的频率为:48000 000 / 480 =100 000Hz
由第一个形参可知,计数100次之后管脚上电平发生翻转:100 000 / 100 = 1000Hz
所以,在管脚上会产生一个1000Hz频率的波形
五、编译下载验证
23.png
0错误和0警告,说明编译通过,点击下载按钮下载到板子上验证,接上逻辑分析仪(或者示波器)到PA6管脚,探测PA6输出的波形
24.png
探测到的频率为1000Hz和配置的一致
六、众所周知,PWM有占空比一说,要想改变输出波形的占空比,查看寄存器capture/compare register 1(这里选用的是第一个通道,所以是1)
25.png
改变这个寄存器的数值即可改变占空比
在main函数中这样写上
26.png
这里填写的是30,即输出的占空比是30%(注意前面输入的计数次数是100,所以这里填写多少就是占空比多少),再次编译下载,探测波形
27.png
看到高电平的时长变成了0.3ms,前面的是0.49ms
七、附件中同时包含有IAR、MDK、Source Insight工程,大家可自行打开
八、至于普通定时器功能,可将本工程中PWM寄存器配置部分去掉,配置相关中断部分即可实现,大家自行实验
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。