IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 嵌入式 -> STM32H750VB ADC+DSP -> 正文阅读

[嵌入式]STM32H750VB ADC+DSP

系列文章目录

提示:这里可以添加系列文章的所有文章的目录,目录需要自己手动添加
例如:第一章 Python 机器学习入门之pandas的使用


提示:写完文章后,目录可以自动生成,如何生成可参考右边的帮助文档


前言

在之前的文章中有提到使用STM32H750VB进行ADC+FFT的事,但是由于给出的采样点数过高,直接导致上电进入hardfault,放弃了一段时间想使用FPGA+SPI的方式进行数据交换然后进行FFT,之前用Verilog尝试写了一下SPI的时序,感觉问题比较多,上周考完业余无线电A证,现在又对H750做DSP念念不忘,于是乎采用较少点数进行了尝试,本文就介绍了基于ARM的DSP的基础内容。


提示:以下是本篇文章正文内容,下面案例可供参考

一、STM32H750 ADC

使用STM32CUBEMX配置工程,ADC并没有采用DMA的方式,只是想简单地得到数据然后进行信号处理。
主频配置为480MHz,直接拉满,ADC时钟为150MHz,采样深度16bit,采样时间1.5个时钟周期。

static void MX_ADC3_Init(void)
{
  ADC_ChannelConfTypeDef sConfig = {0};
  hadc3.Instance = ADC3;
  hadc3.Init.ClockPrescaler = ADC_CLOCK_ASYNC_DIV1;
  hadc3.Init.Resolution = ADC_RESOLUTION_16B;
  hadc3.Init.ScanConvMode = ADC_SCAN_DISABLE;
  hadc3.Init.EOCSelection = ADC_EOC_SINGLE_CONV;
  hadc3.Init.LowPowerAutoWait = DISABLE;
  hadc3.Init.ContinuousConvMode = DISABLE;
  hadc3.Init.NbrOfConversion = 1;
  hadc3.Init.DiscontinuousConvMode = DISABLE;
  hadc3.Init.ExternalTrigConv = ADC_SOFTWARE_START;
  hadc3.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
  hadc3.Init.ConversionDataManagement = ADC_CONVERSIONDATA_DR;
  hadc3.Init.Overrun = ADC_OVR_DATA_PRESERVED;
  hadc3.Init.LeftBitShift = ADC_LEFTBITSHIFT_NONE;
  hadc3.Init.OversamplingMode = DISABLE;
  if (HAL_ADC_Init(&hadc3) != HAL_OK)
  {
    Error_Handler();
  }
  sConfig.Channel = ADC_CHANNEL_0;
  sConfig.Rank = ADC_REGULAR_RANK_1;
  sConfig.SamplingTime = ADC_SAMPLETIME_1CYCLE_5;
  sConfig.SingleDiff = ADC_SINGLE_ENDED;
  sConfig.OffsetNumber = ADC_OFFSET_NONE;
  sConfig.Offset = 0;
  sConfig.OffsetSignedSaturation = DISABLE;
  if (HAL_ADC_ConfigChannel(&hadc3, &sConfig) != HAL_OK)
  {
    Error_Handler();
  }
}

在主函数中采集128次,并将数据存在数组里

for(j=0;j<128;j++)
{
	HAL_ADC_Start(&hadc3);
	HAL_ADC_PollForConversion(&hadc3,10);
	u1=HAL_ADC_GetValue(&hadc3);
	b[j]=(float32_t)u1*/65536*3.3;
}

随后进行FFT处理。

二、FFT相关

1. fft

与fft相关的函数可以在keil的文档中找到,本文中使用到的为

void arm_cfft_f32	(	const arm_cfft_instance_f32 * 	S,
float32_t * 	p1,
uint8_t 	ifftFlag,
uint8_t 	bitReverseFlag 
)	

解释如下:
Parameters
[in] S points to an instance of the floating-point CFFT structure
[in,out] p1 points to the complex data buffer of size 2*fftLen. Processing occurs in-place
[in] ifftFlag flag that selects transform direction
value = 0: forward transform
value = 1: inverse transform
[in] bitReverseFlag flag that enables / disables bit reversal of output
value = 0: disables bit reversal of output
value = 1: enables bit reversal of output
Returns
none

具体用法如下,只摘部分关键代码,代码来自于官方example

  arm_status status;
  float32_t maxValue;

  status = ARM_MATH_SUCCESS;

  status=arm_cfft_init_f32(&varInstCfftF32,fftSize);

  /* Process the data through the CFFT/CIFFT module */
  arm_cfft_f32(&varInstCfftF32, testInput_f32_10khz, ifftFlag, doBitReverse);

延续了arm的传统,首先还是先初始化,在初始化中根据fft的长度初始化一个复浮点fft结构varInstCfftF32,然后 arm_cfft_f32进行fft变换。在文档中没有办法对所有的函数进行溯源,只能进行推测。
设想:
由于是fft,初始化应该是生成蝶形网络,方便进行快速运算。

