概述
前言
人生如逆旅,我亦是行人。
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:Keil5ARMPACKARMCMSIS5.8.0CMSISDSP
-
帮助文件位于:F:Keil5ARMPACKARMCMSIS5.8.0CMSISDocumentationDSPhtmlindex.html
-
官方例程:F:Keil5ARMPACKARMCMSIS5.8.0CMSISDSPExamplesARM
四、利用 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("hellon");
HAL_Delay(5000);
for(int i =0;i<1024;i++)
{
PrintfDebugUSB("%f rn",testOutput[i]);
HAL_Delay(10);
}
while(1);
}
/* USER CODE END 3 */
}
7、使用串口助手接收打印数据
8、用Excel整理我们接收到的数据转换为折线
以上便完成了我们对 DSP 库中的 fft 例子的调用。
最后
以上就是虚心唇彩为你收集整理的STM32H750VBT6的DSP使用的学习——基于CubeMX前言1、STM32H7的DSP功能介绍二、ARM 提供的 CMSIS-DSP 库三、获取 DSP 库的学习资料四、利用 CubeMX 进行配置的全部内容,希望文章能够帮你解决STM32H750VBT6的DSP使用的学习——基于CubeMX前言1、STM32H7的DSP功能介绍二、ARM 提供的 CMSIS-DSP 库三、获取 DSP 库的学习资料四、利用 CubeMX 进行配置所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复