STM32F103 "Hello World" Part3

Purpose
本篇實際操作STM32CubeMX去生成initialization code
Development board在Part1介紹

預計demo功能為USART, GPIO, HSE
USART dump "Hello World",
GPIO toggle LED,
使用Oscillator -> PLL -> 72MHz, 為system clock

STM32CubeMX Version 4.25

Pin assignment
USART1 : RX(PA_10), TX(PA_9)
LED : PC_13
External Oscillator : OSC_IN(PD_0) & OSC_OUT(PD_1)
2-Wire Serial Debug : SWDIO(PA_13) & SWCLK(PA_14)

Step by step
Step 1. click New Project

Step 2. 選擇MCU型號, 可透過下方Filter Search挑選MCU, 或直接Part Number Search輸入型號, 找到後連點兩次進去主畫面

Step 3. 主畫面
在Pinout分頁中可設定開啟或關閉各項Peripherals, 右邊為Chip View, 檢查Pin使用情況

Step 4. 設定各Peripherals, 如下圖左
  • RCC config
選擇High Speed Clock (HSE)Crystal/Ceramic Resonator
  • SYS config
選擇DebugSerial Wire
  • USART1 config
選擇ModeAsynchronous
  • GPIO config
於Chip View選擇PC13GPIO Output

設定好後, 右邊Chip View顯示相對應的Pin assignment
被設定過的Peripherals與Pin會以不同顏色表示
於官方TRM (UM1718)有詳細定義, 下方列出常見define


Step 5. 切換至Clock Configuration可看到Clock Tree
使用外部8MHz Oscillator, 經倍頻到72MHz (SYS_CLK max.), 配置如下圖
以HSE為PLL Source -> PLLMul*9 -> System Clock Mux選擇PLLCLK

如設定出現錯誤, 框底以紅色警示

說明

Step 6. 切換至Configuration頁面, 可詳細設定Periphals

USART1
Baud rate = 115200bps
GPIO
使用自定義名稱(User Label), 於Pinout將顯示自定義接腳名稱

Step 7. Project Setting
Menu -> Project -> Setting
相關設定供參考, 依喜好設定
官方TRM 5.8章Project Settings window
  • Project頁面
設定專案名稱, 路徑與Toolchain

  • Code Generator頁面
選擇Copy only the necessary library files
只複製有需要的Library, 第一項會將Middleware Level的Library也一併放進Project, 容量過大

Step 8. Generate Code
Menu -> Project -> Generate Code
生成完Initialization code, 跳出一對話框, 如下圖

STM32CubeMX操作流程如上述, 接下來轉至Keil進行coding!


Step 9. Open Project
以Keil開啟後, project tree如下
main.c 位於./Application/User, 主要執行system clock configuration, HAL peripherals initialization, user code
stm32f1xx_it.c 為interrupt handler