2. 数据处理

由于在stm32上数据可视化不太行,所以想使用keil导出数据再进行分析。在板子上将ADC通道连接到3.3V电源,采集到的数据乘1000,得到下图所示的数据。
在这里插入图片描述
在keil的command窗口输入,就能将数组b中的数据以txt的形式进行导出。

save E:\v.txt &b[0],&b[128]

保存的文件打开如下图所示,从keil中导出数据save中对数据的格式进行了分析,而且本例中所有数据都一样,所以相对较容易分析,可以看到从第二行开始,掐去开头几位和最后两位,中间的数据多次重复,每16个字符为一组,而这16个字符正好构成32bit的uint32_t的数据长度,可以看出数据为reverse排列。例如0x454e3f32,0x45被放到了最后,0x32在最前。
在这里插入图片描述

3. python处理导出数据

二进制与十进制整数,浮点数相互转换这篇文章讲了如何将二进制转换为浮点数,下面的代码实现了32bit二进制数转单精度浮点数

def str2int(a):
    if((a<='9')and(a>='0')):
        return int(a);
    else:
        if((a >= 'a' ) and ( a <= 'f' )) :
            return 10+ord(a)-ord('a');
        else:
            if ((a >= 'A') and (a <= 'F')):
                return 10 + ord(a) - ord('A');
def str2float(a):
    changdu=len(a)
    c=str2int(a[1])
    if(str2int( a[0] )>= 8):
        flag=-1;#负数
        b=str2int(a[0])-8;
    else:
        flag=1;
        b=str2int(a[0]);
    d=(str2int(a[2])&0x8)>>3;
    exponent=(b<<5)+(c<<1)+d-127;##整数部分二进制位数
    weishu=0
    for i in range(3,changdu-1):
        exp=((str2int(a[i-1])&0x7)<<1)+(str2int(a[i])>>3)
        weishu=exp*pow(16,-(i-2))+weishu;
    exp=(str2int(a[changdu-2])&0x7)<<1
    weishu = exp*pow(16, -6) + weishu;
    result=pow(2,exponent)*(1+weishu)*flag;
    return result;
def print_hi(name):
    word_size=4;#*8
    # Use a breakpoint in the code line below to debug your script.
    print(f'Hi, {name}')  # Press Ctrl+F8 to toggle the breakpoint.
    de_f=open("de_f.txt","w")
    with open("v.txt","r") as f:
        data=f.readlines()
        row=len(data)
        for i in range(1,row-2):
            length=len(data[i])
            num=int((length-12)/8);#一行的组数
            for j in range(0,num-1):
                temp=data[i][15+j*8]+data[i][16+j*8]+data[i][13+j*8]+data[i][14+j*8]+data[i][11+j*8]+data[i][12+j*8]+data[i][9+j*8]+data[i][10+j*8]+'\n'
                #单精度类型
                temp=str2float(temp)
                print(temp)
# Press the green button in the gutter to run the script.
if __name__ == '__main__':
    print_hi('PyCharm');

3. 数据处理

在keil中继续运行,得到fft变换之后数据的模,可以发现,仅在数组的前两项中有较大值存在,而其他相都为0,说明信号基本为直流信号。
在这里插入图片描述
将ADC采集端口连接到GND进行采集,使用上述方法将信号进行导出,并使用matlab求得频谱,得到如下图所示结果
在这里插入图片描述
H750求得的频谱为下图,并没有对横坐标进行处理,但是基本与使用matlab的结果一致。在这里插入图片描述
附matlab程序

clear all;
data=textread('de_f.txt');
Sample_clock=150e6/1.5;
sample_rate=1/Sample_clock;
a=size(data);
D=2*pi/(a(1)*sample_rate);
k=floor((-(a(1)-1)/2):(a(1)-1)/2);
size=128;
a=fftshift(fft(data,size));
figure(1)
subplot(2,1,1)
plot(data)
subplot(2,1,2)
axis([min(k*D),max(k*D),0,inf]);
plot(k*D,abs(a));

总结

本文使用STM32H750进行了ADC数据采集以及快速傅里叶变换,中间涉及到了keil数据导出、python二进制转单精度浮点、matlab求fft等多方面内容,下一步考虑使用FPGA+ARM实现同样功能。

  嵌入式 最新文章
基于高精度单片机开发红外测温仪方案
89C51单片机与DAC0832
基于51单片机宠物自动投料喂食器控制系统仿
《痞子衡嵌入式半月刊》 第 68 期
多思计组实验实验七 简单模型机实验
CSC7720
启明智显分享| ESP32学习笔记参考--PWM(脉冲
STM32初探
STM32 总结
【STM32】CubeMX例程四---定时器中断(附工
上一篇文章      下一篇文章      查看所有文章
加:2021-07-14 23:07:51  更:2021-07-14 23:08:31 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/25 19:52:54-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码