【STM32】 DSP库函数的一些基本使用

news/2024/10/30 15:24:29/

对于一些刚接触STM32的童靴来说,DSP库一定是一个陌生的东西。通俗来说,DSP库就是为了让MCU能够使用像DSP(数字信号处理的芯片)功能弄的一些官方库函数,它是基于MCU的FPU(浮点运算功能)的,如果你连FPU都不知道咋开,我个人建议先去查一查啥是FPU以及DSP库移植的一些步骤(移植也分两种,一种是使用lib文件,另一种是直接的C语言函数库)。
这里推荐的参考资料是:安富莱的STM32-V6开发板_第二版DSP数字信号处理教程,下载链接在这里:https://download.csdn.net/download/qq_32006213/87406373
说实话,只要能认真看这个教程,也不需要看我这个文章在这里BB了,这里仅做一些整理。

【一】类型:浮点数、定点数;浮点数就有:
float32_t→float;float64_t→double;定点数就不介绍了,一般也很少用到。这里需要注意的是,如果你使用的是STM32,那么就一定要注意你的浮点计算往往在一开始就因为你传入的数值不是浮点型或者是被编译器给你整成其他类型而变慢了。例如在运算时你需要使用一个数:1.234,你直接在公式中写:

NMSL = 1.234 - 5;
或者
Fun(1.234);

那恭喜你,喜提慢速计算。为啥,因为单片机认为你传入的 1.234并不是浮点型而是double型,而单片机只有FPU却没有针对double类型快速计算的模块,就只能硬着头皮去算了。
还有一点就是,如果你使用一些math.h中的传统C库的函数,它的入参默认就是double类型,那即便你确保传入的是浮点数同样也会很慢。个人认为这就是传统库相比DSP库的劣势之一,当然不是不让你用double类型,而是都是用浮点型时,DSP库会更快罢了。为了解决以上的问题,可以改为:

NMSL = 1.234f - 5.0f;
或者
Fun(1.234f);

所以第一个需要注意点就是,确保你的变量类型没有错误,基本上使用float32_t即可。
【二】常用函数:
2.1 三角函数:arm_cos_f32/arm_sin_f32/arm_sin_cos_f32
使用案例:

#define PI 3.141592f
float32_t Angle = 60.0f;
float32_t Angle_Arc = Angle/180*PI;
float32_t Cos = 0.0f;
float32_t Sin = 0.0f;
Cos = arm_cos_f32(Angle_Arc);//注意这个函数要传入的东西是弧度制
Sin = arm_sin_f32(Angle_Arc);//注意这个函数要传入的东西是弧度制
arm_sin_cos_f32(Angle,&Sin,&Cos);//这个函数顶级就顶级在它可以直接传角度,而且角度是可以有小数的,但是使用方式就完全不同了。

2.2 平方根:arm_sqrt_f32

float32_t Input = 9.0f;
float32_t Output = 0.0f;
arm_sqrt_f32(Input,&Output);//这样Output上获得的就是平方根,暂时没试过负数能开出来不,可能有风险哦。

2.3 最大值、最小值、平均值
2.3.1最大值:arm_max_f32 最小值:arm_min_f32

float32_t Array[3]={0f,1.2f,1.3f};
float32_t Min = 0.0f;
uint32_t Min_index = 0;
float32_t Max = 0.0f;
uint32_t Max_index = 0;
arm_max_f32(Array,3,&Max,&Max_index);//数组:长度;获得的最小值;最小值在数组中的位置
arm_min_f32(Array,3,&Min,&Min_index);//最为强大的就是能找到位置啦

实际上第二个参数也可以不使用整体长度,第一个参数也可以不传入数组第一个元素的地址。如果你想要求局部的最大/最小,可以通过操控第一个参数传入你想要从哪一个数据开始计算的n地址,例如:
(float32_t *)(Array +n)→表示从第n个开始,至于为什么这么写,是因为有很多不同的类型,这样写是习惯比较稳妥,更多的可以自行去查询(uint32_t *)Array+n 这样为什么会有问题【提示:Memcpy函数也需要注意】。然后长度填5。那么现在就是求数组第n个开始五个数中间的最大/最小值啦。
2.3.2 平均值 arm_mean_f32

float32_t Array[3]={0f,1.2f,1.3f};
float32_t Mean = 0.0f;
arm_mean_f32(Array,3,&Mean);

2.4 标准差、均方根、方差
这三者在统计上具有较大的意义,在处理一系列的数据时可能用的到,至于每个数表示啥意思请自行查询。

float32_t Array[3]={0f,1.2f,1.3f};
float32_t Std = 0.0f;
float32_t Rms = 0.0f;
float32_t Var = 0.0f;
arm_std_f32(Array,3,&Std);//标准差
arm_rms_f32(Array,3,&Rms);//均方根
arm_var_f32(Array,3,&Var);//方差

2.5数据拷贝、填充

float32_t Array_A[3]={0f,1.2f,1.3f};
float32_t Array_B[3];
arm_copy_f32(Array_A,Array_B,3);//拷贝
arm_fill_f32(5.0f,Array_B,3);//将5.0f填充至Array_B

2.6基本运算:求和、求差、求乘法、求点乘、求绝对值、求相反数、求比例化
以上基本上都是面对两个数组多个数据进行的,如果本身就没多少变量/数,直接公式算也不差。

