STM32 ADC+定时器+DMA+FFT

本次实现的功能为单片机DAC输出一个正弦波,然后ADC定时采样用DMA输出,最后对DAC输出的波形进行FFT。

单片机STM32F103ZET6

内部时钟

一、配置ADC

ADC端口为PA1,采用DMA输出,定时器3触发

定时器时钟64M,分频后为102.4KHz

ADC采样时间为102.4KHz/100=1.024KHz

二、配置DAC

DAC端口PA4

DMA传输

定时器6

定时器时钟64M,分频后为1MHz

三、配置DSP

四、配置时钟

四、代码

注意生成的代码里初始化中DMA要在ADC之前

FFT需要#include "arm_math.h"头文件

需添加include

在define后面补全USE_HAL_DRIVER,STM32F103xE,ARM_MATH_CM4,__CC_ARM,ARM_MATH_MATRIX_CHECK,ARM_MATH_ROUNDING,__FPU_PRESENT=1

main中加入ADC、DAC与FFT代码

uint16_t ad_value;          
uint16_t adc_buffer[1] = {0};

HAL_TIM_Base_Start(&htim3);
HAL_ADC_Start_DMA(&hadc1,(uint32_t *)&adc_buffer,1);

HAL_TIM_Base_Start(&htim6);
SineWave_Data(n,DualSine12bit,1.6);
HAL_DAC_Start_DMA(&hdac,DAC_CHANNEL_1,(uint32_t *)DualSine12bit,n,DAC_ALIGN_12B_R);

arm_cfft_radix4_instance_f32 scfft;        //FFT对应结构体变量
arm_cfft_radix4_init_f32(&scfft,fft_adc_n,0,1); //初始化scfft结构体,设置FFT相关参数

SineWave_Data是产生正弦波的点(子函数)

#include "math.h"
#define n 100
uint16_t DualSine12bit[n];
//num:要在一个正弦波中采集多少点
//*D:创建的一个数组用来存放正弦波各个点的数值的
//U:输出电压的峰值(0~1.5V)
//Pi:3.1415926 自己定义
void SineWave_Data( uint16_t num,uint16_t *D,float U)
{
    uint16_t i;
    for( i=0;i<num;i++)
    {
        D[i]=(uint16_t)((U*sin(( 1.0*i/(num-1))*2*3.14159265358979)+U)*4095/3.3);
    }
}

FFT定义

#define fft_adc_n 1024    // 采1024个点
uint16_t i;
float adc_data[fft_adc_n*2]={0};        // 存ADC值
float fft_in_adc_data[fft_adc_n*2]={0}; // FFT输入,实部是ADC值,虚部补0
float fft_out_adc_data[fft_adc_n]={0};  // FFT输出

/*********************************************************************
    Name          : FFT_deal0(short int *data, float *fft_in,int data_length)
    Funcation :对波形数据进行补零操作
    Parameter :    short int *data        波形信号
                float *fft_in            输入信号(信号长度应是输出信号的2倍)
                int data_length        输出信号长度(与波形信号长度保持一致)
    Return    无
********************************************************************/
void FFT_deal0(float *data, float *fft_in,int data_length)
{
        for(int i = 0;i < data_length;i++)
        {
            fft_in[2*i] = data[i];
            fft_in[2*i+1]=0;
        }
}

在ADC回调函数中加入标志位

void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc)
{
    ad_flag=1;
}

主函数

        while(i<fft_adc_n)  //等待1024个点
        {
            if(ad_flag==1)
            {
                i++;
                ad_flag=0;
                ad_value=HAL_ADC_GetValue(&hadc1);
                adc_data[i]=ad_value;
            }
        }
        
        for(i=0;i<fft_adc_n;i++)   //打印采集到得ADC值
        {
            printf("%.2f\r\n",adc_data[i]);
        }
        
        //FFT
        FFT_deal0(adc_data,fft_in_adc_data,fft_adc_n);                                //对采集后的数据进行补0,补足虚部
        arm_cfft_radix4_f32(&scfft,fft_in_adc_data);                                            //FFT计算(基4)
        arm_cmplx_mag_f32(fft_in_adc_data,fft_out_adc_data,fft_adc_n);            //把计算结果复数求模得幅值 
        
        printf("ffffffffffffffffffff\r\n");
        //打印FFT输出
        for(i=0;i<fft_adc_n;i++)
        {
            fft_out_adc_data[i]=fft_out_adc_data[i]*0.0008056640625;
            printf("%.2f\r\n",fft_out_adc_data[i]);
        }
        while(1);

