基于STM32的频率计(采用定时器外部计数的模式的方式)

前言

之前拿外部中断做过这个实验,但是精度范围都不是很理想。之后尝试过输入捕获的方法,虽然精度提高了不少,但是输入范围依旧不是很理想(精度做到了误差0.5%,范围做到了1.1MHZ)。而且更要命的是,这两种方法对于cpu的占用率特别的大,在测试的时候,我因为多加了一句串口输出函数,就导致了整体频率检测误差(虽然一句串口对于整个系统来讲不需要耗时多久,但是在检测高频率信号时,可能处理串口的时间就大于了频率检测的时间,这就是为什么这两个方法都不适用于检测高频信号的原因了,当然了真的想追求极致的话是可以采用DMA进行输出的,但是这个也只是治标不治本)。
之后在看了使用 STM32 测量频率和占空比的几种方法这篇博客。我知道了还能用定时器的外部计数器模式来检测信号的上升沿个数,所以这次我打算用外部计数器模式来做一个频率计。

外部计数器的相关知识

我现在对于这种方法的理解就相当于是一种用硬件来实现检测信号上升沿的方法。特点在于不消耗CPU资源,所以只需要在规定时间内调用相关函数,就能完成对信号上升沿次数的读取了。

思路

除了串口之外,我配置了两个定时器 TIM1和TIM2.我用TIM1来作为定时器中断,用TIM2来作为外部计数器。
TIM1的定时器中断的配置
这里用的是0.0005s的定时器(这个是有讲究的,之后会讲)
TIM2的外部计数器配置
重点看一下这里的65535这个数,这个是外部计数器的满载

#include "counter.h" #include "stdio.h" #include "usart.h" /*********************************************************************************************** //上升沿捕获 ************************************************************************************************/ TIM_ICInitTypeDef TIM3_ICInitStructure; void TIM3_counter_Init(u16 arr,u16 psc) { GPIO_InitTypeDef GPIO_InitStructure; TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; NVIC_InitTypeDef NVIC_InitStructure; RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); //使能TIM5时钟 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); //使能GPIOA时钟 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7; //PA7 清除之前设置 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; //PA7 浮空输入 GPIO_Init(GPIOA, &GPIO_InitStructure); GPIO_ResetBits(GPIOA,GPIO_Pin_7); //PA7 下拉 //初始化定时器5 TIM5 TIM_TimeBaseStructure.TIM_Period = arr; //设定计数器自动重装值 TIM_TimeBaseStructure.TIM_Prescaler =psc; //预分频器 TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; //设置时钟分割:TDTS = Tck_tim TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //TIM向上计数模式 TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); //根据TIM_TimeBaseInitStruct中指定的参数初始化TIMx的时间基数单位 //初始化TIM5输入捕获参数 TIM3_ICInitStructure.TIM_Channel = TIM_Channel_2; // 选择输入端 IC1映射到TI1上 TIM3_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising; //上升沿捕获 TIM3_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI; //映射到TI1上 TIM3_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1; //配置输入分频,不分频 TIM3_ICInitStructure.TIM_ICFilter = 0x00; //IC1F=0000 配置输入滤波器 不滤波 TIM_ICInit(TIM3, &TIM3_ICInitStructure);
评论 27
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值