你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

体验NUCLEO-G474RE板卡试用

[复制链接]
gaosmile 发布时间:2020-3-4 16:31

资源篇


外观还是一如既往的靓,简洁美观。板子搭载的是M4内核,速度快,高达170M主频,和数学运算加速器CORDIC大大提高运算能力, 输入电压范围1.71~3.6V,512Flash,128的SRAM,1个用户LED,一个用户按键,32.768khz的外部低速晶振,外接24M的高速晶振,Micro-AB连接器,Arduino™ Uno V3连接器可扩与Arduino™ Uno V3连接,板载STLINK_V3仿真调试器,调试器的主控是STM32F723,下载速度得到的很大的提高。

STM32G474资源介绍:

微信图片_20200304161117.jpg

STM32G474开发板实物图:

微信图片_20200304161126.jpg
▲ 开发板实物图
开发板分为上下两部分,上半部分为ST-LINK-V3仿真器,可以给开发板进行调试和程序下载。下半部分是G474的最小系统板:全IO引出,兼容流行的Arduino扩展口如下图所示。值得一提的是:上半部分的ST-LINK是可以通过断开跳帽之后可以单独作为调试器使用。
微信图片_20200304161133.jpg



实战篇


测试内容:
  • IO测试
  • 虚拟串口VCP测试
  • FPU测试
  • DSP测试

1. LED和GPIO测试1

(1) 原理:短按一下按键,LED点亮,再短按一下按键LED熄灭。(2) 步骤:使用CubeCubeMx生成工程。
微信图片_20200304161144.png
▲ 引脚配置
时钟配置:外接24M晶振,高达170M主频
微信图片_20200304161151.png

生成工程,固件包版本V1.1.0。

微信图片_20200304161159.png

代码:
微信图片_20200304161209.png

结果:短按一下按键,LED点亮,再短按一下按键LED熄灭。

结论:使用MX配置简单快速。

2. VCP虚拟串口测试1

(1) 原理:
MCU与stlik连接
微信图片_20200304161216.png

虚拟串口连接MCU的LPUART1
微信图片_20200304161224.png
(2) 配置工程:
微信图片_20200304161240.jpg

相关代码:
微信图片_20200304161249.png

微信图片_20200304161258.png

(3)结果:如下所示,按一次按键就打印一个“OK”,LED一亮灭交替。
微信图片_20200304161307.png

结论:这个功能在我们调试的时候十分方便,节省了很多的资源和时间。

3.FPU性能测试1

原理:
FPU浮点运算单元,如果CPU上没有FPU进行浮点运算的话必须按照IEEE标准进行运算十分的耗时,相较之下具有FPU的处理器在计算浮点运算是非常快的,G474Nucleo板载FPU运算加速器,运算性能非常出色,我们可以通过简单的测试来测一下板子的FPU的性能,可以通过计算使用FPU时单精度的乘除法使用的时间和没有使用FPU时消耗的时间进行比较来得出结论,其中时间的计数我们使用的是systick定时器。

步骤:
首先我们要学会打开硬件FPU,我们要设置 CPACR寄存器,其中在SystemInit函数中已经写好怎么配置,如下图:
微信图片_20200304161315.png

我们只需要添加宏定义__FPU_PRESENT =1 ,_FPU_USED=1就可以了,而默认已经定义了__FPU_PRESENT =1,我们还需要添加_FPU_USED=1,在target 的Code Generation 选single Precision 就行了,如下图。

微信图片_20200304161323.png

相关代码如下:双精度和单精度计算函数

  1. /**
  2.   * @name  DoubleD
  3.   * @brief 双精度乘除法.
  4.   * @param angle:起始值,times:计算次数,
  5. *mod:1除法0乘法
  6.   */
  7. void DoubleD(double angle,uint32_t times,uint8_t mode)
  8. {
  9.     uint32_t i;
  10.     double result;
  11.     if(mode)//除法
  12.     {
  13.         for(i=0;i<times;i++)
  14.         {
  15.             result = angle/PI;
  16.             angle += 0.00001f;
  17.         }        
  18.     }
  19.     else//乘法
  20.     {
  21.         for(i=0;i<times;i++)
  22.         {
  23.             result = angle*PI;
  24.             angle += 0.00001f;
  25.         }
  26.     }
  27. }
