STM32单片机-输入捕获、FFT测频

发布者:龙腾少年最新更新时间:2022-02-14 来源: eefocus关键字:STM32  单片机  输入捕获 手机看文章 扫描二维码
随时随地手机看文章

一、硬件连接

1、电压信号处理电路仿真

图1.1.1

-----------------------------------------------------------

2、单片机连接

主控MCU:STM32F103ZET6,LM293输出连接在PB0上检测电压信号的频率,如图1.1.1与图1.2.1所示。

图1.2.1

图1.2.2

如图1.2.2所示,注意其中的TIM3_CH2N是PWM捕获比较输出,TIM3_CH3才是输入捕获。

图1.2.3

-----------------------------------------------------------------------------------------------------------------

二、程序部分

这里通过STM32输入捕获或FFT转换两种方式实现频率的测量,在实际工程中都已实现。STM32输入捕获信号幅度小于2V时,单片机检测不到跳变沿,需硬件对信号适当处理(如图1.1.1)。PB0/ADC8也可用ADC读信号电压值,ADC值为0时进行记录,再次为0就相当于经过了半个周期。计算两次ADC为0的时间差,就可以计算出信号的频率,这种方法不会受限于信号幅度的限制。

--------------------------------

1、通过STM32输入捕获

下面的程序采集PB0口(图1.2.1)的电压信号,因频率较低,且要求继电器出口时间小于35mS,采用测周法计算频率。给出主要部分定时器配置与定时器中断程序。因上升沿示波器测试并不陡峭(图1.1.1仿真图也可看出),故取一周波两次下降沿。

注意后期的处理程序必须捕获到两个下降沿的前提下,才能作相应的处理,采集程序未完成,处理会出错。

图2.1.1

1)定时器配置

void adc_TIM_Init(void)

{

   TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; //定时器

   GPIO_InitTypeDef GPIO_InitStructure; //端口

   TIM_ICInitTypeDef TIM_ICInitStructure; //输入捕获

   

   //初始化GPIO口

  GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IN_FLOATING; //浮空输入模式

   GPIO_InitStructure.GPIO_Pin=GPIO_Pin_0;

   GPIO_Init(GPIOB,&GPIO_InitStructure);

   GPIO_SetBits(GPIOB,GPIO_Pin_0);

   

   //使能时钟

   RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE); //TIM3

   RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB|RCC_APB2Periph_AFIO,ENABLE);

   

   //初始化TIM3定时

   TIM_TimeBaseStructInit(&TIM_TimeBaseStructure);

   TIM_TimeBaseStructure.TIM_Prescaler = 17; //1MHz计数脉冲 1uS

   TIM_TimeBaseStructure.TIM_Period = 65535;

   TIM_TimeBaseStructure.TIM_ClockDivision = 0x0;

   TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //向上计数

   TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);

   TIM_TimeBaseStructInit(&TIM_TimeBaseStructure);

   

   //初始化TIM3 Channel3输入捕获IC(Input Capture)

   TIM_ICInitStructure.TIM_Channel=TIM_Channel_3;

   TIM_ICInitStructure.TIM_ICPolarity=TIM_ICPolarity_Falling; //下降沿捕获

   TIM_ICInitStructure.TIM_ICSelection=TIM_ICSelection_DirectTI; //管脚与寄存器一一对应

   TIM_ICInitStructure.TIM_ICPrescaler=TIM_ICPSC_DIV1; //有下降沿就捕获,不分频

   TIM_ICInitStructure.TIM_ICFilter=0x00; //不打开输入捕获滤波器

   TIM_ICInit(TIM3,&TIM_ICInitStructure);

   TIM_ITConfig(TIM3,TIM_IT_Update,ENABLE); //允许定时中断

   TIM_ITConfig(TIM3,TIM_IT_CC3,ENABLE); //允许CC3捕获中断

   TIM_Cmd(TIM3,ENABLE);

…………

}

--------------------------------

2)定时溢出和输入捕获中断处理

void TIM3_IRQHandler(void) //TIM3

