本帖最后由 正点原子运营 于 2024-5-21 16:15 编辑
1)实验平台:正点原子 M144Z-M3 STM32F103最小系统板
2) 章节摘自【正点原子】M144Z-M3最小系统板使用指南——STM32F103版
6)正点原子STM32技术交流QQ群:725095144
本章介绍使用DSP库进行基本的数学运算。通过本章的学习,读者将学习到如何使用DSP库进行数学运算。 本章分为如下几个小节: 50.1 硬件设计 50.2 程序设计 50.3 下载验证
50.1 硬件设计 50.1.1 例程功能 1. 分别在使用和不使用DSP库的情况下进行正弦余弦计算,并分别在LCD上显示计算耗时 2. LED0闪烁,提示程序正在运行
50.1.2 硬件资源 1. LED LED0 - PB5 2. 正点原子 2.8/3.5/4.3/7/10寸TFTLCD模块
50.1.3原理图 本章实验使用的DSP库为软件库,因此没有对应的连接原理图。
50.2 程序设计 50.2.1 DPS库的使用 本章实验使用STM32CubeF1软件包中提供的DSP库,将其添加到工程文件夹后,如下图所示: DSP中就提供了大量用于数学运算的函数,例如:正弦、余弦的计算等。使用DSP库能加快各种算法的实现。 DSP库的使用方法也很简单,仅需将DSP库文件添加到工程中,并包含相应的头文件,就能调用DSP库中的函数了,具体请见本章实验的配套实验例程。
50.2.2 实验应用代码 本章实验的应用代码,如下所示: - int main(void)
- {
- float time;
- char buf[50];
-
- HAL_Init(); /* 初始化HAL库 */
- sys_stm32_clock_init(RCC_PLL_MUL9); /* 配置时钟,72MHz */
- delay_init(72); /* 初始化延时 */
- usart_init(115200); /* 初始化串口 */
- led_init(); /* 初始化LED */
- lcd_init(); /* 初始化LCD */
- btim_timx_int_init(0xFFFF, 7200 - 1); /* 初始化基本定时器 */
-
- lcd_show_string(30, 50, 200, 16, 16, "STM32", RED);
- lcd_show_string(30, 70, 200, 16, 16, "DSPBasicMath TEST", RED);
- lcd_show_string(30, 90, 200, 16, 16, "ATOM@ALIENTEK", RED);
-
- lcd_show_string(30, 110, 200, 16, 16, "No DSPruntime:", RED);
- lcd_show_string(30, 130, 200, 16, 16, "Use DSPruntime:", RED);
-
- while (1)
- {
- /* 不使用DSP库 */
- __HAL_TIM_SET_COUNTER(&g_timx_handle, 0);
- g_timeout = 0;
- if (sin_cos_test(PI / 6, 10000, 0) == 0)
- {
- time = __HAL_TIM_GET_COUNTER(&g_timx_handle) +
- (uint32_t)g_timeout * 0x10000;
- sprintf(buf, "%0.1fms\r\n", time / 10);
- lcd_show_string(150, 110, 200, 16, 16, buf, BLUE);
- }
- else
- {
- lcd_show_string(150, 110, 200, 16, 16, "Error", BLUE);
- }
-
- /* 使用DSP库 */
- __HAL_TIM_SET_COUNTER(&g_timx_handle, 0);
- g_timeout = 0;
- if (sin_cos_test(PI / 6, 10000, 1) == 0)
- {
- time = __HAL_TIM_GET_COUNTER(&g_timx_handle) +
- (uint32_t)g_timeout * 0x10000;
- sprintf(buf, "%0.1fms\r\n", time / 10);
- lcd_show_string(158, 130, 200, 16, 16, buf, BLUE);
- }
- else
- {
- lcd_show_string(158, 130, 200, 16, 16, "Error", BLUE);
- }
-
- LED0_TOGGLE();
- }
- }
复制代码从上面的代码中可以看出,分别调用了两次函数sin_cos_test()在使用DSP库和不使用DSP的情况下分别进行10000次进行正弦和余弦的计算测试,并使用定时器统计两者的计算耗时,最终在LCD上显示两个的计算耗时情况。 函数sin_cos_test()如下所示: - /* 定义误差值 */
- #define DELTA 0.0001f
- /**
- *@brief 正弦余弦测试
- *@param angle: 起始角度
- *@param times: 运算次数
- *@param mode: 是否使用DSP库
- *@arg 0: 不使用DSP库
- *@arg 1: 使用DSP库
- *@retval 计算结果
- *@arg 0: 计算无误
- *@arg 1: 计算错误
- */
- uint8_t sin_cos_test(float angle, uint32_t times, uint8_t mode)
- {
- float sinx;
- float cosx;
- float result;
- uint32_t i = 0;
-
- if (mode == 0)
- {
- /* 不使用DSP库计算正弦余弦 */
- for (i=0; i<times; i++)
- {
- cosx = cosf(angle);
- sinx = sinf(angle);
- result = sinx * sinx + cosx * cosx;
- result = fabsf(result - 1.0f);
-
- if (result > DELTA)
- {
- return 0xFF;
- }
-
- angle += 0.001f;
- }
- }
- else
- {
- /* 使用DSP库计算正弦余弦 */
- for (i=0; i<times; i++)
- {
- cosx = arm_cos_f32(angle);
- sinx = arm_sin_f32(angle);
- result = sinx * sinx + cosx * cosx;
- result = fabsf(result - 1.0f);
-
- if (result > DELTA)
- {
- return 0xFF;
- }
-
- angle += 0.001f;
- }
- }
-
- return 0;
- }
复制代码从上面的代码中可以看出,使用DSP库计算正弦、余弦时,使用了DPS库中的函数arm_cos_f32()和函数arm_sin_f32(),不使用DSP库正弦、余弦时,使用了C标准库中的函数consf()和函数sinf()。
50.3 下载验证 在完成编译和烧录操作后,可以看到LCD上分别显示了不使用DSP库和使用DSP库的运算耗时时间,从两者的耗时时间中,能看出使用DSP库进行数学运算有明显的速度优势。
|