前言
人生如逆旅,我亦是行人。
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功能是内核自带的:
其中较为重要的两个设计单元:
下面是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、进行各种配置
3、生成代码
4、Keil 中的配置
,__FPU_PRESENT=1,__FPU_USED=1,ARM_MATH_CM7,__CC_ARM
- 添加路径:
5、工程配置
6、添加代码
#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);
}
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_Reset();
#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];
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;
while (1)
{
arm_status status;
float32_t maxValue;
status = ARM_MATH_SUCCESS;
arm_cfft_f32(&arm_cfft_sR_f32_len1024, testInput_f32_10khz, ifftFlag, doBitReverse);
arm_cmplx_mag_f32(testInput_f32_10khz, testOutput, fftSize);
arm_max_f32(testOutput, fftSize, &maxValue, &testIndex);
if (testIndex != refIndex)
{
status = ARM_MATH_TEST_FAILURE;
}
if ( status != ARM_MATH_SUCCESS)
{
while (1);
}
while (1)
{
HAL_Delay(5000);
for(int i =0;i<1024;i++)
{
PrintfDebugUSB("%f \r\n",testOutput[i]);
HAL_Delay(10);
}
while(1);
}
}
7、使用串口助手接收打印数据
8、用Excel整理我们接收到的数据转换为折线
以上便完成了我们对 DSP 库中的 fft 例子的调用。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)