{

   static u8 CapStatus=0; //捕获状态,CapStatus=0未捕获到第1个下降沿,CapStatus=1捕获到第1个下降沿

   static u8 TIM3_CH3_Capture=0; //总的计数次数

   u32 FrequencyTemp=0;

   

   if(TIM_GetITStatus(TIM3,TIM_IT_Update)) //TIM3定时溢出更新中断

   {

      TIM_ClearITPendingBit(TIM3,TIM_IT_Update); //清除中断标志位

      if(CapStatus)

         TIM3_CH3_Capture++;

   }

   

   if(TIM_GetITStatus(TIM3,TIM_IT_CC3)) //RB0输入捕获中断

   {

      TIM_ClearITPendingBit(TIM3,TIM_IT_CC3); //清除中断标志位

      if(!CapStatus)

      {

         CapStatus=1;

         TIM_SetCounter(TIM3,0); //计数器清零

      }

      else if(CapStatus) //已经捕获到第1个下降沿

      {

         CapStatus=0;

         FrequencyTemp=TIM_GetCapture3(TIM3)+TIM3_CH3_Capture*65536; //计算两个下降沿总计数

         TIM3_CH3_Capture=0; //溢出次数清零

         TIM_SetCounter(TIM3,0); //计数器清零

         FrequencyValue=400000000/FrequencyTemp; //计算频率,比如5000,单位0.01Hz

      }

   }

}

图2.1.2

图2.1.3

-----------------------------------------------------------

2、通过FFT实现

下面是采集PC1口(图1.2.1)的小通道电流信号,计算频率,其固件具ST官方DSP库实现FFT,测试固件移步:FFT(具ST官方DSP库实现)。

--------------------------------

1)用STM32F103自带的12位ADC进行数据采集,定时器触发ADC采集,DMA搬运,定时器时间自行设置,采样频率已知。此部分相关内容移步:AD转换汇总(STM32、取平均、过采样)。

--------------------------------

2)通过FFT可以准确测量电压值、电流值、有功功率无功功率、频率、谐波分量(比如显示2~32次谐波)、相角(电压与电流夹角)。互感器二次值精确到小数点后2位无压力,电流范围大,硬件增加大小通道、程序分别采集即可;涌流二次谐波含量最多,故可实现二次谐波制动,相关介绍移步:电力-涌流抑制与谐波。

图2.2.1

-----------------------------------------------------------

3、屏显驱动介绍

移步:12864液晶显示原理(C程序)。

-----------------------------------------------------------------------------------------------------------------

附录1:测频法计算频率

网上找的资料,不保证正确性,没有实际测试过,仅供参考。

通过在一定时间内检测跳边沿的个数可计算出频率 频率=上升沿或下降沿个数/统计时间。

-----------------------------------------------------------

方法1:利用外部中断统计跳边沿个数,配置一个定时器每隔一定时间对频率进行计算。部分代码如下。

void exti_init()  //外部中断初始化函数

{

GPIO_InitTypeDef GPIO_InitStructure;

EXTI_InitTypeDef EXTI_InitStructure;

NVIC_InitTypeDef NVIC_InitStructure;

RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC,ENABLE);

       

GPIO_InitStructure.GPIO_Pin=GPIO_Pin_2;

GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IN_FLOATING;

GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;

GPIO_Init(GPIOC,&GPIO_InitStructure);

 

GPIO_EXTILineConfig(GPIO_PortSourceGPIOC, GPIO_PinSource2);//选择GPIO引脚用作外部中段线路

//此处一定要记住给端口管脚加上中断外部线路

 

EXTI_InitStructure.EXTI_Line=EXTI_Line2;

EXTI_InitStructure.EXTI_Mode=EXTI_Mode_Interrupt;

EXTI_InitStructure.EXTI_Trigger=EXTI_Trigger_Falling;  //下降沿进中断

EXTI_InitStructure.EXTI_LineCmd = ENABLE;

EXTI_Init(&EXTI_InitStructure); 

NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);  

NVIC_InitStructure.NVIC_IRQChannel = EXTI2_IRQn; //打开EXTI2的全局中断

NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; //设置优先级

NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;   

NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;   //使能

NVIC_Init(&NVIC_InitStructure);

}

外部中断中断函数

void EXTI2_IRQHandler()    

{

if(EXTI_GetITStatus(EXTI_Line2)==SET)

{

    EXTI_ClearITPendingBit(EXTI_Line0);//清中断

if(GPIO_ReadInputDataBit(GPIOC,GPIO_Pin_2)==Bit_RESET)    //确定沿

{

cnt++;

}

}

定时器中断函数

void TIM3_IRQHandler()   

{

frequent=cnt; //定时器设置时间为1s时

cnt=0;  //清零计数cnt

TIM_ClearITPendingBit(TIM3,TIM_IT_Update);    //清标志位

}

-----------------------------------------------------------

方法2:采用定时器外部计数的方法,另外一个定时器负责每隔一段时间计算频率,部分代码如下。

void time_init()

{

GPIO_InitTypeDef GPIO_InitStructure;

TIM_TimeBaseInitTypeDef TIM2_TimeBaseInitStructure;  

TIM_TimeBaseInitTypeDef TIM3_TimeBaseInitStructure;

NVIC_InitTypeDef NVIC_InitStructure;

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);

RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);

RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);

GPIO_InitStructure.GPIO_Pin=GPIO_Pin_0;

GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IPU;

GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;

GPIO_Init(GPIOA,&GPIO_InitStructure);

TIM_ClearITPendingBit(TIM2,TIM_IT_Update);//清除TIM2中断标志位

TIM2_TimeBaseInitStructure.TIM_Period = 0xFFFF;//设置自动重装载值

TIM2_TimeBaseInitStructure.TIM_Prescaler = 0;//设置分频

TIM2_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1; 

TIM2_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;//向上计数

TIM_TimeBaseInit(TIM2,&TIM2_TimeBaseInitStructure);

  

TIM_ETRClockMode1Config(TIM2, TIM_ExtTRGPSC_OFF,TIM_ExtTRGPolarity_NonInverted, 0x00);  //设置为采用外部时钟计数,可设定滤波参数消除信号干扰

TIM_Cmd(TIM2,ENABLE); 

TIM_ClearITPendingBit(TIM3,TIM_IT_Update);

TIM3_TimeBaseInitStructure.TIM_Period = 999;

TIM3_TimeBaseInitStructure.TIM_Prescaler = 3599;

TIM3_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1; 

TIM3_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;

TIM_TimeBaseInit(TIM3,&TIM3_TimeBaseInitStructure);

TIM_Cmd(TIM3,ENABLE);

TIM_ITConfig(TIM3, TIM_IT_Update, ENABLE );

NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);

NVIC_InitStructure.NVIC_IRQChannel=TIM3_IRQn; 

NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0;

NVIC_InitStructure.NVIC_IRQChannelSubPriority=0;  

NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

NVIC_Init(&NVIC_InitStructure);

}

定时器中断函数

void TIM3_IRQHandler()  

{

static u8 i;

static u32 frequent_sum;

TIM_ClearITPendingBit(TIM3,TIM_IT_Update);   //清中断

if(i<19)

{

cnt += TIM_GetCounter(TIM2);  //,获取计数器的值,累加减少误差

TIM_SetCounter(TIM2,0);    //计数器清零

i++;

}

else

{

cnt += TIM_GetCounter(TIM2);

TIM_SetCounter(TIM2,0);

cnt += cnt*0.000025; //根据实际情况修改系数线性补偿

frequent = cnt;

i = 0;

cnt = 0;

}

}

-----------------------------------------------------------------------------------------------------------------

关键字:STM32  单片机  输入捕获 引用地址:STM32单片机-输入捕获、FFT测频

上一篇:STM32单片机-资料查找
下一篇:STM32单片机-PWM波形输出

推荐阅读最新更新时间:2024-11-17 01:08

