首先,本人虽然初学STM32但极力反对一种误人子弟的观点:“对于STM32这样级别的MCU,有库函数就不用去看寄存器怎么操作的了!”
好了,言归正传,最近总看到很多朋友对于PWM这个实验有很多的疑惑,看到原子也在极力的回复也挺累的(体谅一下幸苦的原子大神,(*^__^*) ),所以我打算写这么一篇文字来阐述一下我个人对STM32的PWM的理解。
首先来说,你要使用PWM模式你得先选择用那个定时器来输出PWM吧!除了TIM6、TIM7这两个普通的定时器无法输出PWM外,其余的定时器都可以输出PWM,每个通用定时器可以输出4路PWM,高级定时器TIM1、TIM8每个可输出7路PWM,这里为了方便起见,我们选择与实验相同的TIM3的通道2来说明。选好定时器及通道后,下一步就是要使能定时器的时钟,根据需要看看是否需要重映射IO,然后就是配置输出PWM的IO及定时器,到这里原子的视频及例程都有详细的介绍,这里只需要提一点有些网友疑惑的TIM_TimeBaseStructure.TIM_ClockDivision = 0;这句话是什么作用?其实仔细看过技术手册后发现这句话与PWM输出实验其实是没关系的,这句话是设置定时器时钟(CK_INT)频率与数字滤波器(ETR,TIx)使用的采样频率之间的分频比例的(与输入捕获相关),0表示滤波器的频率和定时器的频率是一样的。至于其余部分,我就不再赘述。做完这些准备工作后,我就针对大多数朋友疑惑的地方——PWM模式的初始化设置做一个详细的阐述:先贴代码
1 TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2; //选择定时器模式:TIM脉冲宽度调制模式2
2 TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比较输出使能
3 TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //输出极性:TIM输出比较极性高
4 TIM_OC2Init(TIM3, &TIM_OCInitStructure); //根据T指定的参数初始化外设TIM3 OC2
5 TIM_OC2PreloadConfig(TIM3, TIM_OCPreload_Enable); //使能TIM3在CCR2上的预装载寄存器,即TIM3_CCR2的预装载值在更新事件到来时才能被传送至当前寄存器中。
6 TIM_Cmd(TIM3, ENABLE); //使能TIM3
这6句话就把PWM的通道配置好了,一句句来解释:
这里原子选择的PWM2模式,为什么选择的是PWM2模式呢?为什么不选择PWM1模式呢?两者又有什么区别呢?下面我们就一探究竟,PWM1和PWM2模式是由CCMR1的OC1M和OC2M来决定的,因为我们选择的是是通道2,所以设置的是OC2M,再看相关介绍
OC1M[2:0]:输出比较1模式(Output compare 1 enable)
110:PWM模式1- 在向上计数时,一旦TIMx_CNT无效电平;在向下计数时,一旦TIMx_CNT>TIMx_CCR1时通道1为无效电平(OC1REF=0),否
则为有效电平(OC1REF=1)。
111:PWM模式2- 在向上计数时,一旦TIMx_CNT有效电平;在向下计数时,一旦TIMx_CNT>TIMx_CCR1时通道1为有效电平,否则为无效电
平。
看到红色的“有效电平”了吧,那么这又是谁定义的呢?别急,再看手册,可知它是由CCER这个寄存器的CCxP来决定的这里是通道2,所以是CC2P,继续看介绍
CC1P:输入/捕获1输出极性(Capture/Compare 1 output polarity) 位1
CC1通道配置为输出:
0:OC1高电平有效
1:OC1低电平有效
现在很清楚了吧,又因为第3句,TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //输出极性:TIM输出比较极性高,所以这里我们设置的CC2P是0,也就是默认的OC2高电平有效。这样第3句话也捎带着解释了,哈哈!由于我们的战舰板的LED是低电平亮,而刚开始的给CC2P用来设置占空比的led0pwmval为0它是小于等于TIM3_CNT的,也就符合TIMx_CNT>=TIMx_CCR1时通道2输出有效电平,也就是高电平,所以你把原子的例程原封不动的Down到板子里,会看到刚上电,LED灯是不亮的。现在这块明白了吧!若你觉得还是不爽,我就非得用PWM1模式,那也可以,就像有个网友说“我拿原子的PWM Code就改了一个PWM1模式,按原子讲的PWM1和PWM2的输出是相反的啊,可是我上电发现LED是常亮的啊?怎么回事啊,求解释啊。。。”我们来分析一下这位朋友的代码,他把PWM2改成了PWM1,别的什么都没动,那么现在符合“PWM模式1- 在向上计数时,一旦TIMx_CNT,否则为无效电平。“结果必然是就是LED长亮喽,要想得到跟原代妈一样的效果,那就把CC2P设置成1,OC2低电平有效,这样就可以了,有兴趣的朋友可以动手试试!(实践出真知吗!)
好了,废了这么多话,也不早了 洗洗睡吧!希望这篇文字对PWM有疑惑的朋友有所帮助!希望大家共同进步!分享是一种快乐,欢迎批评指正!
关键字:PWM模式 STM32
引用地址:
关于PWM模式
推荐阅读最新更新时间:2024-03-16 15:38
Stm32定时器中断触发AD采样
Stm32的ADC有DMA功能这都毋庸置疑,也是我们用的最多的!然而,如果我们要对一个信号(比如脉搏信号)进行定时采样(也就是隔一段时间,比如说2ms),有三种方法: 1)使用定时器中断每隔一定时间进行ADC转换,这样每次都必须读ADC的数据寄存器,非常浪费时间! 2)把ADC设置成连续转换模式,同时对应的DMA通道开启循环模式,这样ADC就一直在进行数据采集然后通过DMA把数据搬运至内存。但是这样做的话还得加一个定时中断,用来定时读取内存中的数据! 3)使用ADC的定时器触发ADC转换的功能,然后使用DMA进行数据的搬运!这样只要设置好定时器的触发间隔,就能实现ADC定时采样转换的功能,然后可以在程序的死循环中一直检
[单片机]
stm32驱动lora模块sx1278
开发环境 keil5 子设备读取Ds18b20数据,通过iic显示到OLED 屏幕上,同时用spi协议发送给lora,再传给网关。 网关接收到数据在OLED 屏幕上显示。 单片机源码: #include stdio.h #include DELAY/Delay.h #include UART/uart.h #include ADC/ADC.h #include LED/LED.h #include IIC/IIC.h #include OLED/OLED.h #include SPIx/SPIx.h #include SX1278/SX1278.h #define ALARM 22 int ma
[单片机]
【STM32】2—按键控制
0 实验预期效果: ① 上电复位时LED处于熄灭状态; ② 按下KEY1,LED点亮; ③ 按下KEY2,LED熄灭; 1 相关原理图: 2 代码编写 while (1) { /* USER CODE BEGIN 3 */ if(0 == HAL_GPIO_ReadPin(KEY1_GPIO_Port, KEY1_Pin)) { HAL_GPIO_WritePin(LED_GPIO_Port,LED_Pin,GPIO_PIN_SET); } if(0 == HAL_GPIO_ReadPin(KEY2_GPIO_Port, KEY2_Pin)) {
[单片机]
STM32使用J-Link仿真相关汇总
目录: 一、SWD实时仿真接线 二、仿真设置 三、仿真时问题的解决 1、仿真时添加变量或数组 2、程序下载 3、尽量不要由J-Link给线路板供电 4、仿真器与线路板连接需可靠 5、使用J-Link时,Keil软件出现无响应 ---------------------------------------- 所有的操作基于WIN XP,stm32使用J-Link(SWD模式)。 另可参见 系统、软件、数码 / Keil编译软件的使用汇总 (三、Keil5.12编译报错的处理)。 ----------------------------------------------------------------------------
[单片机]
STM32开发笔记36: 串口不能正确发数的解决方法
单片机型号:STM32L053R8T6 今天这个问题一定要记录下来,使用485总线时,串口不能正确发送数据。串口的驱动程序已应用在多个实际项目中,自己并未认识到串口的驱动程序会有什么问题,而且在STM32F0芯片中,已经使用过了485,那时很是正常,所以这次问题的出现,倍感以外。 先说一下现象,使用485向计算机发数,计算机接到的全部都是0x00,开始怀疑很多问题,例如连线焊接等,一一排除,不能解决。使用示波器进行查看,发现单片机发送的数据就是这样的,很是奇怪。好在线路板设计时,单片机所在的线路板可以取下,将其插在带有USB转串口的板子上,发现一切正常。这说明单片机所在的电路是没有问题的,应该在外设板上。继续查找原因,直到
[单片机]
stm单片机型号的意义 stm8和stm32的烧写程序的区别 stm8读取程序
stm单片机型号的意义 STM单片机型号一般由几个部分组成,每个部分都代表着不同的意义: 第一部分:STM或STM32或STM8,代表单片机的品牌和系列。STM32系列是基于ARM Cortex-M内核的单片机系列,而STM8系列则是基于ST8内核的单片机系列。 第二部分:数字,代表单片机的性能等级,数字越高代表性能越高,功能也更加强大。例如,在STM32系列中,STM32F0代表基本型号,STM32F1代表通用型号,STM32F2代表高性能型号,STM32F3代表模拟型号,STM32F4代表高性能数字信号控制型号等。 第三部分:字母,代表单片机的特性和功能。例如,在STM32F4系列中,H代表高速器件,C代表低功耗器件,E代
[单片机]
STM32的SWD使用说明
SWD下载口使用说明 STM32的GPIO的默认下载口是JTAG,所以在需要在引脚上映射到SWD功能。 必须保证JTAG的部分引脚配置放置在所有GPIO配置的最后,或者是在使用那部分引脚时使用map映射函数。 /*JTAG做普通引脚时GPIO最后配置*/ void JTAG_GPIO_Config(void) { GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE); GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable, ENABLE
[单片机]
STM32定时器的几种用法
一、常用的定时功能 (1)基本、通用、高级定时器都有最基本的定时功能,定时功能用到的函数如下: HAL_ TI M_Base_Init 初始化定时,包括分频、 预装值等。 HAL_TIM_ConfigClockSource 选择定时器的 时钟 源 HAL_TIM_Base_Start_IT 开始定时器 HAL_TIM_PeriodElapsedCallb ac k 超时后的回调函数 (2)Cubemx的配置,不管什么定时器,都是这个配置,注意开启中断,计算好最终的定时器时钟 (3)代码片段 1 void MX_TIM12_Init(void) 2 { 3 TIM_ClockConfigTypeDef sClo
[单片机]