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