基于单片机和TDC的磁尺数字化技术研究
本文介绍一种利用89C51单片机及TDC-GP1芯片对现有的磁致伸缩传感器系统进行数字化改造,开发出的新型磁致伸缩线性位移(液位)传感器。 1结构及工作原理 该数字化磁尺由不导磁的不锈钢(探测杆),磁致伸缩线(波导丝)、可移动的浮球(磁环)和电子测量装置等部分组成。波导丝被安装在不锈钢管内,经挤压和热处理后仍保持电磁特性,磁环在不锈钢管外侧可自由滑动。电路单元集成在传感器头部的套管内。 电子测量装置中的脉冲发生器产生电流脉冲(即start脉冲)并沿波导丝传播,产生一个环形的磁场。在探测杆外配置的活动磁环上同时产生一个磁场。当电流磁场与磁环磁场相遇时,两磁场矢量叠加,形成螺旋磁场,产生瞬时扭力,使波导线扭动并产生一个“扭
[单片机]
基于<font color='red'>单片机</font>和TDC的磁尺数字化技术研究
PIC单片机4×4行列式键盘的工作原理解析
在本文中,小编将对pic单片机的4×4行列式键盘的工作原理加以介绍,以帮助大家增进对pic单片机键盘系统的了解,方便后期编程使用。 (1)单片机系统键盘原理 行列式键盘的接法比独立式键盘的接法复杂,编程实现上也会比较复杂。但是,在占用相同的I/O端口的情况下,行列式键盘的接法会比独立式接法允许的按键数量多,其原理图如图1所示。 图1 4×4行列式键盘的原理图 实际的工程中,可能会使用PIC16C5X这种通用的可编程的键盘、显示接口器件,使用PIC16C5X单片器件就能够完成键盘输入和显示控制两种功能。 行列式键盘的工作方式是先用列线发送扫描字,然后读取行线的状态,查看是否有按键按下。键盘部分提供一种扫描的工作方式,可以
[单片机]
PIC<font color='red'>单片机</font>4×4行列式键盘的工作原理解析
基于普通单片机的LIN协议实现方案
1 概述 LIN协议是新出现的一种新型低成本串行通信总线,其全称是Local Interconnect Network,即局部互联网络。它最开始出现于汽车行业,是为解决汽车智能化和网络化的发展要求和降低汽车制造成本的矛盾而提出来的一种串行总线协议,主要用于车门、车灯等需要简单控制但又要求智能控制的场合。它的主要特点是:采用单个主控制器/多从设备通信模式;基于普通UART/SCI接口硬件实现,协议简单;网络传输速率不高,最高可达20kb/s。由于LIN协议的突出特点是协议对硬件的依赖程度低,可以基于普通单片机的通用串口等硬件资源以软件方式实现,成本低廉,因此可广泛应用于汽车行业以外的其他领域,如智能家庭网络内部的数据传输、节点
[应用]
EM78系列单片机--D/A变换程序的设计
EM78系列 单片机 --D/A变换程序的设计 PORT6的输出接有一个数模转换器(D/A convert)。写一程序产生一个鋸此波。 本例的D/A Convert所采用的方式为R – 2R的方式,所使用的电阻为20K的同一品牌的排阻。因PORT6有8个位,所以在0V-VCC一共有256个阶层。 PORT6 == 6;定义。 MOV A, @0 ;將A设成0。 IOW PORT6 ;將PORT6设成OUTPUT口。 MOV PORT6, A ;PORT6输出内容为0。 AGAIN: INC PORT6 ;PORT6的值依序递增1。 JMP AGAIN
[单片机]
基于射频技术的无线识别系统设计
  O 引言   射频识别是一种非接触式的自动识别技术,它通过射频信号自动识别目标对象并获取相关数据。射频识别工作无须人工干预、非接触、阅读速度快、无磨损、不受环境影响、寿命长、便于使用。目前,射频识别技术在国外发展非常迅速,产品种类繁多,已广泛用于工业自动化、商业自动化、交通运输控制管理等众多领域,如汽车、火车等交通监控;高速公路自动收费系统;停车场管理系统;物品管理;仓储管理:车辆防盗等。由于我国射频识别技术起步较晚,除用于中国铁路的车号自动识别系统外,仅限于射频公交卡的应用。本文给出一种实现简单射频识别系统的方式。阅读器和应答器均包含在单片机控制系统中,利用ASK调制与解调电路以及匹配网络电路,使整个系统的可识别有效距离