float32_t Array_A[3]={0f,1.2f,1.3f};
float32_t Array_B[3] ={3.5f,-5.0f,2.5f};
float32_t Result_Array[3];
float32_t Dot_result;
arm_add_f32(Array_A,Array_B,Result_Array,3);//求和:Result_Array[n] = Array_A[n]+Array_B[n]
arm_sub_f32(Array_A,Array_B,Result_Array,3);//求差:Result_Array[n] = Array_A[n]-Array_B[n],这个要记得是前面减去后面
arm_abs_f32(Array_B,Result_Array,3);//求绝对值Result_Array[n] =|Array_B[n]|
arm_mult_f32(Array_A,Array_B,Result_Array,3);//求乘法Result_Array[n] = Array_A[n]*Array_B[n]
arm_dot_prod_f32(Array_A,Array_B,3,&Dot_result);//点乘得到的是一个值,详情看线性代数。Dot_result = Array_A[0]*Array_B[0]+···Array_A[2]*Array_B[2]
arm_negate_f32(Array_A,Result_Array,3);//求相反数:Result_Array[n] = -Array_A[n]
arm_scale_f32(Array_A,1.5f,Result_Array,3);//求比例乘积后:Result_Array[n] = Array_A[n]*1.5f;

2.7 矩阵运算、复数运算
基本上用不到,而且拿单片机算矩阵未免有那么一点点刁难它。一般的步骤都是复杂的运算在Matlab上运行,将算法简化为单一的公式再在arm上实现,这里就不继续讲解了。如果一定要使用矩阵,这里提三点意见:
1.使用矩阵一定要严格按照Arm_math中的矩阵定义来使用,如果要秀操作搞数组,就用不了DSP库了。关于矩阵的定义和初始化,一定要详细看清楚:arm_matrix_instance_f32这个结构体的定义。
2.单片机算矩阵运算很有可能算不出结果而一直递归,别问我怎么知道的…包括你在Matlab上算一些矩阵的运算,如果它本身就不成立,那就没有意义,会一直不收敛。
3.DSP库的逆矩阵求法是有局限性的,有些你在matlab上算的出来,DSP库缺不能求解。所以如果遇到问题,建议先仿真看看,确保矩阵和数值没有问题。


http://www.ppmy.cn/news/520352.html

相关文章

STM32_arm_sin_f32和sin的区别

FOC控制中会用到三角函数 调试通信的时候,也会用三角函数产生一个测试波形 优化三角函数的运行时间是一个不可避免的事情,而幸运的是,前人已经把树种上了。 用专用的浮点运算单元FPU来做浮点运算,比用STM32本身来做浮点运算要快…

STM32F1 FFT初试

1、STM32有dsp库,百度一堆的文章,注意有f4有硬件fft可以使用arm_rfft_fast_init_f32,F1不能使用,F1可以使用arm_cfft_radix4_init_f32,256长度1024长度,arm_cfft_radix2_init_f32 512长度。 2、采样率FFT_S…

UVM1.2究竟在UVM1.1上做了哪些升级

想必大家平时也没有很注意UVM1.1版本和UVM1.2版本的不同之处,只有在用一些以前UVM1.1能支持的功能,到了UVM1.2却出现编译报错,找不到对应的变量或者函数或者类的时候,才意识到这两个版本的差异。笔者也是遇到了1个打印问题&#x…

【webFlux】使用zip()或concatMap操作符处理两个表,基于条件修改两个表

要响应式地处理两个列表,并基于条件修改第一个列表的一个bean,并根据条件修改第二个列表中对应bean的属性,你可以使用RxJava的操作符来实现。 以下是一个示例代码,展示了如何响应式地处理两个列表并进行相应的修改操作: Observable<List<Bean1>> list1Obser…

基于Web的数字家庭网站设计与实现【附开题报告和万字文档(Lun文)】

主要功能 前台登录&#xff1a; ①主页&#xff1a;新闻信息展示、最新动态、家庭亲子视频展示、亲友动态展示 ②论坛&#xff1a;发布帖子 ③家庭亲自视频&#xff1a;视频类型分类、亲子视频标题 ④家庭日记&#xff1a;日记类型分类、日记标题 ⑤新闻信息&#xff1a;新闻类…

航天双五归零

技术归零中&#xff1a; 定位准确是前提&#xff0c;机理清楚是关键&#xff0c;问题复现是手段&#xff0c;措施有效是核心&#xff0c;举一反三是延伸。 管理归零中&#xff1a; 过程清楚是基础&#xff0c;责任明确是前提&#xff0c;措施落实是核心&#xff0c;严肃处理…

航天动力学

航天动力学是研究航天器和运载器在飞行中所受的力及其在力作用下的运动的学科&#xff0c;又称星际航行动力学。航天动力学研究的运动包括航天器的质心运动&#xff0c;称轨道运动&#xff1b;航天器相对于自身质心的运动和各部分的相对运动&#xff0c;称姿态运动&#xff1b;…

银河航天简介

徐鸣&#xff0c;董事长、创始人 2018年10月25日6时57分&#xff0c;银河航天试验载荷“玉泉一号”搭载长征四号乙运载火箭&#xff08;CZ-4B&#xff09;&#xff0c;在太原卫星发射中心发射升空。“玉泉一号”是银河航天自研的试验载荷&#xff0c;将在阿里巴巴“糖果罐号”迷…