复制代码





  1. /**
  2.   * @name  FloatXFloat
  3.   * @brief 单精度乘除法.
  4. * @param angle:起始值,times:计算次数,*mod:1除法0乘法
  5.   */
  6. void FloatXFloat(float angle,uint32_t times,uint8_t mode)
  7. {
  8.     uint32_t i;
  9.     float result;
  10.     if(mode)//除法
  11.     {
  12.         for(i=0;i<times;i++)
  13.         {
  14.             result = angle/PI;
  15.             angle += 0.00001f;
  16.         }        
  17.     }
  18.     else//乘法
  19.     {
  20.         for(i=0;i<times;i++)
  21.         {
  22.             result = angle*PI;
  23.             angle += 0.00001f;
  24.         }
  25.     }
  26. }
复制代码


主函数

  1. int main(void)
  2. {
  3.   /* USER CODE BEGIN 1 */
  4.   /* USER CODE END 1 */
  5.   /* MCU Configuration--------------------------------------------------------*
  6.   /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  7.   HAL_Init();
  8.   /* USER CODE BEGIN Init */
  9.   /* USER CODE END Init */
  10.   /* Configure the system clock */
  11.   SystemClock_Config();
  12.   /* USER CODE BEGIN SysInit */
  13.   /* USER CODE END SysInit */
  14.   /* Initialize all configured peripherals */
  15.   MX_GPIO_Init();
  16.   MX_USART1_UART_Init();
  17.   MX_LPUART1_UART_Init();
  18.   /* USER CODE BEGIN 2 */
  19.   HAL_Init();
  20.   /* USER CODE END 2 */
  21. /* Infinite loop */
  22.   /* USER CODE BEGIN WHILE */
  23.   while (1)
  24.   {
  25.     /* USER CODE END WHILE */
  26.     /* USER CODE BEGIN 3 */
  27.     printf("---------------NOT USER FPU----------------------\n");
  28.     //-------------------测试单精度乘法----------------------------------------
  29.     start_tim = HAL_GetTick();   
  30.     //乘法
  31.     FloatXFloat(PI/6,TIMES,0);      
  32.     end_tim = HAL_GetTick();
  33.     if(end_tim > start_tim)
  34.     {
  35.         tim_cnt = end_tim - start_tim;
  36.     }
  37.     else
  38.     {
  39.         tim_cnt = 0xffffffff - start_tim + end_tim;
  40.     }
  41.     printf("单精度乘法-- %d ms\r\n",tim_cnt);    //显示运行时间  
  42.     //-----------------测试单精度除法-------------------------------------------
  43.     start_tim = HAL_GetTick();
  44.     //除法
  45.     FloatXFloat(PI/6,TIMES,1);
  46.     end_tim = HAL_GetTick();
  47.     if(end_tim > start_tim)
  48.     {
  49.         tim_cnt = end_tim - start_tim;
  50.     }
  51.     else
  52.     {
  53.         tim_cnt = 0xffffffff - start_tim + end_tim;
  54.     }
  55.     printf("单精度除法-- %d ms\r\n",tim_cnt);    //显示运行时间
  56.     //-----------------测试双精度乘法-------------------------------------------
  57.     start_tim = HAL_GetTick();
  58.     //乘法
  59.     DoubleD(PI/6,TIMES,1);
  60.     end_tim = HAL_GetTick();
  61.     if(end_tim > start_tim)
  62.     {
  63.         tim_cnt = end_tim - start_tim;
  64.     }
  65.     else
  66.     {
  67.         tim_cnt = 0xffffffff - start_tim + end_tim;
  68.     }
  69.     printf("双精度乘法-- %d ms\r\n",tim_cnt);    //显示运行时间     
  70.     //-----------------测试双精度除法-------------------------------------------
  71.     start_tim = HAL_GetTick();
  72.     //除法
  73.     DoubleD(PI/6,TIMES,1);

  74.     end_tim = HAL_GetTick();
  75.     if(end_tim > start_tim)
  76.     {
  77.         tim_cnt = end_tim - start_tim;
  78.     }
  79.     else
  80.     {
  81.         tim_cnt = 0xffffffff - start_tim + end_tim;
  82.     }
  83.     printf("双精度除法-- %d ms\r\n",tim_cnt);    //显示运行时间


  84.     HAL_GPIO_TogglePin(USER_LED_GPIO_Port,USER_LED_Pin);      
  85.     HAL_Delay(500);
  86.   }
  87.   /* USER CODE END 3 */
  88. }
