国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

STM32 基礎(chǔ)知識(shí)入門 (C語言基礎(chǔ)鞏固)

這篇具有很好參考價(jià)值的文章主要介紹了STM32 基礎(chǔ)知識(shí)入門 (C語言基礎(chǔ)鞏固)。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問。

1、在不改變其他位的值的狀況下,對(duì)某幾個(gè)位進(jìn)行設(shè)值

這個(gè)場(chǎng)景在單片機(jī)開發(fā)中經(jīng)常使用,方法就是先對(duì)需要設(shè)置的位用&操作符進(jìn)行清零操作, 然后用|操作符設(shè)值。

比如我要改變 GPIOA 的 CRL 寄存器 bit6(第 6 位)的值為 1,可以先對(duì)寄 存器的值進(jìn)行&清零操作:

GPIOA->CRL &= 0XFFFFFFBF; /* 將第 bit6 清 0 */ 

?然后再與需要設(shè)置的值進(jìn)行|或運(yùn)算:

GPIOA->CRL |= 0X00000040; /* 設(shè)置 bit6 的值為 1,不改變其他位的值 */ 

?2、移位操作提高代碼的可讀性

?移位操作在單片機(jī)開發(fā)中非常重要,下面是 delay_init 函數(shù)的一行代碼:

SysTick->CTRL |= 1 << 1;

?這個(gè)操作就是將 CTRL 寄存器的第 1 位(從 0 開始算起)設(shè)置為 1,為什么要通過左移而 不是直接設(shè)置一個(gè)固定的值呢?其實(shí)這是為了提高代碼的可讀性以及可重用性。這行代碼可以 很直觀明了的知道,是將第 1 位設(shè)置為 1。如果寫成:

SysTick->CTRL |= 0X0002;

?這個(gè)雖然也能實(shí)現(xiàn)同樣的效果,但是可讀性稍差,而且修改也比較麻煩。

3、~按位取反操作使用技巧 ?

按位取反在設(shè)置寄存器的時(shí)候經(jīng)常被使用,常用于清除某一個(gè) /某幾個(gè)位。下面是 delay_us

函數(shù)的一行代碼:

SysTick->CTRL &= ~(1 << 0) ; /* 關(guān)閉 SYSTICK */ 

該代碼可以解讀為 僅設(shè)置 CTRL 寄存器的第 0 位(最低位)為 0,其他位的值保持不變。 同樣我們也不使用按位取反,將代碼寫成:

SysTick->CTRL &= 0XFFFFFFFE; /* 關(guān)閉 SYSTICK */ 

?可見前者的可讀性,及可維護(hù)性都要比后者好很多。

4、^按位異或操作使用技巧?

該功能非常適合用于控制某個(gè)位翻轉(zhuǎn),常見的應(yīng)用場(chǎng)景就是控制 LED 閃爍,如:

GPIOB->ODR ^= 1 << 5;

執(zhí)行一次該代碼,就會(huì)使 PB5 的輸出狀態(tài)翻轉(zhuǎn)一次,如果我們的 LED 接在 PB5 上,就可 以看到 LED 閃爍了。?

5、ifdef 條件編譯

單片機(jī)程序開發(fā)過程中,經(jīng)常會(huì)遇到一種情況,當(dāng)滿足某條件時(shí)對(duì)一組語句進(jìn)行編譯,而 當(dāng)條件不滿足時(shí)則編譯另一組語句。條件編譯命令最常見的形式為:

#ifdef 標(biāo)識(shí)符 

    程序段 1 

#else 

    程序段 2 

#endif

