STM32—常用的幾種偽指令宏
2021-09-03 來源:eefocus
說到偽指令宏一般就會聯想到指令、宏指令和偽指令。
先借用別人的話簡單介紹一下三者之間的關聯和區別(看到一個博主寫的很不錯):
我們使用的各種指令,都是寫給“編譯軟件”看的。
要由“編譯軟件”翻譯成計算機可以識別的機器語言,即機器碼。
通俗地講:
就好像召開新聞發布會,主持人用中文講話,由一個翻譯,現場翻譯成英文,講給外國記者聽。
主持人說的中文,大部分都是要翻譯成英文的;少數幾句,是說給翻譯聽的,告訴他如何翻譯。
我們寫的指令,由“編譯軟件”翻譯成機器碼的,稱為指令語句;
有一些是寫給“編譯軟件”看的,不翻譯成機器碼,這樣的就是“偽指令”。
一條條計算機的指令,一般來說,功能都是極為簡單的。我們可以把幾條、幾十條指令,編寫成一個“宏指令”,來完成一個比較復雜的任務。
在這樣“一批指令”的前面,要用一條“偽指令”來命名這個“宏指令”;
在后面,要用一條“偽指令”說明結尾。
以后,這個“宏指令”,就可以當成 正式指令 來使用了。
2.偽指令宏分為簡單宏、參數宏、條件宏、預定義宏和宏釋放
簡單宏:
定義格式: #define 宏標識符 宏體
是最常見的宏,在宏體長的時候使用續行符“”連接宏體,如示
#define IS_GPIO_ALL_PERIPH(PERIPH) (((PERIPH) == GPIOA) ||
((PERIPH) == GPIOB) ||
((PERIPH) == GPIOC) ||
((PERIPH) == GPIOD) ||
((PERIPH) == GPIOE) ||
((PERIPH) == GPIOF) ||
((PERIPH) == GPIOG))
宏的用法:在源文件中,用預處理器偽指令定義過宏標識符后,就可以用宏標識符編寫程序。當源文件被預處理器處理時,每遇到該宏標識符,預處理器便在宏的所在處將宏擴展為宏體。
參數宏:
定義格式:#define 宏標識符(形式參數表) 宏體
形式參數表為逗號分割的形式參數,宏體可以用“”進行續行,使用參數宏時形式參數被換為相同個數的實參數表。(類似于函數的調用,實際上許多庫函數時用參數宏編寫的。二者區別是參數宏的形式參數表中沒有類型說明符)
舉例如示
#define IS_GET_GPIO_PIN(PIN) (((PIN) == GPIO_Pin_0) ||
((PIN) == GPIO_Pin_1) ||
((PIN) == GPIO_Pin_2) ||
((PIN) == GPIO_Pin_3) ||
((PIN) == GPIO_Pin_4) ||
((PIN) == GPIO_Pin_5) ||
((PIN) == GPIO_Pin_6) ||
((PIN) == GPIO_Pin_7) ||
((PIN) == GPIO_Pin_8) ||
((PIN) == GPIO_Pin_9) ||
((PIN) == GPIO_Pin_10) ||
((PIN) == GPIO_Pin_11) ||
((PIN) == GPIO_Pin_12) ||
((PIN) == GPIO_Pin_13) ||
((PIN) == GPIO_Pin_14) ||
((PIN) == GPIO_Pin_15))
預處理器在處理參數宏時使用倆次宏展開。第一次展開宏體,第二次對展開的宏體用實參數替換形式參數。
宏釋放:
定義格式: #undef 宏標識符
用于釋放原定義的宏標識符,釋放后的宏標識符可以再次用于定義其他宏體。
條件宏定義:
條件宏定義主要是用來測試是否定義過某宏標識符,以及決定如何處理宏標識符,具體格式有倆種:
\測試存在情況
#ifdef 宏標識符
#undef 宏標識符
#define 宏標識符 宏體
#else
#define 宏標識符 宏體
#endif
\測試不存在情況
#ifndef 宏標識符
#define 宏標識符 宏體
#else
#undef 宏標識符
#define 宏標識符 宏體
#endif
常用于頭文件中。
預定義宏:
預定義宏基本莫得存在感,其特征就是標識符前后都有雙下劃線。如
__DATE__ __TIME__
__FILE__ __LINE__
__STDC__
這些預定義宏的宏體分別是當時的日期、時間、所在文件名、所在文件的行數。
這些宏在后續的學習階段會頻繁出現,在此總結一下。