這段代碼中do while的作用:
宏定義中的語句塊:do { ... } while (0)?允許你在宏定義中創建一個語句塊,從而可以包含多條語句。這在宏定義中特別有用,因為宏只是簡單的文本替換,不像函數那樣有作用域和返回類型。因此,如果你想在宏中執行多個操作,你需要將這些操作放在一個語句塊中。
保證邏輯在一行內完成:使用?do { ... } while (0)?可以確保宏定義中的所有邏輯都在一行內完成。這有助于避免在宏展開時可能出現的語法錯誤,特別是當宏在復雜的表達式中被調用時。
免編譯器警告或錯誤:如果宏定義中有多條語句,并且沒有使用?do { ... } while (0),編譯器可能會產生關于未使用的循環變量的警告或錯誤。使用?do { ... } while (0)?可以避免這些警告或錯誤,因為循環條件是常量值“零”,所以循環實際上不會執行。
?HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_5);對引腳電平進行翻轉
對兩個引腳初始化,推完輸出,默認為高電平。
C中的三元運算符(X ? A : B):如果x為真(非0),那么宏BEEP(x)將調用HAL_GPIO_WritePin函數來設置(或打開)蜂鳴器;如果x為假(0),那么宏BEEP(x)將調用HAL_GPIO_WritePin函數來重置(或關閉)蜂鳴器。兩個函數之間是冒號。
引腳的輸入定義默認為高或低電平的作用:
防止輸入端懸空:當輸入端處于懸空狀態時,即沒有外部信號連接,其電平狀態容易受到外界干擾而改變。上拉和下拉電阻可以將輸入端的電平狀態固定在一個確定的狀態上,防止其受到外部信號的干擾。
確定電平狀態:上拉電阻將不確定的信號通過一個電阻提升為高電平,而下拉電阻將不確定的信號通過一個電阻降低為低電平。這樣,無論輸入端是否接收到外部信號,都可以保證其電平狀態是確定的,從而避免數字信號的傳輸和控制受到干擾。
按鍵掃描程序加入delay_ms()去抖動,KEY的值由 HAL_GPIO_ReadPin()所得。
按鍵掃描+switch判斷。
一個外部中斷的設置(重點看看gpio_init_struct.Mode = GPIO_MODE_IT_FALLING; ):
注意看下圖的最后一行,這里的EXTI4_IRQn與PE4是對應的。
中斷回調函數:
注意看這三個函數之間的關系,弄明白HAL外部中斷回調函數的使用方法。
外部中斷可以繞開主循環,避免影響。
usart的使用:
HAL_UART_Receive_IT開啟UART接受中斷。
串口的底層初始化:
#define USART_EN_RX ?1 ????這種條件限定值得學習。
在串口中斷里處理接收到的數據;
????
單片機中的看門狗(Watchdog Timer,WDT)是一個重要的安全保護機制。它由一個獨立的時鐘和一個計數器組成,用于檢測系統是否運行正常。當計數器達到一個預先設定的值時,看門狗會向系統發出警報,以此來檢測系統是否運行正常。如果系統運行正常,單片機會在計數器達到警報值之前給看門狗發出“清除”信號,以此來重置計數器,繼續監測系統的運行狀態。然而,如果系統運行異常,例如出現程序跑飛、受到干擾或陷入死循環等情況,單片機不會給看門狗發出“清除”信號。這種情況下,看門狗計數器會持續增加,當達到警報值后,看門狗會向系統發出警報,使單片機強制復位,從而使程序重新開始執行。這樣,看門狗能夠確保系統在異常情況下能夠安全停止運行,避免造成重大損失。看門狗定時器的溢出時間越短,其靈敏度越高,系統跑飛后復位的時間也就越短,從而提高了系統的安全性。然而,這也意味著需要更頻繁地給看門狗“喂食”,即在程序中定期給看門狗設置值,以防止其溢出。
看門狗初始化和喂狗:
需要再主函數中每一秒執行iwdg_feed(); 狗才不會瘋強制系統復位。
窗口看門狗與普通看門狗的區別:
普通看門狗通常只設定一個時間閾值,系統需要在這個時間閾值內“喂狗”以重置看門狗。如果系統因故障或死鎖無法在規定時間內“喂狗”,看門狗會觸發復位操作,強制重啟系統。這種看門狗方式相對簡單,但缺乏靈活性,因為它只有一個固定的時間閾值。
窗口看門狗則設定了兩個時間閾值:窗口上限和窗口下限。在這個窗口時間內,系統需要至少“喂狗”一次以重置看門狗。如果系統在這個窗口時間內沒有“喂狗”,或者“喂狗”的時間超出窗口上限或下限,看門狗會觸發復位操作。這種方式提供了更大的靈活性,因為它允許系統在一定時間范圍內“喂狗”,而不是固定在一個時間點。
wwdg_init(0X7F, 0X5F, WWDG_PRESCALER_8);/* 計數器值為7f,窗口寄存器為5f,分頻數為8 */
窗口看門狗可以設置中斷處理函數,在窗口看門狗需要喂狗的時候調用。