PWM介绍:全称Pulse Width Modulation:脉冲宽度调制。可能你会好奇这是什么? 先来打开脑洞想象一个有趣的问题,假如我们家里的灯,你以一秒钟内开0.2ms关0.8ms的手速一直循环操作,会发生什么?你可能会观察到灯的亮度发生了改变,同时,人眼有视觉暂留现象,大概在0.1~0.4S内,开关频率高了以后人眼是完全无法察觉到灯的闪烁的。
占空比调节演示: 由于是软件模拟方式,所以和实际的计算有些误差。
PWM主要几个技术参数:周期(T)、频率(f)、占空比(高电平在整个周期的持续时间) 周期是频率的倒数,T = 1/f。占空比(%):高电平在整个周期持续时间/T
为什么要使用软件模拟方式来实现PWM?可能有人会问,本来就有硬件实现方式,软件是不是多此一举?貌似确实是的,但在一些特殊场景就需要使用到软件模拟IO口方式实现PWM,这里介绍一种实现思路。
这里主要介绍使用通用定时器。
STM32F1 的通用定时器是一个通过可编程预分频器(PSC)驱动的 16 位自动装载计数器 (CNT)构成。STM32 的通用定时器可以被用于:测量输入信号的脉冲长度(输入捕获)或者产生输出波形(输出比较和 PWM)等。使用定时器预分频器和 RCC 时钟控制器预分频器,脉冲长度和波形周期可以在几个微秒到几个毫秒间调整。STM32 的每个通用定时器都是完全独立的,没有互相共享的任何资源。
STM3F1 的通用 TIMx (TIM2、TIM3、TIM4 和 TIM5)定时器功能包括: 1)16 位向上、向下、向上/向下自动装载计数器(TIMx_CNT)。 2)16 位可编程(可以实时修改)预分频器(TIMx_PSC),计数器时钟频率的分频系数为 1~65535 之间的任意数值。 3)4 个独立通道(TIMx_CH1~4),这些通道可以用来作为: A.输入捕获 B.输出比较 C.PWM 生成(边缘或中间对齐模式) D.单脉冲模式输出 4)可使用外部信号(TIMx_ETR)控制定时器和定时器互连(可以用 1 个定时器控制另外一个定时器)的同步电路。 5)如下事件发生时产生中断/DMA: A.更新:计数器向上溢出/向下溢出,计数器初始化(通过软件或者内部/外部触发) B.触发事件(计数器启动、停止、初始化或者由内部/外部触发计数) C.输入捕获 D.输出比较 E.支持针对定位的增量(正交)编码器和霍尔传感器电路 F.触发输入作为外部时钟或者按周期的电流管理
STM32的定时器功能十分强大,由于篇幅限制,这里只介绍通用定时计数器、中断方式。使用时钟为APB2,72Mhz,通用定时器,向上计数模式,计数值中断溢出方式。
我们使用的是边沿对齐模式,可以看到在计数时钟脉冲下,数字为向上计数,通过设置计数比较值,在小于指定值范围内输出低电平,高于此值范围输出高电平。达到设定的计数值后自动重装载计数值,依次循环往复产生PWM信号。
下面来计算一下分频值、计数值来实现我们的需求。
CK_PSC : 当前定时器时钟源频率(72Mhz), PSC:预分频系数(从当前定时器时钟源频率的分频) ARR:计数周期(决定了PWM的周期) Duty:占空比 Reso:分辨率
计算实例:计算实例:生成一个1Khz,50%占空比,分辨率1%的pwm。 Freq = 72Mhz/ (PSC+1) / (ARR +1) = 1000HZ Duty = CCR / (ARR+1) = 50% = 0.5 Reso = 1 / (ARR+1) = 1% = 0.0 1 所以:ARR+1得100,CCR得50 Freq = 72000000 / (PSC+1) / 100 =1000 720000 / (PSC+1) = 1000 所以PSC+1 = 720 整理所得:ARR+1 = 100,CCR = 50,PSC+1 = 720
|