[嵌入式]
采用AT89C2051和AT89S52单片机实现红外遥控电子密码锁的设计
随着科学技术的进步和社会经济的发展,电子密码锁取代传统的机械锁已成为一种必然的趋势。以往基于单片机的密码锁系统,直接将编好的密码程序存储在片内EPROM中,但不易实现密码的修改;如要完成修改密码功能,多采用片外串行E2PROM实现。本文研究并设计的一种基于单片机的红外遥控电子密码锁,不但具有普通密码锁智能控制上锁、开锁、报警等特点,而且在不扩展E2PROM的情况下,可以实现8位密码任意修改的功能,节省了硬件资源,减小了系统体积,这是本设计的一个创新点。另外还增加了遥控开锁的特点。所以该系统不但成本低、保密性强,更适用于那些正常人体不宜接近的特殊场合,比如高辐射区、高传染区等。 1 系统硬件设计方案 1.1 系统总体设计 系统主
[单片机]
采用AT89C2051和AT89S52<font color='red'>单片机</font>实现红外遥控电子密码锁的设计
51单片机特殊功能寄存器有哪些_功能是什么
  51单片机是对所有兼容Intel 8031指令系统的单片机的统称。该系列单片机的始祖是Intel的8004单片机,后来随着Flash rom技术的发展,8004单片机取得了长足的进展,成为应用最广泛的8位单片机之一,其代表型号是ATMEL公司的AT89系列,它广泛应用于工业测控系统之中。很多公司都有51系列的兼容机型推出,今后很长的一段时间内将占有大量市场。51单片机是基础入门的一个单片机,还是应用最广泛的一种。需要注意的是51系列的单片机一般不具备自编程能力。   51单片机特殊功能寄存器   1、21个寄存器介绍   51系列单片机内部主要有四大功能模块,分别是I/O口模块、中断模块、定时器模块和串口通信模块(串行I/O口
[单片机]
51<font color='red'>单片机</font>特殊功能寄存器有哪些_功能是什么
ST与麻省理工学院合作超低功耗微控制器技术
2008年11月21日 ,意法半导体宣布加入在麻省理工学院微系统技术实验室(MTL)成立的微系统产业联盟(MIG)。微系统产业联盟成立于上个世纪80年代,是支持微系统技术实验室发展基础架构,为其研究和教育目标提供发展方向咨询的唯一产业合作组织。意法半导体是第一个加入该组织的欧洲公司。 “意法半导体作为第一家加入微系统产业联盟的欧洲公司,我们为此感到非常高兴,”微系统技术实验室主任兼MIT电气工程系教授Anantha Chandrakasan表示,“我们期待与意法半导体在多个重要领域展开积极的合作,包括超低功耗电子元器件、传感器系统和医疗电子元器件。” “意法半导体在开发低功耗技术方面居世界领先水
[单片机]

推荐帖子

zigbee修改发射功率的问题
现在想做一个发射终端间隔自动修改发射功率的问题,请大家来出出点子zigbee修改发射功率的问题这个意思不是太明白啊,是要低功耗,还是就是要降低发送功率,让接受不到。低功耗专门有LPMx的设置实现,而RSSI主要和距离有关系,反应的是接受强度。主动降低发射功率应该是有一个寄存器写入就可以实现的,但是没有试过,不大熟悉。cc2530的芯片,在协议栈中写好程序,启动之后然后程序自动从最低功耗开始,到最高功耗,时间间隔2s 请问这个修改要在哪里进行修改编写现在我用的是Ember357芯
lygqichunyang RF/无线
简单实用的调频话筒制作
下面的就是调频无线话筒的电路图,电路非常简洁,没有多余的器件。高频三极管V1和电容C3、C5、C6组成一个电容三点式的振荡器,对于初学者我们暂时不要去琢磨电容三点式的具体工作原理,我们只要知道这种电路结构就是一个高频振荡器就可以。三极管集电极的负载C4、L组成一个谐振器,谐振频率就是调频话筒的发射频率,根据图中元件的参数发射频率可以在88~108MHZ之间,正好覆盖调频收音机的接收频率,通过调整L的数值(拉伸或者压缩线圈L)可以方便地改变发射频率,避开调频电台。发射信号通过C4耦合到天线上再发
maker 单片机
关于进程中止的问题,求教!
一般对于应用程序的中止上,大家一般用的方法都是Findwindow,terminateProcessing.除了这个方法,还有别的方法吗?不用这个,用什么方法能阻止应用程序的启动?关于进程中止的问题,求教!
chenmaoxiong 嵌入式系统
ISE14.7编译时不能Map了是怎么回事?
用例程也不能改变这样的情况,可能是360或者什么软件把里面的文件给破坏了,但不知道具体什么原因,具体怎么去解决,希望知道朋友能帮忙解决一下,谢谢!ISE14.7编译时不能Map了是怎么回事?报的什么错啊?会不会是引脚约束的文件没有?会不会是引脚约束的文件没有?不懂帮顶cat3902982发表于2015-9-2215:58报的什么错啊? 他没有报错误,就是编译的时候到这步就停止了。。elvike发表于2015-9-2218:00会不会是引脚
besideyou FPGA/CPLD
TI DSP .CMD 文件的编写
CMD它是用来分配rom和ram空间用的,告诉链接程序怎样计算地址和分配空间……TIDSP.CMD文件的编写CMD它是用来分配rom和ram空间用的,告诉链接程序怎样计算地址和分配空间.所以不同的芯片就有不同大小的rom和ram.放用户程序的地方也不尽相同.所以要根据你的芯片进行修改.分两部分.MEMORY和SECTIONS.MEMORY{PAGE0..........PAGE1.........}SECTIONS{SECTIONS{.vector
DSP16 DSP 与 ARM 处理器
新手关于消影的问题
我是新手,正在学习51单片机,也正在做实验。关于消影还是不怎么理解。我用定时器中断做了个0至59秒的计时器,但是影子相对明显,我将硬件情况及程序附上,请各位指点。怎样才能较好地控制消影呢?还有最好能说明白消影的原理,看得比较多,但是还是没有透彻的理解。1、硬件情况:STC89C52,P0口接三极管控制共阳数码管;2、程序如下:#includereg52.h#defineucharunsignedchar#defineuintunsignedintuintnum1,n
zanexue 单片机
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved