# STM32 & C/C++ 常用程式語法 ## C/C++ ### 基本符號 - {} 大括號 - () 小括號 - = 等於 - ! 驚嘆號 - & and - ; 分號 ### 變數 - 用來儲存資料的容器 - 有分不同型態 - int 整數 ex. 1, 2, 3... - float/double 浮點數(小數) ex. 1.2, 1.3, 1.4... ### if/else - 如果... 就... 不然就... - 布林運算 - && - 且(兩個都是對的才成立) - || - 或(只要有一個是對的就成立) - 條件判斷 - == - 等於 - != - 不等於 ### 迴圈 - 不斷執行 - while - while(條件){執行內容} - for - for(變數初始化;直到什麼狀況;變數怎麼變){執行內容} ## STM32 基礎程式架構 - 東西放在 Begin - End 中間!! - 主要程式放在 main 裡 - 大約在 70 行上下 - 要不斷執行的放在 **main** 裡的 while 中 (約在105行上下) - 中斷那些東西可以放在 USER CODE 4 中 - 約在 360 行上下 ## GPIO ::: warning 放在 MX_GPIO_Init(); 後面 ::: ### 輸出 高/低 電位 - 三個參數記得改! - 英文編號, 數字編號, 高 or 低 ```Cpp= HAL_GPIO_WritePin(GPIOx, GPIO_PIN_x, GPIO_PIN_SET/GPIO_PIN_RESET); ``` 輸出 上次相反 電位 ```Cpp= HAL_GPIO_TogglePin(GPIOx, GPIO_PIN_x); ``` ### 接收輸入電位 - 回傳 高(1) or 低(0) ```Cpp= HAL_GPIO_ReadPin(GPIOx, GPIO_PIN_x); ``` ::: warning 放在 MX_GPIO_Init(); 後面 ::: ## EXTI 外部中斷 - 放在 USER CODE 4 中(約在 360 行上下) ```Cpp= void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin){ if(GPIO_Pin == GPIO_PIN_x){ // 執行內容 } } ``` ## Timer 中斷 - 頻率公式 $$ f_{out} = \frac{f_{clk}}{(PSC+1)(ARR+1)} $$ $f_{out}$: PWM 訊號頻率 $f_{clk}$: STM32 晶片時脈信號頻率, 170*1000000 Hz for G431RB - 放在 USER CODE 2 中(約在 96 行上下) ```Cpp= /* USER CODE BEGIN 2 */ HAL_TIM_Base_Start_IT(&htimx); /* USER CODE END 2 */ ``` - 放在 USER CODE 4 中(約在 360 行上下) ```Cpp= /* USER CODE BEGIN 4 */ void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim){ if (htim -> Instance == TIMx){ // 執行內容 } } /* USER CODE END 4 */ ``` ## 輸出 PWM 訊號 - 頻率公式 $$ f_{out} = \frac{f_{clk}}{(PSC+1)(ARR+1)} $$ $f_{out}$: PWM 訊號頻率 $f_{clk}$: STM32 晶片時脈信號頻率, 170*1000000 Hz for G431RB - 工作週期 $$ Duty\ cycle = \frac{Pulse}{ARR+1} \times 100\% $$ - 放在 USER CODE 2 中(約在 96 行上下) ```Cpp= /* USER CODE BEGIN 2 */ HAL_TIM_PWM_Start(&htimx, TIM_CHANNEL_x); /* USER CODE END 2 */ ``` - 要改變 Pulse ```Cpp= __HAL_TIM_SET_COMPARE(&htimx, TIM_CHANNEL_x, Pulse值); ``` - 要改變 ARR ```Cpp= __HAL_TIM_SET_AUTORELOAD(&htimx, ARR值); ``` ## Encoder 編碼器讀取 - 放在 USER CODE 2 中(約在 96 行上下) ```Cpp= /* USER CODE BEGIN 2 */ // 有用到的 Channel 都要填 HAL_TIM_Encoder_Start(&htimx, TIM_CHANNEL_a); HAL_TIM_Encoder_Start(&htimx, TIM_CHANNEL_b); /* USER CODE END 2 */ ``` - 讀取 Encoder 值 ```Cpp= __HAL_TIM_GetCounter(&htimx); ``` - 賦予 Encoder 值 ```Cpp= __HAL_TIM_SetCounter(&htimx, 賦予的值); ``` ## NUCLEO-G431RB 腳位圖 ![image](https://hackmd.io/_uploads/r1AeSn850.png)