江科大/江协科技 STM32学习笔记P17

文章目录


一、TIM输入捕获

输入捕获与输出比较的关系

在输出比较中,CNT和CCR作为比较电路的输入,根据CNT和CCR的大小关系,从通道引脚输出高低电平。

输入捕获,一旦左边的边沿信号产生,比如上升沿,输入滤波和边沿检测电路就会检测到上升沿,让输入捕获电路产生动作,控制后续电路,让当前CNT的值锁存到CCR寄存器中

频率测量

对于STM32测频率而言,只能测数字信号,如果要测正弦波,还需要搭建信号预处理电路,比如最简单的是用运放搭建一个比较器,把正弦波转换为数字信号输入给STM32,如果测量的信号电压非常高,需要考虑隔离的问题,比如用隔离放大器、电压互感器等元件隔离高压端和低压端,保证电路的安全。

测频法

适合测量高频信号,测量结果更新的慢,实际上是闸门时间内的平均频率

测周法

适合测量低频信号,测量结果更新的快,周期的倒数就是频率,用标准频率测一个周期,再取倒数

输入捕获的电路

左边是四个通道的引脚,通道1、2、3端口接了一个异或门。

异或门的执行逻辑

当三个输入引脚的任何一个有电平翻转时,输出引脚就产生一次电平翻转,之后输出通过数据选择器到达输入捕获通道1,数据选择器如果选择上面一个,输入捕获通道1的输入就是三个引脚的异或值,如果选择下面一个,异或门不起作用,四个通道各用各的引脚。异或门的作用是为三相无刷电机服务,无刷电机有3个霍尔传感器检测转子的位置,可以根据转子的位置进行换相,有了这个异或门就可以在前三个通道接上无刷电机的霍尔传感器,定时器就作为无刷电机的接口定时器,驱动换相电路工作。

接着输入信号来到了输入滤波器和边沿检测器,输入滤波器可以对输入信号进行滤波,避免高频毛刺信号误触发,边沿检测器可以选高电平或低电平触发,每一个通道都设计两套滤波和边沿检测电路, 第一套电路经过滤波和极性选择,得到TI1FP1,输入给通道一的后续电路,第二套电路经过另一套波和极性选择得到TI2FP2,输入给下面通道2的后续电路,下面同理。

就CH1和CH2来说,两个信号可以各走各的,也可以交叉让CH2引脚输入给通道1,或CH1引脚输入给通道2。这样做的目的第一可以通过数据选择器灵活切换后续捕获电路的输入,第二可以把一个引脚的输入同时映射到两个捕获单元,是PWMI模式的经典结构,PWMI模式简单来说第一个捕获通道使用上升沿触发,用来捕获周期,第二个通道用下降沿触发,用来捕获占空比,两个通道同时对一个引脚进行捕获,就可以同时测量频率和占空比了。

再接着看预分频器,每个通道各一个,可以选择对前面的信号进行分频,分频后的触发信号可以触发捕获电路进行工作,每来一个触发信号,CNT的值就会向CCR转运一次,转运的同时发生一个捕获事件,事件会在状态寄存器置标志位,同时也可以产生中断,如果需要在捕获的瞬间处理一些事,就可以开启这个捕获中断,这就是整个电路的工作流程。

举个例子,配置上升沿触发捕获,每来一个上升沿,CNT转运到CCR一次,又因为CNT计数器是由内部的标准时钟驱动的,所以CNT的数值可以用来记录两个上升沿之间的时间间隔(周期),取倒数就是测周法测量的频率了。另外注意每次捕获之后都要把CNT清零,这样下次上升沿再捕获时取出的CNT才是两个上升沿的时间间隔,这个操作可以用主从触发模式自动完成。

输入捕获通道

TI1就是CH1的引脚,TI1F就是滤波后的信号, f D T S f_{DTS} fDTS是滤波器的采样时钟来源,CCMR1寄存器里的ICF位可以控制滤波器的参数,滤波器的工作原理就是以采样频率对输入信号进行采样,当连续N个值都为高电平,输出才为高电平,连续N个值都为低电平,输出才为低电平,如果信号出现抖动导致连续采样N个值不全一样,输出则不变,达到滤波效果。采样频率越低,采样个数N越大,滤波效果越好。

滤波后的信号通过边沿检测器,捕获上升沿或下降沿,用CCER寄存器里的CC1P位,就可以选择极性了,最终得到TIFP1触发信号,通过数据选择器进入通道1后续的捕获电路,CC1S位可以对数据选择器进行选择,之后ICPS位可以配置分频器,最后CC1E位控制输出使能或失能,如果使能了输出,输入端产生指定边沿信号,经过层层电路到最后,让CNT的值转运到CCR里,而每捕获一次CNT的值,都要把CNT清零一下,便于下次捕获,如何自动清零CNT,首先TI1FP1信号和TI1的边沿信号都可以通向从模式控制器,比如TI1FP1信号的上升沿触发捕获,上面还可以同时触发从模式,从模式里有电路可以自动完成CNT清零

主从触发模式

主模式可以将定时器内部的信号,映射到TRGO引脚,用于触发别的外设

