STM32H750VBT6的DSP使用的学习——基于CubeMX

前言

人生如逆旅,我亦是行人。


1、STM32H7的DSP功能介绍

  • (STMicroelectronics,简称ST)推出新的运算性能创记录的H7系列微控制器。新系列内置STM32平台中存储容量最高的SRAM(1MB)、高达2MB闪存和种类最丰富的通信外设,为实现让智慧更高的智能硬件无处不在的目标铺平道路。

  • STM32H7系列沿用STM32F7系列的ARM Cortex-M7处理器内核,是业界首款采用40nm闪存制造工艺的Cortex-M7微控制器,还是首款运行频率达到400MHz的微控制器,这些重大改进之处使得STM32H743能够创下运算性能测试856D的记录,EEMBC CoreMark 测试取得2010分。

  • DSP功能是内核自带的:

其中较为重要的两个设计单元:

  • DSP(Digital Signal Processing):数字信号处理

    DSP单元集成了一批专用的指令集(主要是SMID指令和快速MAC乘积累加指令),可以加速数字信号处理的执行速度。

  • FPU(Float Point Unit):浮点运算器

    Cortex-M7内核支持双精度浮点,可以大大加速浮点运算的处理速度。


下面是Cortex-M3,M4和M7的指令集爆炸图:

在这里插入图片描述

  • M4 和 M7 系列有相同的 DSP 指令集;
  • M7 相比 M4 系列要多一些浮点指令集;
  • 同时这里要注意一个小细节,浮点指令都是以字符 V 开头的。通过这点,我们可以方便的验证是否正确开启了 FPU (MDK 或者 IAR 调试状态查看浮点运算对应的反汇编是否有这种指令);

不同 M 内核的 DSP 性能比较:

在这里插入图片描述

  • Cortex-M7内核的DSP性能最强;
  • Cortex-M3,M4和M33是中等性能,其中M3最弱;
  • Cortex-M0,M0+和M23性能最弱

二、ARM 提供的 CMSIS-DSP 库

为了方便用户实现DSP功能,ARM专门做了一个DSP库CMSIS-DSP,主要包含以下数字信号处理算法:

  • BasicMathFunctions

    在这里插入图片描述

    提供了基本的数据运算,如加减乘除等基本运算,以_f32结尾的函数是浮点运算,以_q8, _q15, _q31,结尾的函数是定点运算

  • FastMathFunctions

    在这里插入图片描述

    快速数学函数,提供 sin ,cos 以及平方根 sqrt 的运算。

  • ComplexMathFunctions

    在这里插入图片描述

    复杂数学函数,主要是向量、求模等运算。

  • FilteringFunctions

    在这里插入图片描述

    过滤功能,主要是滤波函数,如 IIR、FIR、LMS等。

  • MatrixFunctions

    在这里插入图片描述

    矩阵函数,主要是矩阵的运算。

  • TransformFunctions

    在这里插入图片描述

    转换函数,变换功能,包括复数FFT(CFFT),复数FFT逆运算(CIFFT),实数FFT(RFFT),实数 FFT 逆运算。

  • ControllerFunctions

    在这里插入图片描述
    控制器功能,主要是 PID 控制函数和正余弦函数。

  • StatisticsFunctions

    在这里插入图片描述
    统计函数,求平均值,最大值,最小值,功率,RMS等。

  • SupportFunctions

    在这里插入图片描述
    支持功能函数,如数据拷贝,Q格式和浮点格式相互转换。

  • CommonTables


三、获取 DSP 库的学习资料

在 Keil MDK 版本中,DSP 库集成与 runtime environment 之中,可以在 Keil 的安装目录中找到。

  • 通常路径:F:\Keil5\ARM\PACK\ARM\CMSIS\5.8.0\CMSIS\DSP

  • 帮助文件位于:F:\Keil5\ARM\PACK\ARM\CMSIS\5.8.0\CMSIS\Documentation\DSP\html\index.html

  • 官方例程:F:\Keil5\ARM\PACK\ARM\CMSIS\5.8.0\CMSIS\DSP\Examples\ARM

    在这里插入图片描述


四、利用 CubeMX 进行配置

  • 现在开始我们的主要部分,进行 CubeMX 的配置。
  • 我所使用的开发板是 STM32H7 的最小系统板:STM32H750VBT6,下面有请主角闪亮登场。
    在这里插入图片描述
  • 接下来进行 CubeMX 的主要配置:

1、新建工程

在这里插入图片描述
在这里插入图片描述

