1. 程式人生 > 其它 >2021/7/18--stm32需要用到的c語言

2021/7/18--stm32需要用到的c語言

2021/7/18

stm32需要用到的c語言

(本來是13號寫的 最近太忙 忘記了)

1. ifdef條件編譯

條件編譯命令最常見的形式為:

#ifdef 識別符號
程式段1
#else
程式段2
#endif

它的作用是:當識別符號已經被定義過(一般是用#define命令定義),則對程式段1進行編譯,否則編譯程式段2。

2. extern變數宣告

C語言中extern可以置於變數或者函式前,以表示變數或者函式的定義在別的檔案中,提示編譯器遇到此變數和函式時在其他模組中尋找其定義。這裡面要注意,對於extern申明變數可以多次,但定義只有一次。在我們的程式碼中你會看到看到這樣的語句:

extern u16 USART_RX_STA;

這個語句是申明USART_RX_STA變數在其他檔案中已經定義了,在這裡要使用到。所以,你肯定可以找到在某個地方有變數定義的語句:

u16 USART_RX_STA;

下面通過一個例子說明一下使用方法。 在Main.c定義的全域性變數id,id的初始化都是在Main.c裡面進行的。 Main.c檔案

u8 id;//定義只允許一次

main()
{

id=1;
printf("d%",id);//id=1

test();
printf("d%",id);//id=2

}

但是我們希望在main.c的 changeId(void)函式中使用變數id,這個時候我們就需要在main.c裡面去申明變數id是外部定義的了,因為如果不申明,變數id的作用域是到不了main.c檔案中。看下面main.c中的程式碼:

extern u8 id;//申明變數id是在外部定義的,申明可以在很多個檔案中進行
void test(void)
{
id=2;
}

在main.c中申明變數id在外部定義,然後在main.c中就可以使用變數id了。

3.typedef類型別名

typedef用於為現有型別建立一個新的名字,或稱為類型別名,用來簡化變數的定義。typedef在MDK用得最多的就是定義結構體的類型別名和列舉型別了。

struct _GPIO
{
__IO uint32_t MODER;
__IO uint32_t OTYPER;
...
};
struct _GPIO GPIOA;//定義結構體變數GPIOA

但是這樣很繁瑣,MDK中有很多這樣的結構體變數需要定義。這裡可以為結體定義一個別名GPIO_TypeDef,這樣就可以在其他地方通過別名GPIO_TypeDef來定義結構體變量了。方法如下:

typedef struct
{
__IO uint32_t MODER;
__IO uint32_t OTYPER;

} GPIO_TypeDef;

Typedef為結構體定義一個別名GPIO_TypeDef,這樣我們可以通過GPIO_TypeDef來定義結構體變數:

GPIO_TypeDef _GPIOA,_GPIOB;

這裡的GPIO_TypeDef就跟struct _GPIO是等同的作用了。

4.結構體

宣告結構體型別:

Struct 結構體名{
成員列表;
}變數名列表;

例如:

Struct U_TYPE {
Int BaudRate
Int WordLength;
}usart1,usart2;

在結構體申明的時候可以定義變數,也可以申明之後定義,方法是:

Struct 結構體名字結構體變數列表;

例如:

struct U_TYPE usart1,usart2;

結構體成員變數的引用方法是:

結構體變數名字.成員名

比如要引用usart1的成員BaudRate,方法是:usart1.BaudRate; 結構體指標變數定義也是一樣的,跟其他變數沒有啥區別。 例如:struct U_TYPE *usart3;//定義結構體指標變數usart1; 結構體指標成員變數引用方法是通過“->”符號實現,比如要訪問usart3結構體指標指向的結構體的成員變數BaudRate,方法是:

Usart3->BaudRate;

在我們微控制器程式開發過程中,經常會遇到要初始化一個外設比如串列埠,它的初始化狀態是由幾個屬性來決定的,比如串列埠號,波特率,極性,以及模式等。對於這種情況,在沒有學習結構體的時候,我們一般的方法是:

void USART_Init(u8 usartx,u32 u32 BaudRate,u8 parity,u8 mode);

這種方式是有效的同時在一定場合是可取的。但是試想,如果有一天,我們希望往這個函式裡面再傳入一個引數,那麼勢必需要修改這個函式的定義,重新加入字長這個入口引數。於是定義被修改為:

void USART_Init (u8 usartx,u32 BaudRate, u8 parity,u8 mode,u8 wordlength );

結構體就是將多個變數組合為一個有機的整體。上面的函式,BaudRate,wordlength, Parity,mode,wordlength這些引數,他們對於串列埠而言,是一個有機整體,都是來設定串列埠引數的,所以可以將他們通過定義一個結構體來組合在一個。MDK中是這樣定義的:

typedef struct
{
uint32_t USART_BaudRate;
uint16_t USART_WordLength;
uint16_t USART_StopBits;
uint16_t USART_Parity;
uint16_t USART_Mode;
uint16_t USART_HardwareFlowControl;
} USART_InitTypeDef;

於是,在初始化串列埠的時候入口引數就可以是USART_InitTypeDef型別的變數或者指標變量了,MDK中是這樣做的:

void USART_Init(USART_TypeDef* USARTx, USART_InitTypeDef* USART_InitStruct);

這樣,任何時候,只需要修改結構體成員變數,往結構體中間加入新的成員變數,而不需要修改函式定義就可以達到修改入口引數同樣的目的了。這樣的好處是不用修改任何函式定義就可以達到增加變數的目的。