从模式就是接收其他外设或者自身外设的一些信号,用于控制自身定时器的运行,也就是被别的信号控制

触发源选择就是选择从模式的触发信号源,选择指定的一个信号得到TRGI,然后去触发从模式,如果想让TI1FP1信号自动触发CNT清零,触发源选择就可以选中TI1FP1,从模式执行的操作,可以选择执行Reset的操作

注意触发源选择只有TI1FP1和TI1FP2,没有TI3和TI4的信号,如果想用从模式自动清零CNT,就只能用通道1和通道2,对于通道3和通道4就只能开启捕获中断,在中断里手动清零

输入捕获基本结构

CNT是测周法中计数的东西,经过预分配后的时钟频率,就是驱动CNT的标准频率fc,标准频率=72M/预分频系数。下面是输入捕获通道1的GPIO口,输入一个左上角的方波信号,经过滤波器和边沿检测,选择TI1FP1为上升沿触发,之后输入选择直连的通道,分频器选择不分频,当TI1FP1出现上升沿之后,CNT的当前计数值转运到CCR1,同时触发源选择,选中TI1FP1为触发信号,从模式选择复位操作,这样TI1FP1的上升沿也会通过上面一路触发CNT清零,CNT的值转到CCR,0转移到CNT。电路工作时,CCR1的值始终保持为最新一个周期的计数值N, f c / n f_c/n fc/n就是信号的频率

PWMI基本结构

PWMI模式,使用两个通道同时捕获一个引脚,可以同时测量周期和占空比。首先TI1FP1配置上升沿触发,触发捕获和清零CNT,正常地捕获周期,再来一个TI1FP2,配置为下降沿触发,通过交叉通道触发通道2的捕获单元,就是在下降沿时CCR2捕获此时的CNT计数值(高电平期间的计数值),不触发CNT清零,这样一个周期后CCR1是一整个周期计数值,CCR2是高电平期间的计数值,CCR2/CCR1就是占空比

输入捕获模式测频率

main.c

c 复制代码
#include "stm32f10x.h"                  // Device header
#include "Delay.h"
#include "OLED.h"
#include "PWM.h"
#include "IC.h"

int main(void)
{
	/*模块初始化*/
	OLED_Init();		//OLED初始化
	PWM_Init();			//PWM初始化
	IC_Init();			//输入捕获初始化
	
	/*显示静态字符串*/
	OLED_ShowString(1, 1, "Freq:00000Hz");		//1行1列显示字符串Freq:00000Hz
	
	/*使用PWM模块提供输入捕获的测试信号*/
	PWM_SetPrescaler(720 - 1);					//PWM频率Freq = 72M / (PSC + 1) / 100
	PWM_SetCompare1(50);						//PWM占空比Duty = CCR / 100
	
	while (1)
	{
		OLED_ShowNum(1, 6, IC_GetFreq(), 5);	//不断刷新显示输入捕获测得的频率
	}
}

输入捕获模式测占空比

main.c

c 复制代码
#include "stm32f10x.h"                  // Device header
#include "Delay.h"
#include "OLED.h"
#include "PWM.h"
#include "IC.h"

int main(void)
{
	/*模块初始化*/
	OLED_Init();		//OLED初始化
	PWM_Init();			//PWM初始化
	IC_Init();			//输入捕获初始化
	
	/*显示静态字符串*/
	OLED_ShowString(1, 1, "Freq:00000Hz");		//1行1列显示字符串Freq:00000Hz
	OLED_ShowString(2, 1, "Duty:00%");			//2行1列显示字符串Duty:00%
	
	/*使用PWM模块提供输入捕获的测试信号*/
	PWM_SetPrescaler(720 - 1);					//PWM频率Freq = 72M / (PSC + 1) / 100
	PWM_SetCompare1(50);						//PWM占空比Duty = CCR / 100
	
	while (1)
	{
		OLED_ShowNum(1, 6, IC_GetFreq(), 5);	//不断刷新显示输入捕获测得的频率
		OLED_ShowNum(2, 6, IC_GetDuty(), 2);	//不断刷新显示输入捕获测得的占空比
	}
}
相关推荐
重生之我在20年代敲代码24 分钟前
strncpy函数的使用和模拟实现
c语言·开发语言·c++·经验分享·笔记
2401_858286114 小时前
52.【C语言】 字符函数和字符串函数(strcat函数)
c语言·开发语言
jiao000015 小时前
数据结构——队列
c语言·数据结构·算法
铁匠匠匠5 小时前
从零开始学数据结构系列之第六章《排序简介》
c语言·数据结构·经验分享·笔记·学习·开源·课程设计
C-SDN花园GGbond5 小时前
【探索数据结构与算法】插入排序:原理、实现与分析(图文详解)
c语言·开发语言·数据结构·排序算法
Navigator_Z7 小时前
数据结构C //线性表(链表)ADT结构及相关函数
c语言·数据结构·算法·链表
菜菜想进步7 小时前
内存管理(C++版)
c语言·开发语言·c++
知星小度S8 小时前
C语言——自定义类型
c语言·开发语言
cleveryuoyuo8 小时前
二叉树的链式结构和递归程序的递归流程图
c语言·数据结构·流程图