STM32F103ZET6 PWM输出
1、通用定时器的PWM功能
STM32F103ZET6有4个通用定时器,分别是TIM2、TIM3、TIM4、TIM5。
通用定时器由一个可编程预分频器驱动的16位自动装载计数器构成。
通用定时器的很多功能与基本定时器是一样的,但是每个通用定时器都有4个IO口,可以用来测量输入信号的脉冲长度(输入捕获)或产生输出波形(输出比较和PWM)。
通用定时器可以用来输出PWM信号,每个通用定时器可以输出4路PWM信号。
2、通用定时器的输入/输出脚
每个通用定时器都具有4个输入/输出通道,即4个IO口,它们的对应关系如下图:

3、通用定时器的计数方式
通用定时器的框图如下:

图中TIMx_CH1、TIMx_CH2、TIMx_CH3、TIMx_CH4就是用来输出PWM的脚位,对应定时器的4个通道。
通用定时器的功能是在基本定时器功能上的扩展,定时部分跟基本定时器是差不多的,只是基本定时器只能是向上计数,而通用定时器既可以设置成向上计数、也可以设置成向下计数、或是设置成向上/向下计数。
通用定时器的向上计数模式跟基本定时器是一样的。
通用定时器的向下计数模式:
在向下计数模式中,计数器先从TIMx_ARR自动装载寄存器中获取计数初值,然后开始向下计数,当计数到0时产生中断并重新从TIMx_ARR自动装载寄存器中获取初值。
通用定时器的向上/向下计数模式:
在向上/向下计数模式中,计数器从0开始计数到TIMx_ARR-1的值后产生中断,然后向下计数到1并产生中断;然后再从0开始重新计数。
在向上/向下计数模式中,不能对TIMx_CR1寄存器中的DIR位赋值,DIR位由硬件更新,可以通过读取DIR位来确认当前是向上计数还是向下计数。
在向上/向下计数模式中,如果内部时钟分频因子为1,TIMx_ARR自动装载寄存器的值为0x06,那么定时器的的时序图如下:

从图中可以看到,计数器向上计数到0x05的时候产生了溢出中断,计数器向下计数到1的时候产生了溢出中断。
通用定时器通过TIMx_CR1控制寄存器的CMS[1:0]位和DIR位来控制定时器的计数方向。
4、通用定时器PWM输出的工作原理
通用定时器PWM输出的频率由TIMx_ARR自动重装载寄存器和TIMx_PSC预分频器寄存器确定、占空比由TIMx_CCRx捕获/比较寄存器决定。
通用定时器PWM的工作模式:
通用定时器的PWM可以设置为两种模式:PWM模式1和PWM模式2,模式的选择是根据TIMx_CCMRx捕获/比较模式寄存器OCxM[2:0](x范围是1~4,表示4个通道)这三个位的设置决定的。
这里需要特别注意的是每个定时器的PWM输出通道有4个,但是捕获/比较模式寄存器只有2个:TIMx_CCMR1和TIMx_CCMR2,TIMx_CCMR1寄存器的低16位为有效位,低8位用来配置通道1,高8位用来配置通道2;TIMx_CCMR2寄存器也是低16位为有效位,低8位用来配置通道3,高8位用来配置通道4。也就是说每8个位配置一个通道,这8个位的配置参数是一样的,不一样的只是配置的通道不一样。
PWM模式1:
当OCxM[2:0] = 110时,PWM处于模式1下。
当定时器的计数器的值小于捕获/比较寄存器的值时(TIMx_CNT < TIMx_CCRx),输出通道输出有效电平。
当定时器的计数器的值大于等于捕获/比较寄存器的值时(TIMx_CNT >= TIMx_CCRx),输出通道输出无效电平。
PWM模式2:
当OCxM[2:0] = 111时,PWM处于模式2下。
当定时器的计数器的值小于捕获/比较寄存器的值时(TIMx_CNT < TIMx_CCRx),输出通道输出无效电平。
当定时器的计数器的值大于等于捕获/比较寄存器的值时(TIMx_CNT >= TIMx_CCRx),输出通道输出有效电平。
通过对比可以看出,PWM模式1和PWM模式2的输出电平刚好是相反的。
有效电平和无效电平:
在PWM模式1和PWM模式2的介绍中可以看到PWM输出通道输出分为有效电平和无效电平两种状态。有效和无效电平是根据TIMx_CCER捕获/比较使能寄存器的bit1位CCxP来决定是什么状态的。
当CCxP = 0时,输出通道的有效电平为高电平,无效电平为低电平。
当CCxP = 1时,输出通道的有效电平为低电平,无效电平为高电平。
当CCxP = 0时,如果PWM处于模式1的状态下,当TIMx_CNT < TIMx_CCRx时,输出通道输出高电平,当TIMx_CNT >= TIMx_CCRx时,输出通道输出低电平;如果PWM处于模式2的状态下,当TIMx_CNT < TIMx_CCRx时,输出通道输出低电平,当TIMx_CNT >= TIMx_CCRx时,输出通道输出高电平。模式1和模式2刚好相反。
当CCxP = 1时,如果PWM处于模式1的状态下,当TIMx_CNT < TIMx_CCRx时,输出通道输出低电平,当TIMx_CNT >= TIMx_CCRx时,输出通道输出高电平。如果PWM处于模式2的状态下,当TIMx_CNT < TIMx_CCRx时,输出通道输出高电平,当TIMx_CNT >= TIMx_CCRx时,输出通道输出低电平。模式1和模式2刚好相反。
在PWM模式1或2下,TIMxCNT寄存器和TIMx_CCRx寄存器始终在进行比较(一句计数器的计数方向)以确定是否符合TIMx_CCRx <= TIMx_CNT或者TIMx_CNT <= TIMx_CCRx。
当使能定时器后,计数器开始计数,可以将定时器设置为向上计数、向下计数、向上/向上计数。
在STM3参考手册中,用边沿对齐模式来指示计数器向上计数、计数器向下计数这两种模式,具体是向上还是向下,需要根据TIMx_CR1寄存器的DIR位来设置,当DIR=0时是向上计数模式;当DIR=1时是向下计数模式。用中央对齐模式来指示计数器向上和向下同时计数的模式。
通过TIMx_CR1控制寄存器的bit6~bit5位CMS[1:0]来选择是边沿对齐模式还是中央对齐模式。
PWM边沿对齐模式:
定时器向上计数:
当TIMx_CR1寄存器的bit4位DIR为0时,定时器向上计数。
下图是PWM选择为模式1,有效电平为高电平,OCXREF指示输出的电平状态,TIMx_ARR的值为8,也就是计数器TIMx_CNT递增到8后清0从新计数。
从图中可以看,当CCRx = 4,若TIMx_CNT < 4,则OCXREF输出的是高电平;若TIMx_CNT >= 4,则OCXREF输出的是低电平。
当CCRx = 8,若TIMx_CNT < 8,则OCXREF输出高电平;若TIMx_CNT >= 8,则OCXREF输出低电平。
当CCRx > 8,则TIMx_CNT一直小于CCRx,则OCXREF一直保持高电平。
当CCRx = 0,则TIMx_CNT一直不小于CCRx,则OCXREF一直保持低电平。
从图中还可以看到,CCxIF中断状态位的变化,CCRx与TIMx_CNT每比较成功一次就会置位CCxIF,当CCRx > TIMx_CNT或CCRx = 0时,在定时器计数器溢出时,CCxIF会被置位。

定时器向下计数:
当TIMx_CR1寄存器的bit4位DIR为1时,定时器向下计数。
这个跟向上计数模式是差不多的,只是计数方向不一样。
PWM中央对齐模式:
当TIMx_CR1寄存器中的CMS位不为'00'时,定时器的计数方式为中央对齐模式。
根据不同的CMS位设置,比较标志可以在计数器向上计数时被置1、在计数器向下计数时被置1、或是在计数器向上和向下计数时被置1。
当定时器工作在中央对齐模式时,TIMx_CR1寄存器中的计数方向位DIR由硬件更新,DIR变为只读位,不能软件修改。
如下图是定时器工作在中央对齐模式时的PWM图形:

