系列文章目录
嵌入式|蓝桥杯STM32G431(HAL库开发)——CT117E学习笔记01:赛事介绍与硬件平台
嵌入式|蓝桥杯STM32G431(HAL库开发)——CT117E学习笔记02:开发环境安装
嵌入式|蓝桥杯STM32G431(HAL库开发)——CT117E学习笔记03:G4时钟结构
嵌入式|蓝桥杯STM32G431(HAL库开发)——CT117E学习笔记04:从零开始创建工程模板并开始点灯
嵌入式|蓝桥杯STM32G431(HAL库开发)——CT117E学习笔记05:Systick滴答定时器
嵌入式|蓝桥杯STM32G431(HAL库开发)——CT117E学习笔记06:按键输入
嵌入式|蓝桥杯STM32G431(HAL库开发)——CT117E学习笔记07:ADC模数转换
嵌入式|蓝桥杯STM32G431(HAL库开发)——CT117E学习笔记08:LCD液晶屏
嵌入式|蓝桥杯STM32G431(HAL库开发)——CT117E学习笔记09:EEPROM
嵌入式|蓝桥杯STM32G431(HAL库开发)——CT117E学习笔记10:USART串口通讯
嵌入式|蓝桥杯STM32G431(HAL库开发)——CT117E学习笔记11:数字电位器MCP4017
嵌入式|蓝桥杯STM32G431(HAL库开发)——CT117E学习笔记12:DAC数模转换
嵌入式|蓝桥杯STM32G431(HAL库开发)——CT117E学习笔记13:RTC实时时钟
嵌入式|蓝桥杯STM32G431(HAL库开发)——CT117E学习笔记14:PWM捕获
嵌入式|蓝桥杯STM32G431(HAL库开发)——CT117E学习笔记15:PWM输出
嵌入式|蓝桥杯STM32G431(HAL库开发)——CT117E学习笔记16:蓝桥杯编程手册
嵌入式|蓝桥杯STM32G431(HAL库开发)——CT117E学习笔记17:第十四届省赛真题
前言
这节讲解一下PWM捕获的基础知识。PWM捕获是指我们的单片机可以测量输入到它管脚上的方波的频率或者占空比,捕获就是说我们可以捕捉外部方波的信息。这就是我们这节要学习的内容。
一、基础知识
首先我们看一下电路图,这里有两个555芯片构成了一个方波发生器。
我们可以通过R40和R39两个电位器,就可以在555芯片的3号管脚输出一个方波,方波的频率就是通过R40和R39进行调节。3号管脚通过跳帽J9、J10接入PA15和PB4两个管脚。PA15和PB4分别可以配置成TIM2_CH1和TIM3_CH1,也就是定时器2的1通道和定时器3的1通道,用他们来捕获外部方波的频率和占空比。
捕获频率的作用有很多,比如说无人机上很多接收机的信号都是方波信号,也可以用来测量霍尔传感器的输出等等。但是我们这里只需要测量555的输出就行了。我们不需要知道555的具体接法是什么,只需要知道他可以通过调节这两个电阻就能产生不同频率的方波就行了,而我们的任务就是要用单片机测量他们的频率。另外还要注意好每个管脚分别对应着定时器的哪个通道。
此外呢,我们还要知道如何用示波器来观察方波的频率和占空比,只需要把示波器接在J9、J10两个跳线上就行了,我们调节R39、R40就可以看到方波的频率是在变化的。大致范围是在1-23kHz,并且频率太快(20k以上)的话波形是会失真的,波形正常时的频率范围应该在5k左右。占空比大概就是在50%。
二、测量单路频率
我们先研究U8芯片,通过R40可以产生频率可变的方波,然后通过跳帽J10接到了PA15管脚,对应TIM2_CH1通道来捕获。
首先看一下编程思路:每次上升沿中断,获取CNT值(定时器的计数值),并重新清零CNT值,重新计时。CNT的值就是一个PWM的周期,通过周期可以获得其频率(周期的倒数)。
我们可以把定时器配置成每us加1,那么如果CNT=1000,就相当于周期就是1ms,对应的频率就是1kHz。
程序设计步骤:
1.用“模板”生成代码
2.配置TIM2的PA15作为TIM2_CH1的输入捕获,注意要配置输入捕获模式,并勾选中断NVIC(一定不能忘)
3.根据需求配置TIM2_CH1的分频值,推荐配置成1us计数一次(因为系统时钟80MHz,我们想要1us就要1MHz,也就是分频80,因为从0开始算所以设置成79。up是上升沿产生中断,默认,不用更改。Counter Period是计时周期,它是32位的,也就是0—0xffffffff,如果超过这个这个周期就会溢出,所以我们把它设置成最大。)
4.移植文件到编程工程
- main.c包含tim.h头文件
- 添加tim.c的源文件和TIM相关的HAL库驱动函到工程中
- 在stm32g4xx_hal_conf.h中启动TIM模块
- 在stm32g4xx_it.c中移植TIM2_IRQHandler中断服务函数
- 在主函数中调用MX_TIM2_Init()定时器初始化函数和HAL_TIM_IC_Start_IT(&htim2,TIM_CHANNEL_1)启动定时器2捕获功能
- 在HAL_TIM_IC_CaptureCallback回调函数里,获取CNT值,计算PWM的频率
前四步都是常规的移植步骤,我们前面已经做过很多次,下面重点讲解一下后面两步:定时器捕获启动函数和中断回调函数。
MX_TIM2_Init()初始化之后,我们在后面加上HAL_TIM_IC_Start_IT(&htim2,TIM_CHANNEL_1)启动定时器2捕获。这样只要有up输入进到PA15,我们的定时器就会产生一个中断,然后就可以在中断处理函数中处理了。
下面我们就可以用HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)回调函数了,这个回调函数我们可以在stm32g4xx_it.c中找到HAL_TIM_IRQHandler(),即TIM的中断处理函数,然后在里面就能找到了。
这是一个弱定义的函数,我们把它复制到main.c中编辑它的功能。编程思路之前已经讲过了,中断后开始计时,每1us计时一次作为CNT,回调函数中先要__HAL_TIM_GetCounter(&htim2)获取之前计时的CNT,再__HAL_TIM_SetCounter(&htim2,0)设置重新计时,然后计算得到频率,最后重新使能中断启动函数(否则只会中断一次)。
//pwm capture
u32 tim2_cnt1=0;
u32 f1=0;
void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)
{
tim2_cnt1 = __HAL_TIM_GetCounter(&htim2); //获取CNT
__HAL_TIM_SetCounter(&htim2,0);//CNT置0,重新计数
f1=1000000/tim2_cnt1;//计算频率
HAL_TIM_IC_Start_IT(&htim2,TIM_CHANNEL_1);//重新启动中断
}
这样我们就能得到R40输出的方波频率f1了。我们可以把它显示在LCD上,也可以接在示波器上看一下波形,频率对不对。接示波器的时候一头接地,一头接J10。