如何在STM32中使用arm_math.h并移植DSP库
摘要:在程序编写中使用到了cos,sin,arctan等函数,这些函数如果直接调用math.h文件进行计算,耗时长且效率低下。通过了解网上已有信息了解到,STM32可以通过使用arm_math.h这个头文件内的DSP运算函数提升运行效率。本文以使用STM32F722芯片为例。
(一)cubeMX中的配置
按下图顺序先在cubeMX中安装DSP相关软件包,依次点击 :
Software Packs->Select Component->Software Component Class->DSP Library
要是没有调出上图界面需要找到这个按钮并单击,在完成DSP软件包的安装后,窗口左侧栏目中将出现Middleware and Software Packs,继续按如下进行操作找到X-CUBE-ALGOBUILD选项并勾选DSP Library Library。随后保存工程并正常生成代码。如果卡死在了生成代码的部分,可能是因为工程命名的问题,尽量不要出现字母数组下划线以外的命名,这会导致生成代码的时候卡死。
(二)keil中的配置
点击魔法棒,在C/C++这一栏中添加 ,ARM_MATH_CM7,__FPU_PRESENT 值得注意的是,如果是F4系列芯片,则应该添加 ,ARM_MATH_CM4,__FPU_PRESENT 目前根据本人了解这个arm_math.h对应的DSP类型的函数计算只在F4以上的芯片类型支持。
同样在点击魔法棒选项并选择C/C++这一栏,在路径Include Path中添加Drivers\CMSIS\DSP
新路径的添加需要手动进行选择,不能直接输入,点击 … 这个选项后依据自己的当前工程文件DSP库的存储位置选择即可,本人的工程文件存储位置如图所示,仅做参照
任意寻找一个.c文件点击右侧加号,在新展开的列表中找到stm32f722xx.h并打开,注释掉下方提到的此行代码,完成上述所有操作后,再次进行编译程序不再出错及警告。
#define __FPU_PRESENT 1U /*!< FPU present */
(三)上述配置完成后如若不行的额外尝试
注意:若在使用arm_math.h内的函数出现undefine XXX 时尝试以下操作,添加入下图所示的文件,该文件的型号需要依照具体型号而定,该文件的添加方法如下图,在CMSIS这一栏的DSP选项打钩,并再次编译运行。
注意:完成配置后如果再次使用CubeMX生成代码可能会出现下图的情况,本人的解决方法是再次打开魔法棒里的C/C++选项,点击红叉移除红色框内部分而保留蓝色框,并检查下面这行stm32f722xx.h内的代码是否仍保持被注释的状态,完成上述操作后再次编译即可不再出现30Error 5Waring这种情况
#define __FPU_PRESENT 1U /*!< FPU present */
下面提供一些测试代码,经测试,函数可以正常运行并计算。
这段代码放在任意的.c.h文件里
float PI_180=0.017453292519943295;//pi/180
float degrees_to_radians(float degrees)
{
return degrees * PI_180;
}
/**
* @brief 对角度进行COS运算
* @param Angle:需要进行运算的角度(角度制)
* @retval 进行cos运算完后的角度结果
*/
double Cos_Angle(double Angle)
{
double angle=degrees_to_radians(Angle);//将角度由度变换为弧度
double reslut=arm_cos_f32(angle);
return reslut;
}
/**
* @brief 对角度进行SIN运算
* @param Angle:需要进行运算的角度(角度制)
* @retval 进行sin运算完后的角度结果
*/
double Sin_Angle(double Angle)
{
double angle=degrees_to_radians(Angle);//将角度由度变换为弧度
double reslut=arm_sin_f32(angle);
return reslut;
}
下面这段代码为上述函数在主函数中的调试方法, 串口发送函数是自定义的,使用任意方式将测试结果发出来以验证准确性即可,可以看到计算的结果还是较为准确的
while (1)
{
float cosa=Cos_Angle(30);
float sina=Sin_Angle (60);
send_string("cosa= ",&huart1);
send_double(cosa,&huart1);
send_string(" ",&huart1);
send_string("sina= ",&huart1);
send_double(sina,&huart1);
send_string("\r\n",&huart1);
}
(四)一个小小的问题
虽说可以正常使用了,但是有个莫名奇妙的问题,本人在使用这个arm_math.h文件里的函数可以实现运算操作,但无法使用go to the defination选项直接跳转到函数的定义,且同一工程下的非该文件的其余函数均可完成跳转到定义的操作。 有知道怎么解决的欢迎评论一下。
作者:阿 尔 托 莉 雅