您當前的位置:首頁 > 體育

STM32G4板卡試用分享

作者:由 AI電堂 發表于 體育時間:2019-12-24

開發環境:Keil uVision5(版本V5。28a),STM32CubeMX(版本V5。4)

執行平臺:Window10企業版 64位系統

資源篇

外觀還是一如既往的靚,簡潔美觀。板子搭載的是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資源介紹:

STM32G4板卡試用分享

STM32G474開發板實物圖:

STM32G4板卡試用分享

▲ 開發板實物圖

開發板分為上下兩部分,上半部分為ST-LINK-V3模擬器,可以給開發板進行除錯和程式下載。下半部分是G474的最小系統板:全IO引出,相容流行的Arduino擴充套件口如下圖所示。值得一提的是:上半部分的ST-LINK是可以透過斷開跳帽之後可以單獨作為偵錯程式使用。

STM32G4板卡試用分享

實戰篇

測試內容:

IO測試

虛擬串列埠VCP測試

FPU測試

DSP測試

1. LED和GPIO測試1

(1) 原理:短按一下按鍵,LED點亮,再短按一下按鍵LED熄滅。(2) 步驟:使用CubeCubeMx生成工程。

STM32G4板卡試用分享

▲ 引腳配置

時鐘配置:外接24M晶振,高達170M主頻

STM32G4板卡試用分享

生成工程,韌體包版本V1。1。0。

STM32G4板卡試用分享

程式碼:

STM32G4板卡試用分享

結果:短按一下按鍵,LED點亮,再短按一下按鍵LED熄滅。

結論:使用MX配置簡單快速。

2.

VCP虛擬串列埠測試1

(1) 原理:

MCU與stlik連線

STM32G4板卡試用分享

虛擬串列埠連線MCU的LPUART1

STM32G4板卡試用分享

(2) 配置工程:

STM32G4板卡試用分享

相關程式碼:

STM32G4板卡試用分享

STM32G4板卡試用分享

(3)結果:如下所示,按一次按鍵就列印一個“OK”,LED一亮滅交替。

STM32G4板卡試用分享

結論:這個功能在我們除錯的時候十分方便,節省了很多的資源和時間。

3.FPU效能測試1

原理:

FPU浮點運算單元,如果CPU上沒有FPU進行浮點運算的話必須按照IEEE標準進行運算十分的耗時,相較之下具有FPU的處理器在計算浮點運算是非常快的,G474Nucleo板載FPU運算加速器,運算效能非常出色,我們可以透過簡單的測試來測一下板子的FPU的效能,可以透過計算使用FPU時單精度的乘除法使用的時間和沒有使用FPU時消耗的時間進行比較來得出結論,其中時間的計數我們使用的是systick定時器。

步驟:

首先我們要學會開啟硬體FPU,我們要設定 CPACR暫存器,其中在SystemInit函式中已經寫好怎麼配置,如下圖:

STM32G4板卡試用分享

我們只需要新增宏定義__FPU_PRESENT =1 ,_FPU_USED=1就可以了,而預設已經定義了__FPU_PRESENT =1,我們還需要新增_FPU_USED=1,在target 的Code Generation 選single Precision 就行了,如下圖。

STM32G4板卡試用分享

相關程式碼如下:雙精度和單精度計算函式

/**

* @name DoubleD

* @brief 雙精度乘除法。

* @param angle:起始值,times:計算次數,

*mod:1除法0乘法

*/

void DoubleD(double angle,uint32_t times,uint8_t mode)