它的作用是:當(dāng)標(biāo)識(shí)符已經(jīng)被定義過(一般是用#define 命令定義),則對(duì)程序段 1 進(jìn)行編譯, 否則編譯程序段 2。 其中#else 部分也可以沒有,即:

#ifdef 

     程序段 1 

#endif 

?條件編譯在 MDK 里面是用得很多,在 stm32f10x.h 這個(gè)頭文件中經(jīng)常會(huì)看到這樣的語句:

#if !defined (STM32F1)     //在這里也可以換成是#ifndef   
#define STM32F1 
#endif 

?如果沒有定義 STM32F1 這個(gè)宏,則定義 STM32F1 宏。條件編譯也是 c 語言的基礎(chǔ)知識(shí), 這里也就點(diǎn)到為止吧。

6、extern 外部申明

C 語言中 extern 可以置于變量或者函數(shù)前,以表示變量或者函數(shù)的定義在別的文件中,提示編 譯器遇到此變量和函數(shù)時(shí)在其他模塊中尋找其定義。這里面要注意,對(duì)于 extern 申明變量可以多 次,但定義只有一次。在我們的代碼中你會(huì)看到這樣的語句: ?

extern uint16_t g_usart_rx_sta; 

?這個(gè)語句是申明 g_usart_rx_sta 變量在其他文件中已經(jīng)定義了,在這里要使用到。所以,你 肯定可以找到在某個(gè)地方有變量定義的語句:

uint16_t g_usart_rx_sta; 

?在這里大家可以覺得有點(diǎn)繞,但是其思想就是:
例如我在filec文件當(dāng)中定義了uint16_t g_usart_rx_sta;

然后這個(gè)時(shí)候我要在filec文件當(dāng)中使用這個(gè)變量,就是說我想直接從filec文件當(dāng)中將uint16_t g_usart_rx_sta取過來,那么我可以在filec文件當(dāng)中在變量前面加上

extern uint16_t g_usart_rx_sta; 

7、typedef 類型別名

typedef 用于為現(xiàn)有類型創(chuàng)建一個(gè)新的名字,或稱為類型別名,用來簡化變量的定義。typedef

在 MDK 用得最多的就是定義結(jié)構(gòu)體的類型別名和枚舉類型了。

struct _GPIO 

{ 
     __IO uint32_t CRL; 
     __IO uint32_t CRH; 
     … 
    
}; 

?定義了一個(gè)結(jié)構(gòu)體 GPIO,這樣我們定義結(jié)構(gòu)體變量的方式為:

struct _GPIO gpiox; /* 定義結(jié)構(gòu)體變量 gpiox */ 

?但是這樣很繁瑣,MDK 中有很多這樣的結(jié)構(gòu)體變量需要定義。這里我們可以為結(jié)體定義一 個(gè)別名 GPIO_TypeDef,這樣我們就可以在其他地方通過別名 GPIO_TypeDef 來定義結(jié)構(gòu)體變 量了,方法如下:

typedef struct 

{ 
     __IO uint32_t CRL; 
     __IO uint32_t CRH; 
     … 

} GPIO_TypeDef; 

Typedef 為結(jié)構(gòu)體定義一個(gè)別名 GPIO_TypeDef,這樣我們可以通過 GPIO_TypeDef 來定義 結(jié)構(gòu)體變量:

GPIO_TypeDef gpiox;

這里的 GPIO_TypeDef 就跟 struct _GPIO 是等同的作用了,但是 GPIO_TypeDef 使用起來 方便很多。

8、結(jié)構(gòu)體

經(jīng)常很多用戶提到,他們對(duì)結(jié)構(gòu)體使用不是很熟悉,但是 MDK 中太多地方使用結(jié)構(gòu)體以及 結(jié)構(gòu)體指針,這讓他們一下子摸不著頭腦,學(xué)習(xí) STM32 的積極性大大降低,其實(shí)結(jié)構(gòu)體并不是 那么復(fù)雜,這里我們稍微提一下結(jié)構(gòu)體的一些知識(shí),還有一些知識(shí)我們會(huì)在下面的“寄存器映 射”中講到一些。

聲明結(jié)構(gòu)體類型:

struct 結(jié)構(gòu)體名 

{ 
     成員列表; 

}變量名列表;

例如:

struct U_TYPE 

{ 
 int BaudRate 
 int WordLength; 

}usart1, usart2; 

在結(jié)構(gòu)體申明的時(shí)候可以定義變量,也可以申明之后定義,方法是:

struct 結(jié)構(gòu)體名字 結(jié)構(gòu)體變量列表 ;

例如:

struct U_TYPE usart1,usart2; 

結(jié)構(gòu)體成員變量的引用方法是:

結(jié)構(gòu)體變量名字.成員名?

比如要引用 usart1 的成員 BaudRate,方法是:usart1.BaudRate;結(jié)構(gòu)體指針變量定義也是 一樣的,跟其他變量沒有啥區(qū)別。

例如:

struct U_TYPE *usart3; /* 定義結(jié)構(gòu)體指針變量 usart3 */ 

結(jié)構(gòu)體指針成員變量引用方法是通過“->”符號(hào)實(shí)現(xiàn),比如要訪問 usart3 結(jié)構(gòu)體指針指向 的結(jié)構(gòu)體的成員變量 BaudRate,方法是:

usart3->BaudRate;

上面講解了結(jié)構(gòu)體和結(jié)構(gòu)體指針的一些知識(shí),其他的什么初始化這里就不多講解了。 講到 這里,有人會(huì)問,結(jié)構(gòu)體到底有什么作用呢?為什么要使用結(jié)構(gòu)體呢?下面我們將簡單的通過 一個(gè)實(shí)例回答一下這個(gè)問題。

在我們單片機(jī)程序開發(fā)過程中,經(jīng)常會(huì)遇到要初始化一個(gè)外設(shè)比如串口,它的初始化狀態(tài) 是由幾個(gè)屬性來決定的,比如串口號(hào),波特率,極性,以及模式。對(duì)于這種情況,在我們沒有 學(xué)習(xí)結(jié)構(gòu)體的時(shí)候,我們一般的方法是:

void usart_init(uint8_t usartx, uiut32_t BaudRate, uint32_t Parity, 
uint32_t Mode); 

這種方式是有效的同時(shí)在一定場(chǎng)合是可取的。但是試想,如果有一天,我們希望往這個(gè)函 數(shù)里面再傳入一個(gè)/幾個(gè)參數(shù),那么勢(shì)必我們需要修改這個(gè)函數(shù)的定義,重新加入新的入口參數(shù), 隨著開發(fā)不斷的增多,那么是不是我們就要不斷的修改函數(shù)的定義呢?這是不是給我們開發(fā)帶 來很多的麻煩?那又怎樣解決這種情況呢?

我們使用結(jié)構(gòu)體參數(shù),就可以在不改變?nèi)肟趨?shù)的情況下,只需要改變結(jié)構(gòu)體的成員變量, 就可以達(dá)到改變?nèi)肟趨?shù)的目的。

結(jié)構(gòu)體就是將多個(gè)變量組合為一個(gè)有機(jī)的整體,上面的函數(shù),usartx,BaudRate,Parity, Mode

等這些參數(shù),他們對(duì)于串口而言,是一個(gè)有機(jī)整體,都是來設(shè)置串口參數(shù)的,所以我們可以將 他們通過定義一個(gè)結(jié)構(gòu)體來組合在一個(gè)。MDK 中是這樣定義的:

typedef struct 

{ 
     uint32_t BaudRate; 
     uint32_t WordLength; 
     uint32_t StopBits; 
     uint32_t Parity; 
     uint32_t Mode; 
     uint32_t HwFlowCtl; 
     uint32_t OverSampling; 

} UART_InitTypeDef; 

?這樣,我們?cè)诔跏蓟诘臅r(shí)候入口參數(shù)就可以是 USART_InitTypeDef 類型的變量或者指 針變量了,于是我們可以改為:

void usart_init(UART_InitTypeDef *huart); 

這樣,任何時(shí)候,我們只需要修改結(jié)構(gòu)體成員變量,往結(jié)構(gòu)體中間加入新的成員變量,而 不需要修改函數(shù)定義就可以達(dá)到修改入口參數(shù)同樣的目的了。這樣的好處是不用修改任何函數(shù) 定義就可以達(dá)到增加變量的目的。 理解了結(jié)構(gòu)體在這個(gè)例子中間的作用嗎?在以后的開發(fā)過程中,如果你的變量定義過多, 如果某幾個(gè)變量是用來描述某一個(gè)對(duì)象,你可以考慮將這些變量定義在結(jié)構(gòu)體中,這樣也許可 以提高你的代碼的可讀性。

使用結(jié)構(gòu)體組合參數(shù),可以提高代碼的可讀性,不會(huì)覺得變量定義混亂。當(dāng)然結(jié)構(gòu)體的作 用就遠(yuǎn)遠(yuǎn)不止這個(gè)了,同時(shí),MDK 中用結(jié)構(gòu)體來定義外設(shè)也不僅僅只是這個(gè)作用,這里我們只 是舉一個(gè)例子,通過最常用的場(chǎng)景,讓大家理解結(jié)構(gòu)體的一個(gè)作用而已。后面一節(jié)我們還會(huì)講 解結(jié)構(gòu)體的一些其他知識(shí)。

9、指針

指針是一個(gè)值指向地址的變量(或常量),其本質(zhì)是指向一個(gè)地址,從而可以訪問一片內(nèi) 存區(qū)域。在編寫 STM32 代碼的時(shí)候,或多或少都要用到指針,它可以使不同代碼共享同一片內(nèi) 存數(shù)據(jù),也可以用作復(fù)雜的鏈接性的數(shù)據(jù)結(jié)構(gòu)的構(gòu)建,比如鏈表,鏈?zhǔn)蕉鏄涞?,而且,有?地方必須使用指針才能實(shí)現(xiàn),比如內(nèi)存管理等。

申明指針我們一般以 p 開頭,如:

char * p_str = “This is a test!”;

這樣,我們就申明了一個(gè) p_str 的指針,它指向 This is a test!這個(gè)字符串的首地址。我們 編寫如下代碼:

int main(void) 

{ 
     uint8_t temp = 0X88; /* 定義變量 temp */ 
     uint8_t *p_num = &temp; /* 定義指針 p_num,指向 temp 的地址 */
     HAL_Init(); /* 初始化 HAL 庫 */ 
     sys_stm32_clock_init(RCC_PLL_MUL9); /* 設(shè)置時(shí)鐘,72M */ 

     delay_init(72); /* 延時(shí)初始化 */ 
     usart_init(115200); /* 初始化串口 */ 
     printf("temp:0X%X\r\n", temp); /* 打印 temp 的值 */ 
     printf("*p_num: 0X %X\r\n", *p_num); /* 打印*p_num 的值 */ 
     printf("p_num: 0X %X\r\n", (uint32_t)p_num); /* 打印 p_num 的值 */ 
     printf("&p_num: 0X %X\r\n", (uint32_t)&p_num); /* 打印&p_num 的值 */ 
     while (1); 

} 

此代碼的輸出結(jié)果為:

STM32 基礎(chǔ)知識(shí)入門 (C語言基礎(chǔ)鞏固)

p_num:是uint8_t類型指針,指向temp變量的地址,其值等于temp變量的地址。

*p_num:取p_num指向的地址所存儲(chǔ)的值,即temp的值。

&p_num:取p_num指針的地址,即指針自身的地址。

以上,就是指針的簡單使用和基本概念說明,指針的詳細(xì)知識(shí)和使用范例大家可以百度學(xué)習(xí),網(wǎng)上有非常多的資料可供參考。指針是C語言的精髓,在后續(xù)的代碼中我們將會(huì)大量用到各種指針,大家務(wù)必好好學(xué)習(xí)和了解指針的使用。

?文章來源地址http://www.zghlxwxcb.cn/news/detail-429860.html

