# (志航) [STM32]序列埠通訊、外部中斷、窗口看門狗(WWDG) ## 實驗九-序列埠通訊 | 實驗十-外部中斷 | 實驗十二-窗口看門狗(WWDG) ### 序列埠通訊 :::success USART(Universal Synchronous Asynchronous Receiver Transmitter,通用同步/異步收發器) 是嵌入式系統中兩種常見的通訊方式。 我們這邊使用的是Asynchronous(非同步模式):發送端和接收端需要事先協商好一個固定的波特率來同步通信。 ::: *** #### 硬體設置 ![螢幕擷取畫面 2024-10-14 154219](https://hackmd.io/_uploads/rJdasS5y1g.png) ![螢幕擷取畫面 2024-10-14 154057](https://hackmd.io/_uploads/rkk7hBqJye.png) ![S__241467397](https://hackmd.io/_uploads/rJUM6B9y1x.jpg) PIN腳的TX,RX與GND分別接到USB轉TTL的RXD、TXD、GND ___ #### 主要程式碼 ``` c= #include "string.h" uint8_t Rxbuf[3]; uint16_t L[4]= {LD4_Pin, LD3_Pin, LD5_Pin, LD6_Pin}; int main(void) { //啟動 UART DMA 接收 HAL_UART_Receive_DMA(&huart1, Rxbuf, sizeof(Rxbuf)); while (1) { if (strcmp((char *)Rxbuf, "FWD") == 0) // 接收到 'FWD',開啟正轉 { for (int i = 0; i < 4; i++) { HAL_GPIO_WritePin(GPIOD, L[i] , GPIO_PIN_SET); for (int j = 0; j < 4; j++) { if (i != j ) { HAL_GPIO_WritePin(GPIOD, L[j], GPIO_PIN_RESET); } } HAL_Delay(300); HAL_GPIO_WritePin(GPIOD, L[i] , GPIO_PIN_RESET); HAL_Delay(300 ); } } else if (strcmp((char *)Rxbuf, "REV") == 0) // // 接收到 'REV',開啟逆轉 { for (int i = 3; i >= 0; i--) { HAL_GPIO_WritePin(GPIOD, L[i] , GPIO_PIN_SET); for (int j = 0; j < 4; j++) { if (i != j ) { HAL_GPIO_WritePin(GPIOD, L[j], GPIO_PIN_RESET); } } HAL_Delay(300); HAL_GPIO_WritePin(GPIOD, L[i] , GPIO_PIN_RESET); HAL_Delay(300 ); } } } } void HAL_UART_RxCpltCallback(UART_HandleTypeDef *UartHandle) { if (UartHandle->Instance == USART1) { // 顯示接收到的字元 printf("Input: %s\r\n", Rxbuf); // 重新啟動 UART 接收,以便繼續接收下一筆資料 HAL_UART_Receive_DMA(&huart1, Rxbuf, sizeof(Rxbuf)); } } ``` #### 成果 {%youtube p0gpIsDbMKI%} --- ### 外部中斷 :::success 外部中斷(External Interrupt):通過外部硬件引腳觸發中斷。當指定的GPIO引腳發生邊沿變化,就會觸發中斷,MCU會暫停當前的任務,進入中斷服務程序 ::: ___ #### 硬體設置 ![螢幕擷取畫面 2024-10-14 161716](https://hackmd.io/_uploads/rJ3Vjv5JJg.png) ![螢幕擷取畫面 2024-10-18 140633](https://hackmd.io/_uploads/rJy42ukgkx.png) ![螢幕擷取畫面 2024-10-14 180421](https://hackmd.io/_uploads/SyCJpwqkJx.png) ___ #### 主要程式碼 打開stm32f4xx_it.c![螢幕擷取畫面 2024-10-14 174419](https://hackmd.io/_uploads/r1i_uD51Jg.png) :::success ==HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)== 此回調函數可從下列路徑查詢使用 ![螢幕擷取畫面 2024-10-14 174502](https://hackmd.io/_uploads/BkIWtv9kJe.png) ::: ``` c= void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin) { if (GPIO_Pin == PB3_Pin) // 確認是PB3引腳觸發的中斷 { if (HAL_GPIO_ReadPin(GPIOB, PB3_Pin) == GPIO_PIN_SET) // 如果PB3為高電平 { for (int i = 0; i < 4; i++) { HAL_GPIO_WritePin(GPIOB, LD10_Pin, GPIO_PIN_SET); HAL_Delay(200); HAL_GPIO_WritePin(GPIOB, LD10_Pin, GPIO_PIN_RESET); HAL_Delay(200); } } } } ``` main.c ``` c= int main(void) { uint16_t L[4]= {LD4_Pin, LD3_Pin, LD5_Pin, LD6_Pin}; while(1) { /* USER CODE END WHILE */ MX_USB_HOST_Process(); /* USER CODE BEGIN 3 */ for (int i = 0; i < 4; i++) { if(HAL_GPIO_ReadPin(GPIOD, SW1_Pin) == 1){ HAL_GPIO_WritePin(GPIOD, L[i], GPIO_PIN_SET); } for (int j = 0; j < 4; j++) { if (i != j && HAL_GPIO_ReadPin(GPIOD, SW1_Pin) == 1) { HAL_GPIO_WritePin(GPIOD, L[j], GPIO_PIN_RESET); } } HAL_Delay(200); HAL_GPIO_WritePin(GPIOD, L[i], GPIO_PIN_RESET); HAL_Delay(200); } } } ``` ___ #### 成果 {%youtube DyOgAX2GwpQ%} --- ### 窗口看門狗(WWDG) :::success 窗口看門狗定時器(WWDG)監控系統運行,必須在特定時間窗口內重置,否則將觸發復位。它提高系統穩定性,防止死循環或故障,廣泛應用於嵌入式系統和工業控制等領域。 ::: ___ #### 硬體設置 ![螢幕擷取畫面 2024-10-14 201033](https://hackmd.io/_uploads/HJA5oK91Je.png) ![螢幕擷取畫面 2024-10-14 204806](https://hackmd.io/_uploads/ByerXc9y1x.png) ![WWDG-TIME1](https://hackmd.io/_uploads/S18azGqykl.png) ![WWDG-TIME](https://hackmd.io/_uploads/r19MZItJ1g.png) :::success 127(0x7F):當 WWDG 開始工作時,計數器值通常被設置為 0x7F(127),這代表計數器的起始值。 63(0x3F):當計數器倒數到 0x3F(63)時,如果程序沒有在窗口期內(即計數器值介於窗口值和 0x3F 之間)重置計數器,系統將觸發重啟。 ::: 只有在Refresh allowed區間Refresh WWDG才不會系統重啟。 時間計算 #### 主要程式碼 ``` c= int main(void) { HAL_GPIO_TogglePin(GPIOD, LD3_Pin); while (1) { /* USER CODE END WHILE */ MX_USB_HOST_Process(); /* USER CODE BEGIN 3 */ //(1/36000000)*4096*2^3*(127-80) ~ 44 ms Disable reloadin //(1/36000000)*4096*2^3*(80-63+1 ) ~ 16 ms //(1/36000000)*4096*2^3*(127-63+1) ~ 59 ms 44~59 ms Refresh WWDG //HAL_Delay(40); // Disable reloading HAL_Delay(50); // Normal, safe //HAL_Delay(65); // timeout, system reset HAL_WWDG_Refresh(&hwwdg); HAL_GPIO_TogglePin(LD4_GPIO_Port, LD4_Pin); } } ``` EarlyWakeupCallback : WWDG早期喚醒中斷回調函數 ```c= void HAL_WWDG_EarlyWakeupCallback(WWDG_HandleTypeDef *hwwdg) { HAL_GPIO_TogglePin(LD6_GPIO_Port, LD6_Pin); } ``` ___ #### 成果 {%youtube vgjF_HG_FRA%} {%youtube b0LyNaG5tO8%} ___ ## **實驗進度** - [x] 6-跑馬燈實驗 - [x] 7-蜂鳴器實驗 - [x] 8-按鈕輸入實驗 - [x] 9-序列埠通訊實驗 - [x] 10-外部中斷實驗 - [x] 12-窗口門狗(WWDG)實驗 - [ ] 13-定時器中斷實驗 - [ ] 14-PWN輸出實驗 - [ ] 16-電容觸摸按鍵實驗 - [ ] 18-TFTLCD顯示實驗 - [ ] 19-USMART調試組件實驗 - [ ] 20-RTC即時時鐘實驗 - [ ] 23-ADC實驗 - [ ] 29-IIC實驗 - [ ] 30-SPI實驗 - [ ] 36-DHT11數位溫濕度感測器實驗