复制代码



测试结果:
条件:输入参数angle:起始值 = π/6,times:计算次数 = 20000(两万),mod:乘除法时。

(1)没有打开FPU
微信图片_20200304161329.png

(2)打开FPU
微信图片_20200304161336.png

数据比较

打开FPU(ms)
关闭FPU(ms)
比例
单精度乘法
1
9
9
单精度除法
3
13
4.3
双精度乘法
17
16
0.9
双精度乘法
21
21
1
微信图片_20200304161343.jpg

得出结论
打开FPU和没有打开FPU在浮点计算性能上有明显的提高,测试中可以看出在单精度乘法上性能上比较明显,速度大概是没有打开FPU的9倍左右,单精度除法则提升没有那么高4.3倍左右,在双精度上的运算则没有起到作用,耗时基本相同,所以FPU在单精度上计算速度上比较快对于双精度计算则不起作用。

4. DSP测试1

原理:
M4内核除了集成硬件FPU外,还带有DSP指令,还有相应的加速单元增加了数据的处理能力和运算速度,ST还提供了DSP算法相关的库 ,大大的提高了我们开发速度和效率 ,为了展示DSP的性能,我使用ST提供的标准库数学运算的运算速度和使用DSP库的提供的数学函数的运算速度比较,参考原子的比较方式,现在我们用过sin(x)² +cos(x)² = 1 这个运算,首先我们以x为变量,x从π/6开始,每次累加0.001,累加200000次,每次的结果的误差不能大于0.00005的运算时间进行比较,可以得到使用DSP和不使用DSP运算速度上的差别。
步骤:
在原来的工程上加入DSP库的头文件和源文件,并包含头文件路径,还要打开硬件FPU,添加宏定义,添加头文件和lib。
微信图片_20200304161357.png

微信图片_20200304161404.png

打开FPU,在target 的Code Generation 选singlePrecision。
微信图片_20200304161411.png

减价宏定义ARM_MATH_CM4。
微信图片_20200304161418.png

测试主要代码:
运算函数:

  1. //sin cos测试
  2. //angle:起始角度
  3. //times:运算次数
  4. //mode:0,不使用DSP库;1,使用DSP库
  5. //返回值:0,成功;0XFF,出错
  6. uint8_t sin_cos_test(float angle,uint32_t times,uint8_t mode)
  7. {
  8.     float sinx,cosx;
  9.     float result;
  10.     uint32_t i=0;
  11.     if(mode==0)
  12.     {
  13.         for(i=0;i<times;i++)
  14.         {
  15.             cosx=cosf(angle);  //不使用DSP优化的sin,cos函数
  16.             sinx=sinf(angle);
  17.             result=sinx*sinx+cosx*cosx;//计算结果应该等于1  
  18.             result=fabsf(result-1.0f);//对比与1的差值
  19.             if(result>DELTA)
  20.             {
  21.                 return 0XFF;      //判断失败
  22.             }
  23.             angle+=0.001f;         //角度自增
  24.         }
  25.     }
  26.     else
  27.     {
  28.         for(i=0;i<times;i++)
  29.         {
  30.             cosx=arm_cos_f32(angle);//使用DSP优化的sin,cos函数
  31.             sinx=arm_sin_f32(angle);
  32.             result=sinx*sinx+cosx*cosx; //计算结果应该等于1  
  33.             result=fabsf(result-1.0f);    //对比与1的差值
  34.             if(result>DELTA)
  35.             {
  36.                 return 0XFF;//判断失败
  37.             }
  38.             angle+=0.001f;                //角度自增
  39.         }
  40.     }
  41.     return 0;//任务完成
  42. }
复制代码