到了這里,關(guān)于STM32 基礎(chǔ)知識(shí)入門 (C語言基礎(chǔ)鞏固)的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • 自然語言處理從入門到應(yīng)用——LangChain:基礎(chǔ)知識(shí)與介紹

    分類目錄:《大模型從入門到應(yīng)用》總目錄 LangChain系列文章: 基礎(chǔ)知識(shí) 快速入門 安裝與環(huán)境配置 鏈(Chains)、代理(Agent:)和記憶(Memory) 快速開發(fā)聊天模型 模型(Models) 基礎(chǔ)知識(shí) 大型語言模型(LLMs) 基礎(chǔ)知識(shí) LLM的異步API、自定義LLM包裝器、虛假LLM和人類輸入LLM(

    2024年02月13日
    瀏覽(107)
  • 自然語言處理從入門到應(yīng)用——LangChain:模型(Models)-[大型語言模型(LLMs):基礎(chǔ)知識(shí)]

    分類目錄:《大模型從入門到應(yīng)用》總目錄 LangChain系列文章: 基礎(chǔ)知識(shí) 快速入門 安裝與環(huán)境配置 鏈(Chains)、代理(Agent:)和記憶(Memory) 快速開發(fā)聊天模型 模型(Models) 基礎(chǔ)知識(shí) 大型語言模型(LLMs) 基礎(chǔ)知識(shí) LLM的異步API、自定義LLM包裝器、虛假LLM和人類輸入LLM(

    2024年02月16日
    瀏覽(116)
  • 自然語言處理從入門到應(yīng)用——LangChain:索引(Indexes)-[基礎(chǔ)知識(shí)]

    分類目錄:《大模型從入門到應(yīng)用》總目錄 LangChain系列文章: 基礎(chǔ)知識(shí) 快速入門 安裝與環(huán)境配置 鏈(Chains)、代理(Agent:)和記憶(Memory) 快速開發(fā)聊天模型 模型(Models) 基礎(chǔ)知識(shí) 大型語言模型(LLMs) 基礎(chǔ)知識(shí) LLM的異步API、自定義LLM包裝器、虛假LLM和人類輸入LLM(

    2024年02月12日
    瀏覽(64)
  • 自然語言處理從入門到應(yīng)用——LangChain:代理(Agents)-[基礎(chǔ)知識(shí)]

    分類目錄:《大模型從入門到應(yīng)用》總目錄 LangChain系列文章: 基礎(chǔ)知識(shí) 快速入門 安裝與環(huán)境配置 鏈(Chains)、代理(Agent:)和記憶(Memory) 快速開發(fā)聊天模型 模型(Models) 基礎(chǔ)知識(shí) 大型語言模型(LLMs) 基礎(chǔ)知識(shí) LLM的異步API、自定義LLM包裝器、虛假LLM和人類輸入LLM(

    2024年02月13日
    瀏覽(75)
  • 自然語言處理從入門到應(yīng)用——LangChain:鏈(Chains)-[基礎(chǔ)知識(shí)]

    分類目錄:《大模型從入門到應(yīng)用》總目錄 LangChain系列文章: 基礎(chǔ)知識(shí) 快速入門 安裝與環(huán)境配置 鏈(Chains)、代理(Agent:)和記憶(Memory) 快速開發(fā)聊天模型 模型(Models) 基礎(chǔ)知識(shí) 大型語言模型(LLMs) 基礎(chǔ)知識(shí) LLM的異步API、自定義LLM包裝器、虛假LLM和人類輸入LLM(

    2024年02月12日
    瀏覽(64)
  • 自然語言處理從入門到應(yīng)用——LangChain:提示(Prompts)-[基礎(chǔ)知識(shí)]

    分類目錄:《大模型從入門到應(yīng)用》總目錄 LangChain系列文章: 基礎(chǔ)知識(shí) 快速入門 安裝與環(huán)境配置 鏈(Chains)、代理(Agent:)和記憶(Memory) 快速開發(fā)聊天模型 模型(Models) 基礎(chǔ)知識(shí) 大型語言模型(LLMs) 基礎(chǔ)知識(shí) LLM的異步API、自定義LLM包裝器、虛假LLM和人類輸入LLM(

    2024年02月15日
    瀏覽(77)
  • 自然語言處理從入門到應(yīng)用——LangChain:記憶(Memory)-[基礎(chǔ)知識(shí)]

    分類目錄:《大模型從入門到應(yīng)用》總目錄 LangChain系列文章: 基礎(chǔ)知識(shí) 快速入門 安裝與環(huán)境配置 鏈(Chains)、代理(Agent:)和記憶(Memory) 快速開發(fā)聊天模型 模型(Models) 基礎(chǔ)知識(shí) 大型語言模型(LLMs) 基礎(chǔ)知識(shí) LLM的異步API、自定義LLM包裝器、虛假LLM和人類輸入LLM(

    2024年02月14日
    瀏覽(62)
  • 自然語言處理從入門到應(yīng)用——LangChain:提示(Prompts)-[提示模板:基礎(chǔ)知識(shí)]

    分類目錄:《大模型從入門到應(yīng)用》總目錄 LangChain系列文章: 基礎(chǔ)知識(shí) 快速入門 安裝與環(huán)境配置 鏈(Chains)、代理(Agent:)和記憶(Memory) 快速開發(fā)聊天模型 模型(Models) 基礎(chǔ)知識(shí) 大型語言模型(LLMs) 基礎(chǔ)知識(shí) LLM的異步API、自定義LLM包裝器、虛假LLM和人類輸入LLM(

    2024年02月15日
    瀏覽(47)
  • 自然語言處理從入門到應(yīng)用——LangChain:模型(Models)-[聊天模型(Chat Models):基礎(chǔ)知識(shí)]

    分類目錄:《大模型從入門到應(yīng)用》總目錄 LangChain系列文章: 基礎(chǔ)知識(shí) 快速入門 安裝與環(huán)境配置 鏈(Chains)、代理(Agent:)和記憶(Memory) 快速開發(fā)聊天模型 模型(Models) 基礎(chǔ)知識(shí) 大型語言模型(LLMs) 基礎(chǔ)知識(shí) LLM的異步API、自定義LLM包裝器、虛假LLM和人類輸入LLM(

    2024年02月15日
    瀏覽(55)
  • Go語言基礎(chǔ)知識(shí)(一):基礎(chǔ)介紹

    Go語言基礎(chǔ)知識(shí)(一):基礎(chǔ)介紹

    Go 語言又稱 Golang,由 Google 公司于 2009 年發(fā)布,近幾年伴隨著云計(jì)算、微服務(wù)、分布式的發(fā)展而迅速崛起,躋身主流編程語言之列,和 Java 類似,它是一門靜態(tài)的、強(qiáng)類型的、編譯型編程語言,為并發(fā)而生,所以天生適用于并發(fā)編程(網(wǎng)絡(luò)編程)。 目前 Go 語言支持 Windows、

    2024年02月13日
    瀏覽(20)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包