|**银杏科技有限公司旗下技术文档发布平台** |||| |技术支持电话|**0379-69926675-801** ||| |技术支持邮件|Gingko@vip.163.com ||| ^ 版本 ^ 日期 ^ 作者 ^ 修改内容 ^ | V1.0 | 2020-04-21 | gingko | 初次建立 | \\ \\ \\ \\ \\ ===== STM32CbeMX教程四十一——DSP_MATH实验 ===== 1. 新建工程:在主界面选择File-->New Project 或者直接点击ACCEE TO MCU SELECTOR {{ :icore3:icore3_cube_41_1.png?direct | }} 2. 出现芯片型号选择,搜索自己芯片的型号,双击型号,或者点击Start Project进入配置 在搜索栏的下面,提供的各种查找方式,可以选择芯片内核、型号等等,可以帮助你查找芯片。本实验选取的芯片型号为:STM32F407IGTx。 {{ :icore3:icore3_cube_41_2.png?direct | }} 3. 配置RCC,使用外部时钟源 {{ :icore3:icore3_cube_41_3.png?direct | }} 4. 配置调试引脚 {{ :icore3:icore3_cube_41_4.png?direct | }} 5. 将LED对应的3个引脚(PI5,PI6,PI7)设置为GPIO_Output {{ :icore3:icore3_cube_41_5.png?direct | }} 6. 引脚模式配置 {{ :icore3:icore3_cube_41_6.png?direct | }} 7. 设置串口 {{ :icore3:icore3_cube_41_7.png?direct | }} 8设置定时器 {{ :icore3:icore3_cube_41_8.png?direct | }} 9. 时钟源设置,选择外部高速时钟源,配置为最大主频 {{ :icore3:icore3_cube_41_9.png?direct | }} 10. 工程文件的设置, 这里就是工程的各种配置 我们只用到有限几个,其他的默认即可 IDE我们使用的是 MDK5 {{ :icore3:icore3_cube_41_10.png?direct | }} 11. 点击Code Generator,进行进一步配置 {{ :icore3:icore3_cube_41_11.png?direct | }} * **Copy all used libraries into the project folder** * 将HAL库的所有.C和.H都复制到所建工程中 * 优点:这样如果后续需要新增其他外设又可能不再用STM32CubeMX的时候便会很方便 * 缺点:体积大,编译时间很长 * **Copy only the necessary library files** * 只复制所需要的.C和.H(推荐) * 优点:体积相对小,编译时间短,并且工程可复制拷贝 * 缺点:新增外设时需要重新用STM32CubeMX导入 * **Add necessary library files as reference in the toolchain project configuration file** * 不复制文件,直接从软件包存放位置导入.C和.H * 优点:体积小,比较节约硬盘空间 * 缺点:复制到其他电脑上或者软件包位置改变,就需要修改相对应的路径 自行选择方式即可 12. 然后点击GENERATE CODE 创建工程 {{ :icore3:icore3_cube_41_12.png?direct | }} 创建成功,打开工程。 \\ \\ \\ \\ ===== 实验四十一:DSP_MATH实验 ===== ==== 一、 实验目的与意义 ==== - 了解STM32 DSP_MATH结构。 - 了解STM32 DSP_MATH特征。 - 掌握DSP_MATH使用方法。 - 掌握STM32 DSP_MATH库的配置方法 - 掌握Keil MDK集成开发环境使用方法。 ==== 二、 实验设备及平台 ==== - iCore3 双核心板。[[https://item.taobao.com/item.htm?spm=a1z10.1-c.w4024-251734887.3.5923532fXD2RIN&id=524229438677&scene=taobao_shop|点击购买]] - JLINK(或相同功能)仿真器。[[https://item.taobao.com/item.htm?spm=a1z10.5-c.w4002-251734908.13.20822b61MmPeNN&id=554869837940|点击购买]] - Micro USB线缆。 - Keil MDK 开发平台。 - STM32CubeMX开发平台。 - 装有WIN XP(及更高版本)系统的计算机。 ==== 三、 实验原理 ==== === 1、FPU简介 === * STM32F4xx属于Cortex M4F架构,带有32位的单精度硬件FPU(Float Point Unit),支持浮点指令集,相对比M0和M3架构,浮点运算性能高出数十倍甚至上百倍。CortexM4 FPU是ARM FPv4-SP单精度FPU一种实现形式。 === 2、DSP库的使用 === * STM32F4的Cortex-M4内核不仅内置硬件FPU单元,还支持DSP多种指令集,比如支持单周期乘加指令(MAC)、优化的单指令多数据指令(SIMD)等。因此Cortex-M4执行所有的DSP指令集都可以在单周期内完成,而Cortex-M3和M0需要多个指令和多个周期才能完成同样的功能。比如开方运算,M3和M0只能通过迭代法(标准数学函数库)计算,而M4F直接调用VSQRT指令完成。 * (1)获取DSP库 * ST官方提供了一整套的DSP库方便我们开发使用。在ST提供的标准库:stm32f4_dsp_stdperiph_lib.zip里面就有(该文件可以从ST官网上下载:http://www.st.com/web/en/catalog/tools/FM147/CL1794/SC961/SS1743/PF257901下载,文件名:STSW-STM32065)。下载解压缩之后,在目录STM32F4xx_DSP_StdPeriph_Lib_V1.4.0→Libraries→CMSIS→DSP_Lib下可以找到DSP库文件和测试实例。Sourse中是所有DSP库文件源代码,Examples文件夹下是一些测试实例。 * (2)DSP库简介 * ST提供了.lib格式的文件,方便使用这些库。这些.lib文件就是由Source文件夹下的源码编译生成的,如果想看某个函数的源码,可以在Source文件夹下面查找。.lib格式文件路径:STM32F4xx_DSP_StdPeriph_Lib_V1.4.0→Libraries→CMSIS→Lib→ARM,总共有8个.lib文件,和M4F相关的有两个: * arm_cortexM4bf_math.lib(浮点Cortex-M4大端模式) * arm_cortexM4lf_math.lib(浮点Cortex-M4小端模式) * STM32F4的内核CortexM4F采用小端模式,所以选择:arm_cortexM4lf_math.lib(浮点Cortex-M4小端模式)。 ==== 四、 实验程序 ==== === 1. 硬件FPU功能的开启 === * 默认情况下,STM32F4xx的FPU是禁用的,可以通过设置协处理器控制寄存器(CPACR)来开启硬件FPU。在keil编程环境下,可以通过定义全局宏定义标识符_FPU_PRESENT和_FPU_USED都为1来开启硬件FPU。其中宏定义标识符_FPU_PRESENT用来确认处理是否带有FPU功能,标识符_FPU_USED用来确定是否开启FPU功能。实际上,因为STM32F4是带有FPU功能的,所以在stm32f4xx.h头文件中,默认定义_FPU_PRESENT为1。若要开启FPU还需要在头文件stm32f4xx.h中定义标示符_FPU_USED的值为1。即在刚才的宏定义下边添加一个宏定义。 #de-fi-ne __CM4_REV 0x0001U /*!< Core revision r0p1 */ #de-fi-ne __MPU_PRESENT 1U /*!< STM32F4XX provides an MPU */ #de-fi-ne __NVIC_PRIO_BITS 4U /*!< STM32F4XX uses 4 Bits for the Priority Levels */ #de-fi-ne __Vendor_SysTickConfig 0U /*!< Set to 1 if different SysTick Config is used */ #de-fi-ne __FPU_PRESENT 1U /*!< FPU present */ #define __FPU_USED 1U * 至此则完成硬件FPU的使能。在程序中如果遇到浮点运算就会使用硬件FPU相关指令,执行浮点运算,大大提升系统浮点运算速度。 === 2. DSP库编程环境搭建 === * 首先添加库文件。在工程目录下新建DSP_LIB文件夹用于存放库文件。然后把arm_cortexM4lf_math.lib和相关头文件(路径STM32F4xx_DSP_StdPeriph_Lib_V1.4.0\ Libraries\CMSIS\Include 里的文件)拷贝到DSP_LIB文件夹中。 * **附**:ST官方提供了一整套的DSP库方便我们开发使用。在ST提供的标准库:stm32f4_dsp_stdperiph_lib.zip里面就有,该文件可以从ST官网上下载:http://www.st.com/web/en/catalog/tools/FM147/CL1794/SC961/SS1743/PF257901下载,文件名:STSW-STM32065。下载解压缩之后,在目录STM32F4xx_DSP_StdPeriph_Lib_V1.4.0→Libraries→CMSIS→DSP_Lib下可以找到DSP库文件和测试实例。Sourse中是所有DSP库文件源代码,Examples文件夹下是一些测试实例里的文件)。 * 然后打开工程,新建DSP_LIB分组,并将arm_cortexM4lf_math.lib添加到工程里面。 * 添加好文件之后,需要添加头文件包含路径,将第一步拷贝的Include文件夹和DSP_LIB文件夹,加入头文件包含路径。打开工程属性设置面板,然后点击”C/C++“选项卡,点击对号处,弹出include path设置面板。添加”..\DSP_LIB“和“..\DSP_LIB\Include“两个路径。 {{ :icore3:icore3_arm_hal_41_1.png?direct |}} * 最后,为了能够使用DSP库的所有功能,还需要添加以下几个全局宏定义 * 1、ARM_MATH_CM4 {{ :icore3:icore3_arm_hal_41_2.png?direct |}} * 2、_CC_ARM * 3、ARM_MATH_MATRIX_CHECK * 4、ARM_MATH_ROUNDING * 添加方法是打开工程属性设置面板,然后点击”C/C++“选项卡,在“Preprocessor Symbols“下的”Define:”文本框中进行添加。两个宏之间用“,”隔开。 === 3. 主函数 === * 主函数中通过定时器计时,计算在普通模式下浮点数的计算所用时间与DSP模式下计算浮点数所用时间相对比,将结果打印在屏幕上,显而易见,DSP模式所花费的时间更少。 int main(void) { /* USER CODE BEGIN 1 */ int i,j; int res; float time[2]; static int error_flag = 0; /* USER CODE END 1 */ /* MCU Configuration--------------------------------------------------------*/ /* Reset of all peripherals, Initializes the Flash interface and the Systick. */ HAL_Init(); /* USER CODE BEGIN Init */ /* USER CODE END Init */ /* Configure the system clock */ SystemClock_Config(); /* USER CODE BEGIN SysInit */ /* USER CODE END SysInit */ /* Initialize all configured peripherals */ MX_GPIO_Init(); MX_TIM3_Init(); MX_UART4_Init(); /* USER CODE BEGIN 2 */ usart4.initialize(115200); usart4.printf("\x0c"); usart4.printf("\033[1;32;40m"); usart4.printf("Hello, I am iCore4!\r\n\r\n"); usart4.printf("DSP BasicMath TEST......\r\n"); /* Infinite loop */ /* USER CODE BEGIN WHILE */ while (1) { /* USER CODE END WHILE */ /* USER CODE BEGIN 3 */ timeout = 0; __HAL_TIM_SET_COUNTER(&htim3,0); for(j = 0;j < 10000;j++){ for(i = 0;i < MAX_BLOCKSIZE;i ++){ res = SinCos_Test(testInput_f32[i],0); if(res != 0)error_flag ++; } } time[0] = __HAL_TIM_GET_COUTER(&htim3)+ timeout*5000; timeout = 0; __HAL_TIM_SET_COUNTER(&htim3,0); for(j = 0;j < 10000;j++){ for(i = 0;i < MAX_BLOCKSIZE;i ++){ res = SinCos_Test(testIput_f32[i],1); if(res != 0)error_flag ++; } } time[1] = __HAL_TIM_GET_COUTER(&htim3)+ timeout*5000; if(error_flag == 0){ usart4.printf("*NO DSP MATH LIB runtime:%0.1fms *USE DSP MATHLIB runtime:%0.1fms\r",time[0]/10,time[1]/10); LED_GREEN_ON; LED_RED_OFF; LED_BLUE_OFF; } else{ usart4.printf("Error\r"); LED_GREEN_OFF; LED_RED_ON; LED_BLUE_OFF; } } === 4. 计算函数 === int SinCos_Test(float testInput,unsigned char mode) { float Sinx,Cosx; float Result; switch (mode){ case 0: //不适用DSP_MATH库 Sinx = sinf(testInput); Cosx = cosf(testInput); Result = Sinx*Sinx + Cosx*Cosx; Result = fabsf(Result-1.0f); if(Result > DELTA)return -1; break; case 1://使用DSP_MATH库 Sinx = arm_sin_f32(testInput); Cosx = arm_cos_f32(testInput); Result = Sinx*Sinx + Cosx*Cosx; Result = fabsf(Result-1.0f); if(Result > DELTA)return -1; break; default: break; } return 0; } } time[0] = __HAL_TIM_GET_COUTER(&htim3)+ timeout*5000; timeout = 0; __HAL_TIM_SET_COUNTER(&htim3,0); for(j = 0;j < 10000;j++){ for(i = 0;i < MAX_BLOCKSIZE;i ++){ res = SinCos_Test(testIput_f32[i],1); if(res != 0)error_flag ++; } } time[1] = __HAL_TIM_GET_COUTER(&htim3)+ timeout*5000; if(error_flag == 0){ usart4.printf("*NO DSP MATH LIB runtime:%0.1fms *USE DSP MATHLIB runtime:%0.1fms\r",time[0] / 10, time[1] / 10); LED_GREEN_ON; LED_RED_OFF; LED_BLUE_OFF; } else{ usart4.printf("Error\r"); LED_GREEN_OFF; LED_RED_ON; LED_BLUE_OFF; } } === 5. 启动定时器计数模式 === void HAL_TIM_Base_MspInit(TIM_HandleTypeDef* tim_baseHandle) { if(tim_baseHandle->Instance==TIM3) { __HAL_RCC_TIM3_CLK_ENABLE(); HAL_NVIC_SetPriority(TIM3_IRQn, 1, 0); HAL_NVIC_EnableIRQ(TIM3_IRQn); HAL_TIM_Base_Start_IT(&htim3);//开启定时器中断计数模式 } } ==== 五、 实验步骤 ==== - 把仿真器与iCore3的SWD调试口相连(直接相连或者通过转接器相连); - 把iCore3通过Micro USB线与计算机相连,为iCore3供电; - 打开Keil MDK 开发环境,并打开本实验工程; - 烧写程序到iCore3上; - 也可以进入Debug模式,单步运行或设置断点验证程序逻辑; - 打开串口软件,显示运行结果。 ==== 六、 实验现象 ==== * 串口软件将会显示计算结果,LED将会表示状态。 {{ :icore3:icore3_arm_hal_41_3.png?direct |}}