{

uint32_t i;

double result;

if(mode)//除法

{

for(i=0;i

{

result = angle/PI;

angle += 0。00001f;

}

}

else//乘法

{

for(i=0;i

{

result = angle*PI;

angle += 0。00001f;

}

}

}

/**

* @name FloatXFloat

* @brief 單精度乘除法。

* @param angle:起始值,times:計算次數,*mod:1除法0乘法

*/

void FloatXFloat(float angle,uint32_t times,uint8_t mode)

{

uint32_t i;

float result;

if(mode)//除法

{

for(i=0;i

{

result = angle/PI;

angle += 0。00001f;

}

}

else//乘法

{

for(i=0;i

{

result = angle*PI;

angle += 0。00001f;

}

}

}

主函式

int main(void)

{

/* USER CODE BEGIN 1 */

/* 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_USART1_UART_Init();

MX_LPUART1_UART_Init();

/* USER CODE BEGIN 2 */

HAL_Init();

/* USER CODE END 2 */

/* Infinite loop */

/* USER CODE BEGIN WHILE */

while (1)

{

/* USER CODE END WHILE */

/* USER CODE BEGIN 3 */

printf(“————————-NOT USER FPU————————————\n”);

//——————————-測試單精度乘法————————————————————

start_tim = HAL_GetTick();

//乘法

FloatXFloat(PI/6,TIMES,0);

end_tim = HAL_GetTick();

if(end_tim > start_tim)

{

tim_cnt = end_tim - start_tim;

}

else

{

tim_cnt = 0xffffffff - start_tim + end_tim;

}

printf(“單精度乘法—— %d ms\r\n”,tim_cnt); //顯示執行時間

//————————-測試單精度除法——————————————————————-

start_tim = HAL_GetTick();

//除法

FloatXFloat(PI/6,TIMES,1);

end_tim = HAL_GetTick();

if(end_tim > start_tim)

{

tim_cnt = end_tim - start_tim;

}

else

{

tim_cnt = 0xffffffff - start_tim + end_tim;

}

printf(“單精度除法—— %d ms\r\n”,tim_cnt); //顯示執行時間

//————————-測試雙精度乘法——————————————————————-

start_tim = HAL_GetTick();

//乘法

DoubleD(PI/6,TIMES,1);

end_tim = HAL_GetTick();

if(end_tim > start_tim)

{

tim_cnt = end_tim - start_tim;

}

else

{

tim_cnt = 0xffffffff - start_tim + end_tim;

}

printf(“雙精度乘法—— %d ms\r\n”,tim_cnt); //顯示執行時間

//————————-測試雙精度除法——————————————————————-

start_tim = HAL_GetTick();

//除法

DoubleD(PI/6,TIMES,1);

end_tim = HAL_GetTick();

if(end_tim > start_tim)

{

tim_cnt = end_tim - start_tim;

}

else

{

tim_cnt = 0xffffffff - start_tim + end_tim;

}

printf(“雙精度除法—— %d ms\r\n”,tim_cnt); //顯示執行時間

HAL_GPIO_TogglePin(USER_LED_GPIO_Port,USER_LED_Pin);

HAL_Delay(500);

}

/* USER CODE END 3 */

}

測試結果:

條件:輸入引數angle:起始值 = π/6,times:計算次數 = 20000(兩萬),mod:乘除法時。

(1)沒有開啟FPU

STM32G4板卡試用分享

(2)開啟FPU

STM32G4板卡試用分享

資料比較

STM32G4板卡試用分享

STM32G4板卡試用分享

得出結論

開啟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。

STM32G4板卡試用分享

STM32G4板卡試用分享

開啟FPU,在target 的Code Generation 選singlePrecision。

STM32G4板卡試用分享

減價宏定義ARM_MATH_CM4。

STM32G4板卡試用分享

測試主要程式碼:

運算函式:

//sin cos測試

//angle:起始角度

//times:運算次數

//mode:0,不使用DSP庫;1,使用DSP庫

//返回值:0,成功;0XFF,出錯

uint8_t sin_cos_test(float angle,uint32_t times,uint8_t mode)

{

float sinx,cosx;

float result;

uint32_t i=0;

if(mode==0)

{

for(i=0;i

{

cosx=cosf(angle); //不使用DSP最佳化的sin,cos函式

sinx=sinf(angle);

result=sinx*sinx+cosx*cosx;//計算結果應該等於1

result=fabsf(result-1。0f);//對比與1的差值

if(result>DELTA)

{

return 0XFF; //判斷失敗

}

angle+=0。001f; //角度自增

}

}

else

{

for(i=0;i

{

cosx=arm_cos_f32(angle);//使用DSP最佳化的sin,cos函式

sinx=arm_sin_f32(angle);

result=sinx*sinx+cosx*cosx; //計算結果應該等於1

result=fabsf(result-1。0f); //對比與1的差值

if(result>DELTA)

{

return 0XFF;//判斷失敗

}

angle+=0。001f; //角度自增

}

}

return 0;//任務完成

}

函式中當輸入引數mode為1時使用DSP庫提供的arm_cos_f32和arm_sin_f32計算sin(x)² +cos(x)² = 1,輸入引數angle為其實角度,計算一次增加0。001,輸入的引數timers是要計算的次數,計算的次數越多越消耗時間,對硬體的資源要求就越高,mode為1時則使用st標準庫提供的sin,cos函式,所以透過兩者的比較得出那種方式比較節省時間。

主函式

/**

* @brief The application entry point。

* @retval int

*/

int main(void)

{

/* USER CODE BEGIN 1 */

/* 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_USART1_UART_Init();

MX_LPUART1_UART_Init();

/* USER CODE BEGIN 2 */

HAL_Init();

/* USER CODE END 2 */

/* Infinite loop */

/* USER CODE BEGIN WHILE */

while (1)

{

/* USER CODE END WHILE */

/* USER CODE BEGIN 3 */

//使用DSP最佳化

start_tim = HAL_GetTick();

status = sin_cos_test(PI/6,200000,1);

end_tim = HAL_GetTick();

if(end_tim > start_tim)

{

tim_cnt = end_tim - start_tim;

}

else

{

tim_cnt = 0xffffffff - start_tim + end_tim;

}

if(status==0)

{

printf(“USER DSP—— %d ms\r\n”,tim_cnt); //顯示執行時間

}

else

{

printf(“USER DSP ERROR\n”); //顯示當前執行情況

}

//不使用DSP最佳化

start_tim = HAL_GetTick();

status = sin_cos_test(PI/6,200000,0);

end_tim = HAL_GetTick();

if(end_tim > start_tim)

{

tim_cnt = end_tim - start_tim;

}

else

{

tim_cnt = 0xffffffff - start_tim + end_tim;

}

if(status==0)

{

printf(“NOT USER DSP—— %d-ms\r\n”,tim_cnt); //顯示執行時間

}

else

{

printf(“NOT USER DSP ERROR\n”); //顯示當前執行情況

}

HAL_GPIO_TogglePin(USER_LED_GPIO_Port,USER_LED_Pin);

HAL_Delay(500);

引數:angle : 起始角度 = π/6 ; times : 運算次數 = 10 000(1萬);

結果如下圖:使用DSP是8ms,沒有使用DSP是12ms;12/8= 1。5倍。

STM32G4板卡試用分享

引數:angle : 起始角度 = π/6 ; times : 運算次數 = 100 000(10萬);

結果如下圖:使用DSP是86ms,沒有使用DSP是129ms;129/86= 1。5倍。

STM32G4板卡試用分享

引數:angle : 起始角度 = π/6 ; times : 運算次數 = 200000(20萬);

結果如下圖:使用DSP是172ms,沒有使用DSP是258ms;258/172= 1。5倍。

STM32G4板卡試用分享

總結:在單精度數學運算方面使用DSP加數的效果還是比較明顯的,平均來說是沒有說使用DSP的15倍。

STM32G4板卡試用分享

點選連結觀看更多相關課程

標簽: Tim  user  DSP  ANGLE  FPU