基于stm32f103c8t6的fft频率计

这篇具有很好参考价值的文章主要介绍了基于stm32f103c8t6的fft频率计。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

之前项目中需要用到正弦信号的频率测量,也参考了几个大佬的博客(链接如下),但可能是由于stm32的型号不匹配,虽然也在网上查了一些需要修改的地方,但结果一直不太对,后来经过自己摸索结果终于对了,在这里给大家分享下,具体原理不在赘述。
参考的部分大佬博客(stm32f103zet6):
链接1: https://blog.csdn.net/weixin_43368814/article/details/103552114.
链接2: https://blog.csdn.net/weixin_42616791/article/details/108419412.

优缺点

1、fft方式测频率,峰峰值可以最低为20mV,输入捕获方式,峰峰值需要达到七、八百mV以上,才可以精准测量;
2、程序的测量精度利用信号发生器进行了验证(下面表格的数据基本是在峰峰值20mV下测得,峰峰值更大些精度会更高些。

信号发生器输出 实测
10khz 9961hz
15khz 15040hz
20khz 20022hz
25khz 25000hz
30khz 29987hz
35khz 34968hz

3、在峰峰值的峰谷(顶点)小于1.6v时,该方式可以测量的最小峰峰值为20mv(信号发生器的最小峰峰值为20mV),一旦峰底值(最小值)超过1.6V(峰峰值仍为20mV),测量结果就不准了,误差很大(我暂时没找到原因,有知道原因的大佬,欢迎评论区解答);

代码

头文件

#include <stdio.h>
#include "string.h"
#include "fft_calculate.h"
#include "adc.h"

#define ADC1_DR_Address    ((uint32_t)0x4001244C)
uint16_t ADC_Value[NPT];

adc(PA6,定时器2外部触发)

void Adc_Init(void)
{
		GPIO_InitTypeDef GPIO_InitStructure;
		ADC_InitTypeDef ADC_InitStructure;
		RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);	  
		RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);	  

		GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
		GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
		GPIO_Init(GPIOA, &GPIO_InitStructure);  
		ADC_InitStructure.ADC_Mode = ADC_Mode_Independent; 		
		ADC_InitStructure.ADC_ScanConvMode = DISABLE; 
		ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;
		ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T2_CC2; 
		ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
		ADC_InitStructure.ADC_NbrOfChannel = 1; 
		ADC_Init(ADC1, &ADC_InitStructure);
		RCC_ADCCLKConfig(RCC_PCLK2_Div6);
		ADC_RegularChannelConfig(ADC1, ADC_Channel_6, 1, ADC_SampleTime_1Cycles5);
		
		//使能ADC、DMA
		ADC_DMACmd(ADC1,ENABLE);
		ADC_Cmd(ADC1,ENABLE);
	 
		ADC_ResetCalibration(ADC1);	
		while(ADC_GetResetCalibrationStatus(ADC1));
	 
		ADC_StartCalibration(ADC1);				
		while(ADC_GetCalibrationStatus(ADC1));	
		ADC_ExternalTrigConvCmd(ADC1, ENABLE);		
}

DMA(一次接收1024点数据)

void DMA1_Init(void)
{
		DMA_InitTypeDef DMA_InitStructure;
		NVIC_InitTypeDef NVIC_InitStructure;

		RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1,ENABLE);	  			
		DMA_DeInit(DMA1_Channel1);
		DMA_InitStructure.DMA_PeripheralBaseAddr = ADC1_DR_Address;			
		DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)&ADC_Value; 	
		DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC; 				
		DMA_InitStructure.DMA_BufferSize = NPT; 			
		DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; 		
		DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; 			
		DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord ; 
		DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord ;  
		DMA_InitStructure.DMA_Mode = DMA_Mode_Circular  ; 		
		DMA_InitStructure.DMA_Priority = DMA_Priority_High ; 		
		DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;   		
		DMA_Init(DMA1_Channel1, &DMA_InitStructure);  
		DMA_ClearITPendingBit(DMA1_IT_TC1);
		DMA_ITConfig(DMA1_Channel1,DMA_IT_TC, ENABLE);	

		NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel1_IRQn;
		NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
		NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
		NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
		NVIC_Init(&NVIC_InitStructure);
		
		DMA_Cmd(DMA1_Channel1,ENABLE);
}

定时器

void TIM2_Init(void)
{
		TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
		TIM_OCInitTypeDef TIM_OCInitStructure;
		
		RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); 		//时钟使能

		TIM_TimeBaseStructure.TIM_Period = arr; 		//设置在下一个更新事件装入活动的自动重装载寄存器周期的值
		TIM_TimeBaseStructure.TIM_Prescaler =psc; 			//设置用来作为TIMx时钟频率除数的预分频值
		TIM_TimeBaseStructure.TIM_ClockDivision = 0; 		//设置时钟分割:TDTS = Tck_tim
		TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; 		//TIM向上计数模式
		TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);			//根据指定的参数初始化TIMx的时间基数单位
		
		TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;		//选择定时器模式:TIM脉冲宽度调制模式1
		TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;		//比较输出使能
		TIM_OCInitStructure.TIM_Pulse = 9;
		TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low;		//输出极性:TIM输出比较极性低
		TIM_OC2Init(TIM2, & TIM_OCInitStructure);		//初始化外设TIM2_CH2
		
		TIM_Cmd(TIM2, ENABLE); 			//使能TIMx
}

中断处理函数(不需要在.h文件中定义,main中直接调用)

void  DMA1_Channel1_IRQHandler(void)
{
	u16 i = 0;
	if(DMA_GetITStatus(DMA1_IT_TC1)!=RESET)
	{
		for(i=0;i<NPT;i++)
		{
			InBufArray[i] = ((signed short)(ADC_Value[i])) << 16;	
		}
		DMA_ClearITPendingBit(DMA1_IT_TC1);
	}
}

#最后附上程序下载地址
链接: 链接:https://pan.baidu.com/s/1CuYofbGRXZIoccYkexHHzw
.提取码:fp1q文章来源地址https://www.toymoban.com/news/detail-623144.html

到了这里,关于基于stm32f103c8t6的fft频率计的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • STM32f103c8t6模板的搭建-基于正点例程

           笔者认为正点编写的官方例程结构较为整洁,可以便于后期的例程开发,如果开发者对于项目开发中芯片要求较高的话,有很多人会选择正点的开发板,但是通常大多数是stm32初学者会选择用价格更为便宜的c8t6来进行学习,而正点选用的教程开发板大多都是些RC、ZE、

    2024年02月06日
    浏览(66)
  • 基于STM32F103C8T6ADC检测交流电压

    上篇文章写了硬件部分的实现思路,通过采样电阻的到小电压后经过二级放大电路得到单片机可处理的交流电压,此文介绍了如何采用单片机采集交流电压以及stm32ADC外设的使用。首先是硬件电路部分。  电路没有采用核心板,而是直接将芯片焊接到主板上,采用type-c接口供

    2024年02月12日
    浏览(53)
  • 基于STM32F103C8T6的HC-06蓝牙通信

    如果朋友们 遇到了如下问题 ,可以仔细借鉴本文章和另一篇专门讲解 蓝牙通信问题 的文章,一定能够解决你在蓝牙通信时遇到的诸多困难 1.在调试蓝牙模块AT指令时无返回值 2.身边 无USB转TTL模块 可以直接调试蓝牙模块(本人就是由于无模块花了了整整一天才调试成功)

    2024年02月03日
    浏览(60)
  • 基于stm32f103c8t6的定时器详解(持续更新)

    先声明:stm32f103c8t6中没有基本定时器、只有TIM1-TIM4:分别是高级定时器和通用定时器(对照下图请自行阅读stm32f103x的datasheet) 1、定时器功能:定时、输出比较、输入捕获、互补输出,其中基本定时器只有定时功能、通用定时器只没有互补输出功能、高级定时器具有所有功能

    2023年04月24日
    浏览(65)
  • HX711压力传感器(基于STM32F103C8T6)

    HX711模块是我们目前比较常见的压力传感器模块,主要的作用是用来做压力检测,重量监测等等。博主的这篇博文主要实现功能为,在对重量或者压力进行监测的同时,可以累加或者清零数值,在此基础上就可以对比如饮水量进行统计等等。 HX711模块是市面上比较常见的模块

    2024年02月11日
    浏览(53)
  • [STM32F103C8T6]基于stm32的循迹,跟随,避障智能小车

    目录 1.小车驱动主要是通过L9110S模块来驱动电机 motor.c 2.我们可以加入串口控制电机驱动(重写串口接收回调函数,和重定向printf) Uart.c main.c  3.点动功能 uart.c main.c 为什么使用的是HAL_Delay()要设置滴答定时器的中断优先级呢? 4.小车PWM调速,  6.跟随功能 7.避障功能 超声波测距

    2024年02月13日
    浏览(54)
  • 基于STM32F103C8T6的UAV飞控板硬件设计

    一、主控单元:         主控单元基于意法半导体公司的STM32F103C8T6单片机进行设计。STM32F103C8T6DE 内核为ARM Cortex-M3;最大主频:72MHz ;工作电压范围:2V~3.6V ;程序存储容量:64KB; 程序存储器类型:FLASH ;RAM总容量:20KB; GPIO端口数量:37 ;封装为LQFP-48;串行单线调试(

    2024年02月08日
    浏览(54)
  • 基于stm32f103c8t6及AS608-----指纹锁项目

              博主纯小白, 本文适合于初学者,大佬还请勿喷,欢迎提出意见,有纰漏之处将及时纠正。 在浅学了stmf103c8t6后,想着依据现在所拥有的知识和能力做一个小项目。 注:工程代码在文章末尾。 掌握C语言基础....这个最基础啦... 接触过类似单片机,稍微看得懂芯片

    2023年04月09日
    浏览(81)
  • 功耗测评 | STM32F103C8T6

    STM32F103C8T6 MCU越来越广泛的应用在生产生活的各个领域,外接丰富的传感器、功能模块、通信模块、显示存储等可以形成各种可样的产品项目应用。对于功耗要求比较高的产品,一般会选择STM32L系列的MCU,但是从功耗的评测角度,逻辑上是基本相似的。 在很多应用场合中都对

    2024年02月07日
    浏览(40)
  • STM32F103C8T6系统板

    1.电源部分 2.复位 3.晶振 4. 电源电路——防反接 有关二极管 漫谈二极管防电源反接电路 本次采用上图右下角的NMOS防反接电路。 电源电路——电源芯片 AMS1117是AMS公司的 ,LM1117是NS(美国国家半导体)的,LM1117要贵很多,所以一般的用AMS1117就可以了。 (以下分析参考STM32F10

    2024年02月02日
    浏览(68)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包