这一部分继续接着上一节来说,是上一节的拓展
目录
STM32 PWM输出
前言
一、PWM原理
二、PWM输出配置
2.1 输出模式
三、代码
四、输入捕捉
4.1 捕捉电路
4.1.1 输入捕获滤波器
4.1.2 输入捕获极性
4.1.3 输入捕获映射通道
4.1.4 输入捕获分频器
4.2 输入可以设置中断
五、代码部分
简单来说就是图像中靠下的过程,是上一节补充的内容
别人已经讲的很好了,建议看看别人的博客: STM32-一文搞懂通用定时器捕获/比较通道_定时器捕获与比较模式_BUG从入门到精通的博客-CSDN博客
参考博客STM32-一文搞懂通用定时器捕获/比较通道_定时器捕获与比较模式_BUG从入门到精通的博客-CSDN博客
简单解释一下这个图:上边是基于CNT向上计时器不断累加,ARR是一个峰值,比CCRX小输出就是0,比CCRX高就是1,所以PWM原理还是计数器。ARR确定了高电平1的频率(越高就意味着每个周期的时间越长),CCRX确定了占空比(高电平在这个周期内的时间)。
在定时器右下角的输出模式中,OC1就是PWM输出口
也就是说捕获/比较使能寄存器TIMx_CCMR1的输出OC1REF经过输出控制器来输出OC1的值
但是实际上该过程比较坎坷,抽象出来是这样的
也就是说:最左侧的(没画出来的是捕获/比较寄存器),设定了ARR以及CCRX经过OC1M[2:0]控制器得到OC1REF,在经过由TIMX_CCER(CC1P)控制,再次经过TIMX_CCER(CC1E)控制下到OC1。(中间控制器确实省略了不少)
该过程比较复杂,最主要的原因是涉及到了多个传感器定义,虽然在固件库里面被封装好了,但是还需要知道其原理。
捕获/比较模式寄存器 1 (TIMx_CCMR1)有OC1M[2:0]三位,这三位控制着输出模式,
当该三位是这样就会设定为PWM模式(我们也称呼这两种模式为模式一,模式二)(注意名称:CNT是向上计数器,CCR是设定的数值(上面定义过了)):
但:这里的有效不是说输出高低电平,只是说输出有效电平。
那么到底输出什么电平?
我们观察到在OC1REF到OC1之间还有很多步骤,其中就有一步:在OC1输出口前面有TIMX_CCER寄存器的CC1P位以及CC1E位来控制。这个寄存器不扩讲,我们只需要知道其中CC1P位和CC1E来控制就行了。
具体说:
CCER:CC1P位:输入/捕获1输出极性。0:高电平有效,1:低电平有效。
CCER:CC1E位:输入/捕获1输出使能。0:关闭,1:打开。
现在就明白了:前面设定OC1M[2:0] 如果是110(模式一)就要求输出有效电平,而这个有效电平又是高电平(TIMX_CCER寄存器的CC1P位控制的),最后再由输出使能端口使能输出就能够输出高电平了(模式二就反过来了)。
完结撒花。
在实际代码中很容易:
使能定时器3和相关IO口时钟。
1. 使能定时器3时钟:RCC_APB1PeriphClockCmd();
使能GPIOB时钟:RCC_APB2PeriphClockCmd();
2.初始化IO口为复用功能输出。函数:GPIO_Init();
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
3.这里我们是要把PB5用作定时器的PWM输出引脚,所以要重映射配置,所以需要开启AFIO时钟。同时设置重映射。(如果是其他串口可能就不需要配置)
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);
GPIO_PinRemapConfig(GPIO_PartialRemap_TIM3, ENABLE);
4.初始化定时器:ARR,PSC等:TIM_TimeBaseInit();
5.初始化输出比较参数:TIM_OC2Init();
6.使能预装载寄存器: TIM_OC2PreloadConfig(TIM3, TIM_OCPreload_Enable);
7.使能定时器。TIM_Cmd();
8. 不断改变比较值CCRx,达到不同的占空比效果:TIM_SetCompare2();//(一般都会确定一个固定的值)
原本不想说定时器豁免的,结果看到原子哥的ppt有这一节,继续讲吧。
上面原理抽象过来是这样的(确定一下中间的边沿检测器以及最后的输出IC1PS,也就是说中间都是预分频器)
原子哥原话:所谓的捕捉就是说:记录TIMx_CHx上的边沿信号,在边沿信号发生跳变(比如上升沿/下降沿)的时候,将当前定时器的值(TIMx_CNT)存放到对应的捕获/比较寄存器(TIMx_CCRx)里面,完成一次捕获。这部分将会拆开来叙述,相关的捕捉/比较寄存器TIMx_CCER、TIMx_DIER、TIMx_CR1、TIMx_CCR1等,会对应相关部分
这一部分主要是由引脚接口的脉冲电平经过CCMR1的控制到TI1F,CCMR1的ICF控制见上:
在主函数依旧很简单,一行初始化捕捉就行了。
但是在该函数中定义如下
① 初始化定时器和通道对应IO的时钟。
② 初始化IO口,模式为输入:GPIO_Init();
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD; //PA0 输入
③初始化定时器ARR,PSC
TIM_TimeBaseInit();
④初始化输入捕获通道
TIM_ICInit();
⑤如果要开启捕获中断,
TIM_ITConfig();
NVIC_Init();
⑥使能定时器:TIM_Cmd();
⑦编写中断服务函数:TIMx_IRQHandler();
代码中还有一些代码没有解释清楚,比方说TIM2CH1_CAPTURE_STA