进入中央对齐模式时,软件不能同时修改TIMx_CR1寄存器中的DIR位和CMS位。
使用中央对齐模式最保险的方法,就是在启动计数器之前产生一个软件更新(设置TIMx_EGR寄存器中的UG位),不要在计数器工作的过程中修改计数器的值。
5、通用定时器PWM的配置流程
1、开启使用到的通用定时器的时钟,配置相应的输出通道的脚位为复用输出,如果脚位需要重映射,还需要根据具体需求进行重映射配置。
2、通过TIMx_CR1寄存器的bit6~bit5位CMS[1:0]来选择定时器的计数模式,如果设置的是边沿对齐模式,还需要设置TIMx_CR1寄存器的bit4位DIR来选择计数器是向上计数还是向下计数;若选择的是中央对齐模式,则不需要设置DIR位。
3、通过设置TIMx_ARR寄存器和TIMx_PSC寄存器来决定PWM输出的频率,如果TIMx_ARR寄存器需要使用缓冲功能,还需要将TIMx_CR1的bit7位ARPE位置1。
4、通过设置TIMx_CCRx捕获/比较寄存器来决定PWM输出的占空比。
5、通过捕获/比较模式寄存器TIMx_CCMRx配置相应的通道为输出和PWM的模式。这里需要注意的是每个定时器的捕获/比较模式寄存器只有两个,而通道有4个,这是应为TIMx_CCMR1配置的是CH1和CH2;而TIMx_CCMR2配置的CH3和CH4。TIMx_CCMR1寄存器的低8位配置的是CH1,高8位配置的是CH2;而TIMx_CCMR2寄存器的低8位配置的是CH3,高8位配置的是CH4。每8个位配置一个通道,每个通道配置的位都是相同的。通过TIMx_CCMRx寄存器的OCxM[2:0]位选择PWM的工作模式,OCxM[2:0]只有“110”和“111”这两个数值是配置为PWM模式。TIMx_CCMRx寄存器的CCxS[1:0]位用来配置通道是输出还是输入,这里将CCxS[1:0]设置为“00”,将通道配置为输出。
6、通过捕获/比较使能寄存器TIMx_CCER来配置输出通道的有效电平和使能相应的通道输出PWM。TIMx_CCER寄存器可以配置4个通道,每个通道占的bit位置不同。使用TIMx_CCER寄存器的CCxP位选择输出通道的有效电平的状态。通过置位TIMx_CCER寄存器的CCxE位来开启PWM信号输出到对应的脚位,也可以通过清零CCxE位来禁止PWM输出。
7、最后置位TIMx_CR1寄存器的bit0位CEN来启动定时器开始计数。
8、因为这里是配置PWM的输出功能,没有用到中断,所以不需要配置中断。
6、HAL库操作PWM输出
初始化代码如下:
TIM_HandleTypeDef TIM5_Handler_Init;
TIM_OC_InitTypeDef PWM_Handler_Init; void PWM_Init(void)
{
GPIO_InitTypeDef GPIO_InitStruct; __HAL_RCC_GPIOA_CLK_ENABLE();
__HAL_RCC_TIM5_CLK_ENABLE(); GPIO_InitStruct.Pin = GPIO_PIN_0;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); 17 HAL_GPIO_WritePin(GPIOA, GPIO_PIN_0, GPIO_PIN_SET); TIM5_Handler_Init.Instance = TIM5;
TIM5_Handler_Init.Init.Prescaler = -;
TIM5_Handler_Init.Init.Period = ;
TIM5_Handler_Init.Init.CounterMode = TIM_COUNTERMODE_UP;
HAL_TIM_Base_Init(&TIM5_Handler_Init); PWM_Handler_Init.OCMode = TIM_OCMODE_PWM1;
PWM_Handler_Init.Pulse = ;
PWM_Handler_Init.OCPolarity = TIM_OCPOLARITY_HIGH;
PWM_Handler_Init.OCFastMode = TIM_OCFAST_DISABLE; HAL_TIM_PWM_ConfigChannel(&TIM5_Handler_Init,&PWM_Handler_Init,TIM_CHANNEL_1); HAL_TIM_PWM_Start(&TIM5_Handler_Init,TIM_CHANNEL_1);
}
这里配置的是通用定时器TIM5的通道1来作为PWM输出,对应的IO为PA0。
第1、2行定义两个结构体变量,TIM5_Handler_Init用来初始化通用定时器,PWM_Handler_Init用来初始化PWM输出通道。
第8、9行是开启GPIA和TIM5定时器的时钟。
第11到17行配置的是PA0口为复用输出功能。
第19到23行配置的是TIM5定时器的自动重装值和预分频的值,还有TIM5定时器计数模式。
第25到28行配置的是PWM功能,第25行是选择PWM的工作模式;第26行是设置PWM的占空比;第27行是选择通道的有效电平;
第30行是对PWM输出通道进行初始化。
第32行是使能PWM信号输出到对应的脚位和启动TIM5定时器。
STM32F103ZET6 PWM输出的更多相关文章
- Arduino学习经验(一)之解决舵机库和pwm输出冲突
一.前言 最近在公司学习Arduino uno ,用它实现小车超声波避障功能.实现的功能很简单,就是在小车前方挂一个超声波模块,当碰到障碍物时,会通过舵机进行摆头,判断两边的距离,进行左右转弯.但是碰 ...
- 关于普通定时器与高级定时器的 PWM输出的初始化的区别
不管是普通定时器还是高级定时器,你用哪个通道,就在程序里用OC多少.比如CH3对应OC3 TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; TIM_ ...
- (五)转载:通用定时器PWM输出
1. TIMER输出PWM基本概念 脉冲宽度调制(PWM),是英文“Pulse Width Modulation”的缩写,简称脉宽调制,是利用微处理器的数字输出来对模拟电路进行控制的一种非常有 ...
- 16路PWM输出的pca9685模块
今天要介绍的就是该模块,该模块是16路pwm模块,使用I2C总线可以控制16路舵机(led). 接线OE空着就可以,其他VCC是芯片供电+5,SCL时钟线,SDA信号线,GND地线. 芯片介绍可以看: ...
- 关于STM32CubeMX使用LL库设置PWM输出
HAL和LL库 HAL是ST为了实现代码在ST家族的MCU上的移植性,推出的一个库,称为硬件抽象层,很明显,这样做将会牺牲存储资源,所以项目最后的代码比较冗余,且运行效率大大降低,运行速度受制于fla ...
- TIMER门控模式控制PWM输出长度
TIMER门控模式控制PWM输出长度 参照一些网友代码做了些修改,由TIM4来控制TIM2的PWM输出长度, 采用主从的门控模式,即TIM4输出高时候TIM2使能输出 //TIM2 PWM输出,由TI ...
- STM32 PWM输出(映射)
STM32 的定时器除了 TIM6 和 7.其他的定时器都可以用来产生 PWM 输出.其中高级定时器 TIM1 和 TIM8 可以同时产生多达 7 路的 PWM 输出.而通用定时器也能同时产生多达 4 ...
- STM32 HAL库学习系列第4篇 定时器TIM----- 开始定时器与PWM输出配置
基本流程: 1.配置定时器 2.开启定时器 3.动态改变pwm输出,改变值 HAL_TIM_PWM_Start(&htim4, TIM_CHANNEL_1); 函数总结: __HAL_TIM ...
- NUCLEO-L053R8 TIM定时器 PWM输出
TIM2 PWM输出测试 今天给大伙分享一个TIM2 PWM输出小实验. 实验开发板:Nucleo-L053R8,即STM32L053R8T6. 开发环境:MDK5 图1 - 工程界面 本次实验测试的 ...
随机推荐
- Azure CLI 简单入门
Azure CLI 是什么 Azure 命令行接口 (CLI) 是用于管理 Azure 资源的 Microsoft 跨平台命令行体验. Azure CLI 易于学习,是构建适用于 Azure 资源的自 ...
- JS循环嵌套的执行原理
[逆战班] 循环嵌套是指在一个循环语句中再定义一个循环语句的语法结构,外循环执行一次,内循环全部执行完,直到外循环执行完毕,整个循环结束. while.do.. while和for循环语句都可以进行嵌 ...
- CSS 权重图
关系图 图片出处我找不到了. 结论 权重从高到低排序 1. !important 2. style 3. #id 4. .class .child-class 5. .class1.class2 6. ...
- C# .Net Core 3.1 中关于Process.Start 启动Url链接的问题
WPF 项目迁移到.Net Core中时居然出了一堆问题...(很无语) 今天在使用的时候居然发现Process.Start居然打不开Url链接了? 报 找不到指定文件 的异常?! 一.bug重现 首 ...
- Redis05——Redis Cluster 如何实现分布式集群
前面一片文章,我们已经说了Redis的主从集群及其哨兵模式.本文将继续介绍Redis的分布式集群. 在高并发场景下,单个Redis实例往往不能满足业务需求.单个Redis数据量过大会导致RDB文件过大 ...
- MySQL记录操作(增删改)
概览 MySQL数据操作: DML 在MySQL管理软件中,可以通过SQL语句中的DML语言来实现数据的操作,包括 使用INSERT实现数据的插入 UPDATE实现数据的更新 使用DELETE实现数据 ...
- SpringCloud之Hystrix服务降级入门全攻略
理论知识 Hystrix是什么? Hystrix是由Netflix开源的一个服务隔离组件,通过服务隔离来避免由于依赖延迟.异常,引起资源耗尽导致系统不可用的解决方案.这说的有点儿太官方了,它的功能主要 ...
- Rational Rose 2007破解版
首先下载好软件,链接在这里 链接:https://pan.baidu.com/s/1op-W-ZX1tqefHffs3m-r0A 提取码:0jwm 这里面包含了Rational Rose 2007版的 ...
- 强连通分量SCC 2-SAT
强连通分量SCC 2-SAT 部分资料来自: 1.https://blog.csdn.net/whereisherofrom/article/details/79417926 2.https://ba ...
- Javascript的document对象
对象属性 document.title //设置文档标题等价于HTML的<title>标签 document.bgColor / ...