在STM32CubeMX產生的專案裡, 可看到許多USER CODE BEGIN & END的註解, 請將code撰寫於BEGIN & END的範圍內, 避免re-generate code時造成竭盡心力撰寫的code遺失
  1. /* USER CODE BEGIN WHILE */
  2. while (1)
  3. {
  4.  
  5. /* USER CODE END WHILE */


Step 10. Development code

設計功能為間隔1sec 透過UART 發送"Hello World\r\n", 同時PC13 LED toggle

UART 發送可分為polling, interrupt, DMA, 這裡以polling 為範例
由於選擇的是USART1 - asynchronous mode, 以STM32F103C8T6 為例, PA9 PA10 為USART1 interface, 分別是UART_TX, UART_RX

上述設計功能以下列3個API完成

HAL_UART_Driver operation functions

HAL_GPIO_Driver operation functions

HAL_System_Driver operation functions

  • Transmit the string by using HAL_UART_Transmit
  1. int main(void)
  2. {
  3. /* USER CODE BEGIN 1 */
  4. char str[] = "Hello World\r\n";
  5. /* USER CODE END 1 */
  6.  
  7. /* MCU Configuration----------------------------------------------------------*/
  8.  
  9. /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  10. HAL_Init();
  11.  
  12. /* USER CODE BEGIN Init */
  13.  
  14. /* USER CODE END Init */
  15.  
  16. /* Configure the system clock */
  17. SystemClock_Config();
  18.  
  19. /* USER CODE BEGIN SysInit */
  20.  
  21. /* USER CODE END SysInit */
  22.  
  23. /* Initialize all configured peripherals */
  24. MX_GPIO_Init();
  25. MX_USART1_UART_Init();
  26. /* USER CODE BEGIN 2 */
  27.  
  28. /* USER CODE END 2 */
  29.  
  30. /* Infinite loop */
  31. /* USER CODE BEGIN WHILE */
  32. while (1)
  33. {
  34. if (HAL_UART_Transmit(&huart1, (uint8_t *)str, sizeof(str), 0xFFFF) != HAL_OK) {
  35. Error_Handler();
  36. }
  37. HAL_GPIO_Toggle(LED_BUILTIN_GPIO_Port, LED_BUILTIN_Pin);
  38. HAL_Delay(1000);
  39. /* USER CODE END WHILE */
  40.  
  41. /* USER CODE BEGIN 3 */
  42.  
  43. }
  44. /* USER CODE END 3 */
  45.  
  46. }

  • sprintf function增加靈活性, 可快速字串格式設定
  1. int main(void)
  2. {
  3. /* USER CODE BEGIN 1 */
  4. char str[100];
  5. uint32_t i;
  6. /* USER CODE END 1 */
  7.  
  8. /* MCU Configuration----------------------------------------------------------*/
  9.  
  10. /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  11. HAL_Init();
  12.  
  13. /* USER CODE BEGIN Init */
  14.  
  15. /* USER CODE END Init */
  16.  
  17. /* Configure the system clock */
  18. SystemClock_Config();
  19.  
  20. /* USER CODE BEGIN SysInit */
  21.  
  22. /* USER CODE END SysInit */
  23.  
  24. /* Initialize all configured peripherals */
  25. MX_GPIO_Init();
  26. MX_USART1_UART_Init();
  27. /* USER CODE BEGIN 2 */
  28.  
  29. /* USER CODE END 2 */
  30.  
  31. /* Infinite loop */
  32. /* USER CODE BEGIN WHILE */
  33. i = 0;
  34. while (1)
  35. {
  36. sprintf(str, "Hello World, CNT: %d\r\n", i++);
  37. if (HAL_UART_Transmit(&huart1, (uint8_t *)str, sizeof(str), 0xFFFF) != HAL_OK) {
  38. Error_Handler();
  39. }
  40. /* USER CODE END WHILE */
  41.  
  42. /* USER CODE BEGIN 3 */
  43. HAL_GPIO_TogglePin(LED_BUILTIN_GPIO_Port, LED_BUILTIN_Pin);
  44. HAL_Delay(1000);
  45. }
  46. /* USER CODE END 3 */
  47.  
  48. }

參考C:\Users\[User Name]\STM32Cube\Repository\STM32Cube_FW_F1_V1.6.1\Projects\STM32F103RB-Nucleo\Examples\UART\UART_Printf 範例

USER CODE BEGIN PV & USER CODE END PV貼以下code
  1. /* USER CODE BEGIN PV */
  2. /* Private variables ---------------------------------------------------------*/
  3.  
  4. #ifdef __GNUC__
  5. /* With GCC, small printf (option LD Linker->Libraries->Small printf
  6. set to 'Yes') calls __io_putchar() */
  7. #define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
  8. #else
  9. #define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
  10. #endif /* __GNUC__ */
  11. PUTCHAR_PROTOTYPE
  12. {
  13. /* Place your implementation of fputc here */
  14. /* e.g. write a character to the USART1 and Loop until the end of transmission */
  15. HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, 0xFFFF);
  16.  
  17. return ch;
  18. }
  19.  
  20. /* USER CODE END PV */

於while loop 中直接call printf 即可
  1. /* Infinite loop */
  2. /* USER CODE BEGIN WHILE */
  3. i = 0;
  4. while (1)
  5. {
  6. printf("Hello World, CNT: %d\r\n", i++);
  7. /* USER CODE END WHILE */
  8.  
  9. /* USER CODE BEGIN 3 */
  10. HAL_GPIO_TogglePin(LED_BUILTIN_GPIO_Port, LED_BUILTIN_Pin);
  11. HAL_Delay(1000);
  12. }
  13. /* USER CODE END 3 */


Resources
UM1718
http://www.st.com/resource/en/user_manual/dm00104712.pdf

STM32CubeMX介绍、下载与安装
https://blog.csdn.net/ybhuangfugui/article/details/52225736

STM32CubeMX新建工程+基本IO配置过程
https://blog.csdn.net/ybhuangfugui/article/details/52281260

STM32CubeMX系列教程
http://www.waveshare.net/study/portal.php?mod=list&catid=38

留言

這個網誌中的熱門文章

[VB6]使用File Dialog選擇檔案

[VB6]MSFlexGrid使用記錄

[VBA]如何藉由使用 Excel 中的 Visual Basic 程序選取儲存格/範圍