函数中当输入参数mode为1时使用DSP库提供的arm_cos_f32和arm_sin_f32计算sin(x)² +cos(x)² = 1,输入参数angle为其实角度,计算一次增加0.001,输入的参数timers是要计算的次数,计算的次数越多越消耗时间,对硬件的资源要求就越高,mode为1时则使用st标准库提供的sin,cos函数,所以通过两者的比较得出那种方式比较节省时间。

主函数

  1. /**
  2.   * @brief  The application entry point.
  3.   * @retval int
  4.   */
  5. int main(void)
  6. {
  7.   /* USER CODE BEGIN 1 */
  8.   /* USER CODE END 1 */
  9.   /* MCU Configuration--------------------------------------------------------*/
  10.   /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  11.   HAL_Init();
  12.   /* USER CODE BEGIN Init */
  13.   /* USER CODE END Init */
  14.   /* Configure the system clock */
  15.   SystemClock_Config();
  16.   /* USER CODE BEGIN SysInit */
  17.   /* USER CODE END SysInit */
  18.   /* Initialize all configured peripherals */
  19.   MX_GPIO_Init();
  20.   MX_USART1_UART_Init();
  21.   MX_LPUART1_UART_Init();
  22.   /* USER CODE BEGIN 2 */
  23.   HAL_Init();
  24.   /* USER CODE END 2 */
  25.   /* Infinite loop */
  26.   /* USER CODE BEGIN WHILE */
  27.   while (1)
  28.   {
  29.     /* USER CODE END WHILE */
  30.     /* USER CODE BEGIN 3 */
  31.      //使用DSP优化
  32.     start_tim = HAL_GetTick();
  33.     status = sin_cos_test(PI/6,200000,1);
  34.     end_tim = HAL_GetTick();
  35.     if(end_tim > start_tim)
  36.     {
  37.         tim_cnt = end_tim - start_tim;
  38.     }
  39.     else
  40.     {
  41.         tim_cnt = 0xffffffff - start_tim + end_tim;
  42.     }
  43.     if(status==0)
  44.     {
  45.         printf("USER DSP-- %d ms\r\n",tim_cnt);    //显示运行时间  
  46.     }      
  47.     else
  48.     {
  49.         printf("USER DSP ERROR\n");    //显示当前运行情况   
  50.     }      
  51.     //不使用DSP优化        
  52.     start_tim = HAL_GetTick();
  53.     status = sin_cos_test(PI/6,200000,0);
  54.     end_tim = HAL_GetTick();
  55.     if(end_tim > start_tim)
  56.     {
  57.         tim_cnt = end_tim - start_tim;
  58.     }
  59.     else
  60.     {
  61.         tim_cnt = 0xffffffff - start_tim + end_tim;
  62.     }   

  63.     if(status==0)
  64.     {
  65.         printf("NOT USER DSP-- %d-ms\r\n",tim_cnt);    //显示运行时间  
  66.     }      
  67.     else
  68.     {
  69.         printf("NOT USER DSP ERROR\n");    //显示当前运行情况   
  70.     }   
  71.     HAL_GPIO_TogglePin(USER_LED_GPIO_Port,USER_LED_Pin);      
  72.     HAL_Delay(500);
复制代码


参数:angle : 起始角度 = π/6 ; times : 运算次数 = 10 000(1万);

结果如下图:使用DSP是8ms,没有使用DSP是12ms;12/8= 1.5倍。
微信图片_20200304161428.png
参数:angle : 起始角度 = π/6 ; times : 运算次数 = 100 000(10万);

结果如下图:使用DSP是86ms,没有使用DSP是129ms;129/86= 1.5倍。
微信图片_20200304161435.png

参数:angle : 起始角度 = π/6 ; times : 运算次数 = 200000(20万);

结果如下图:使用DSP是172ms,没有使用DSP是258ms;258/172= 1.5倍。
微信图片_20200304161441.png

总结:在单精度数学运算方面使用DSP加数的效果还是比较明显的,平均来说是没有说使用DSP的15倍。

收藏 评论1 发布时间:2020-3-4 16:31

举报

1个回答
goodgft 回答时间:2021-8-20 09:07:31
板子的原理图在哪里找的啊?

所属标签

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版