2、进行各种配置

  • 时钟配置

    开启时钟:
    在这里插入图片描述
    配置时钟树:
    在这里插入图片描述

  • 串口配置

    这里我所使用 USB 的虚拟串口(virtual COM):
    在这里插入图片描述
    在这里插入图片描述

  • 原理图上的硬件与 CubeMX 上的引脚对应:
    在这里插入图片描述
    在这里插入图片描述

  • 另外配置完 USB 虚拟串口之后,还要进行一下时钟树的配置:
    在这里插入图片描述

  • 调试配置在这里插入图片描述
  • DSP 库的添加:

    选中 select components
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

3、生成代码

在这里插入图片描述
在这里插入图片描述

4、Keil 中的配置

在这里插入图片描述

  • 添加宏:
,__FPU_PRESENT=1,__FPU_USED=1,ARM_MATH_CM7,__CC_ARM

在这里插入图片描述

  • 添加路径:
    在这里插入图片描述
    在这里插入图片描述

5、工程配置

  • 添加如下库文件:
    在这里插入图片描述
    在这里插入图片描述
  • 添加 fft 的官方例程:
    在这里插入图片描述
    在这里插入图片描述

6、添加代码

  • USB 的虚拟串口:
#include "usbd_cdc.h"
#include "stdarg.h"

#define CONSOLEBUF_SIZE 256

static char Uart_buf[CONSOLEBUF_SIZE];
extern USBD_HandleTypeDef hUsbDeviceFS;

void PrintfDebugUSB(const char *fmt, ...)
{
	va_list args;
	va_start(args, fmt);
	int length = vsnprintf(Uart_buf, sizeof(Uart_buf) - 1, fmt, args);
	va_end(args);
	
	HAL_Delay(1);
	USBD_CDC_SetTxBuffer(&hUsbDeviceFS, (uint8_t *)Uart_buf, length);
	USBD_CDC_TransmitPacket(&hUsbDeviceFS);
}
  • USB 的重新枚举函数:
/*USB 重新枚举函数*/
void USB_Reset(void)
{
    GPIO_InitTypeDef GPIO_InitStruct = {0};
	__HAL_RCC_GPIOA_CLK_ENABLE();
	GPIO_InitStruct.Pin = GPIO_PIN_12;
	GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
	GPIO_InitStruct.Pull = GPIO_NOPULL;
	GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
	HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
	HAL_GPIO_WritePin(GPIOA,GPIO_PIN_12,GPIO_PIN_RESET);
	HAL_Delay(100);
	HAL_GPIO_WritePin(GPIOA,GPIO_PIN_12,GPIO_PIN_SET);
}
  • 调用 USB 的复位:
  /* USER CODE BEGIN SysInit */
	
	USB_Reset();	//USB复位
	
  /* USER CODE END SysInit */
  • 使用 fft 的例子:
#include <stdio.h>

#include "arm_math.h"
#include "arm_const_structs.h"

#define TEST_LENGTH_SAMPLES 2048

extern float32_t testInput_f32_10khz[TEST_LENGTH_SAMPLES];//only have 1024
static float32_t testOutput[TEST_LENGTH_SAMPLES/2];
uint32_t fftSize = 1024;
uint32_t ifftFlag = 0;
uint32_t doBitReverse = 1;

/* 库的最大能量发生时的参考索引 */
uint32_t refIndex = 213, testIndex = 0;
  • 在主函数中添加以下代码:
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
	  
	arm_status status;
	float32_t maxValue;
	
	status = ARM_MATH_SUCCESS;
	
	/* Process the data through the CFFT/CIFFT module */
	arm_cfft_f32(&arm_cfft_sR_f32_len1024, testInput_f32_10khz, ifftFlag, doBitReverse);
	
	/* Process the data through the Complex Magnitude Module for
	calculating the magnitude at each bin */
	arm_cmplx_mag_f32(testInput_f32_10khz, testOutput, fftSize);
	
	/* Calculates maxValue and returns corresponding BIN value */
	arm_max_f32(testOutput, fftSize, &maxValue, &testIndex);
	
	if (testIndex !=  refIndex)
	{
		status = ARM_MATH_TEST_FAILURE;
	}
	
	/* ----------------------------------------------------------------------
	** Loop here if the signals fail the PASS check.
	** This denotes a test failure
	** ------------------------------------------------------------------- */
	
	if ( status != ARM_MATH_SUCCESS)
	{
		while (1);
	}
	
	while (1)
	{
		//printf("hello\n"); 
		HAL_Delay(5000);
		for(int i =0;i<1024;i++)
		{
			PrintfDebugUSB("%f \r\n",testOutput[i]);
			HAL_Delay(10);
		}
		while(1);
	}
  /* USER CODE END 3 */	
}

7、使用串口助手接收打印数据

在这里插入图片描述

8、用Excel整理我们接收到的数据转换为折线

在这里插入图片描述
以上便完成了我们对 DSP 库中的 fft 例子的调用。

  • 20
    点赞
  • 129
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

W_oilpicture

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值