将采集到得ADC放入Excel打印出来

波形频率50Hz

1.024KHz采样频率采集1024个点,刚好50个波形

FFT分析后得波形

可以看到频率为50左右,还是比较精准的

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/2999.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Scrapy的callback进入不了回调方法

一、前言 有的时候&#xff0c;Scrapy的callback方法直接被略过了&#xff0c;不去执行其中的回调方法&#xff0c;可能排查好久都排查不出来&#xff0c;我来教大家集中解决方法。 yield Request(urlurl, callbackself.parse_detail, cb_kwargs{item: item})二、解决方法 1…

基于QEMU-aarch64学习UEFI(EDK2)-1环境搭建

基于QEMU-aarch64学习UEFI(EDK2)-1环境搭建 文章目录基于QEMU-aarch64学习UEFI(EDK2)-1环境搭建一、环境搭建1、虚拟机Ubuntu系统安装2、docker镜像导入3、下载EDK2源码4、容器创建和代码编译4.1 容器创建4.2 代码编译5、运行QEMU_EFI.fd6、VSCODE配置7、日常工作8、不同项目的…

数据结构——二叉树与堆

作者&#xff1a;几冬雪来 时间&#xff1a; 内容&#xff1a;二叉树与堆内容讲解 目录 前言&#xff1a; 1.完全二叉树的存储&#xff1a; 2.堆的实现&#xff1a; 1.创建文件&#xff1a; 2.定义结构体&#xff1a; 3.初始化结构体&#xff1a; 4.扩容空间与扩容…

学习黑客十余年,如何成为一名高级的安全工程师?

1. 前言 说实话&#xff0c;一直到现在&#xff0c;我都认为绝大多数看我这篇文章的读者最后终究会放弃&#xff0c;原因很简单&#xff0c;自学终究是一种适合于极少数人的学习方法&#xff0c;而且非常非常慢&#xff0c;在这个过程中的变数过大&#xff0c;稍有不慎&#…

win32api之文件系统管理(七)

什么是文件系统 文件系统是一种用于管理计算机存储设备上文件和目录的机制。文件系统为文件和目录分配磁盘空间&#xff0c;管理文件和目录的存储和检索&#xff0c;以及提供对它们的访问和共享&#xff0c;以下是常见的两种文件系统&#xff1a; NTFSFAT32磁盘分区容量2T32G…

C/C++之while(do-while)详细讲解

目录 while循环有两个重要组成部分&#xff1a; while 是一个预测试循环 无限循环 do-while 循环 while循环有两个重要组成部分&#xff1a; 进行 true 值或 false 值判断的表达式&#xff1b;只要表达式为 true 就重复执行的语句或块&#xff1b;图 1 显示了 while 循环的…

GIS开源库GEOS库学习教程(一):编译及示例代码

1、介绍 GEOS库是一个集合形状的拓扑关系操作实用库&#xff0c;简单得说&#xff0c;就是判断两个几何形状之间关系和对两个几何形状进行操作以形成新的几何形状的库。GEOS是仿照JTS库做的&#xff0c;是JTS的C实现。下面是JTS Topology Suite (JTS) 拓扑运算函数库的介绍&…

Android 自定义View 之 Mac地址输入框

Mac地址输入框前言正文一、什么是View?二、什么是自定义View三、自定义View① 构造方法② XML样式③ 测量④ 绘制1. 绘制方框2. 绘制文字⑤ 输入1. 键盘布局2. 键盘接口3. 键盘弹窗4. 显示键盘5. 处理输入四、使用自定义View五、源码前言 在日常工作开发中&#xff0c;我们时长…

Ubuntu下载、配置、安装和编译opencv

1 安装相关依赖安装opencv前&#xff0c;需要先准备好编译器、相关依赖sudo apt-get install gcc g cmake vim sudo apt-get install build-essential libgtk2.0-dev libavcodec-dev libavformat-dev libjpeg-dev libswscale-dev libtiff5-dev sudo apt-get install libgtk2.0-…

MySQL数据库实现主从同步

安装MySQL数据库8.0.32 前言 今天来学习数据库主从同步的原理及过程&#xff0c;数据库主要是用来存储WEB数据&#xff0c;在企业当中是极为重要的&#xff0c;下面一起来看下。 1.1 数据库做主从的目的 MySQL主从复制在中小企业&#xff0c;大型企业中广泛使用&#xff0c…

类和对象 - 下

本文已收录至《C语言》专栏&#xff01; 作者&#xff1a;ARMCSKGT 目录 前言 正文 初始化列表 成员变量的定义与初始化 初始化列表的使用 变量定义顺序 explicit关键字 隐式类型转换 自定义类型隐式转换 explicit 限制转换 关于static static声明类成员 友元 友…

重构类关系-Push Down Method函数下移四

重构类关系-Push Down Method函数下移四 1.函数下移 1.1.使用场景 超类中的某个函数只与部分&#xff08;而非全部&#xff09;子类有关。将这个函数移到相关的那些子类去。 Push Down Method (328)与Pull Up Method (322)恰恰相反。当我有必要把某些行为从超类移至特定的子…

maven的profiles功能介绍、maven自定义插件plugin

profiles maven配置文件的profiles功能类似于springboot的spring.profiles.active配置&#xff0c;指定不同的环境来读取相应的配置内容。 <profiles>标签的子标签可以包含<repository> <plugin> <dependencies> <distributionManagement>等。 …

go语言gin框架学习

让框架去做http解包封包等&#xff0c;让我们的精力用在应用层开发 MVC模式 M: model&#xff0c;操作数据库gorm view 视图 处理模板页面 contoller 控制器 路由 逻辑函数 解决gin相关代码飘红的问题 记得启用gomodule go env -w GO111MODULEon然后到相应目录下执行 go mod i…

Karl Guttag:论相机对焦技术在AR/VR中的沿用

近期&#xff0c;AR/VR光学专家Karl Guttag介绍了两家在CES 2023展出光学传感技术的公司&#xff1a;poLight和CML&#xff08;剑桥机电一体化&#xff09;。​同时介绍两家公司的原因&#xff0c;是因为他们提供了实现AR/VR“光学微动”&#xff08;Optics Micromovement&…

5.多线程学习

作者&#xff1a;爱塔居 专栏&#xff1a;JavaEE 作者简介&#xff1a;大三学生&#xff0c;喜欢总结与分享~ 文章目录 目录 文章目录 章节回顾 一、wait 和notify 二、设计模式 2.1 单例模式 章节回顾 线程安全 1.一个线程不安全的案例&#xff08;两个线程各自自增5w次&…

PyTorch 之 基于经典网络架构训练图像分类模型

文章目录一、 模块简单介绍1. 数据预处理部分2. 网络模块设置3. 网络模型保存与测试二、数据读取与预处理操作1. 制作数据源2. 读取标签对应的实际名字3. 展示数据三、模型构建与实现1. 加载 models 中提供的模型&#xff0c;并且直接用训练的好权重当做初始化参数2. 参考 pyto…

【Linux】基于阻塞队列的生产者消费者模型

​&#x1f320; 作者&#xff1a;阿亮joy. &#x1f386;专栏&#xff1a;《学会Linux》 &#x1f387; 座右铭&#xff1a;每个优秀的人都有一段沉默的时光&#xff0c;那段时光是付出了很多努力却得不到结果的日子&#xff0c;我们把它叫做扎根 目录&#x1f449;为何要使用…

谈谈低代码的安全问题,一文全给你解决喽

低代码是一种软件开发方法&#xff0c;通过使用图形化用户界面和可视化建模工具&#xff0c;以及自动生成代码的技术&#xff0c;使得开发人员可以更快速地构建和发布应用程序。 作为近些年软件开发市场热门之一&#xff0c;市面上也涌现了许多低代码产品&#xff0c;诸如简道云…

SpringCloud:统一网关Gateway

目录 1、网关介绍 2、搭建网关服务 3、路由断言工厂 4、路由过滤器 5、全局过滤器GlobalFilter 6、过滤器执行顺序 7、跨域问题处理 1、网关介绍 网关(Gateway)又称网间连接器、协议转换器。网关在网络层以上实现网络互连&#xff0c;是复杂的网络互 连设备&#xff0…