C語言是單片機(jī)開發(fā)中的必備基礎(chǔ)知識(shí),本文列舉了部分STM32學(xué)習(xí)中比較常見的一些C語言基礎(chǔ)知識(shí),希望能對(duì)大家有所幫助。
01位操作
下面我們先講解幾種位操作符,然后講解位操作使用技巧。C語言支持以下六種位操作:
(六種位操作)
下面,重點(diǎn)講解一下位操作在單片機(jī)開發(fā)中的一些實(shí)用技巧。
1.1 在不改變其他位的值的狀況下,對(duì)某幾個(gè)位進(jìn)行設(shè)值。
這個(gè)場景在單片機(jī)開發(fā)中經(jīng)常使用,方法就是我們先對(duì)需要設(shè)置的位用&操作符進(jìn)行清零操作,然后用 | 操作符設(shè)值。
比如,我要改變GPIOA的狀態(tài),可以先對(duì)寄存器的值進(jìn)行&清零操作:
然后再與需要設(shè)置的值進(jìn)行|或運(yùn)算:
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)同樣的效果,但是可讀性稍差,而且修改也比較麻煩。
1.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ù)性都要比后者好很多。
1.4 ^按位異或操作使用技巧
該功能非常適合用于控制某個(gè)位翻轉(zhuǎn),常見的應(yīng)用場景就是控制LED閃爍,如下:
GPIOB->ODR ^= 1 << 5;
執(zhí)行一次該代碼,就會(huì)使PB5的輸出狀態(tài)翻轉(zhuǎn)一次,如果我們的LED接在PB5上,就可以看到LED閃爍了。
02define宏定義
define是C語言中的預(yù)處理命令,它用于宏定義(定義的是常量),可以提高源代碼的可讀性,為編程提供方便。常見的格式:
“標(biāo)識(shí)符”為所定義的宏名?!白址笨梢允浅?shù)、表達(dá)式、格式串等。例如:
定義標(biāo)識(shí)符HSE_VALUE的值為8000000,數(shù)字后的U表示unsigned的意思。至于define宏定義的其他一些知識(shí),比如宏定義帶參數(shù),這里就不多講解了。
03ifdef條件編譯
單片機(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
條件編譯在HAL庫里面是用得很多,在stm32mp1xx_hal_conf.h這個(gè)頭文件中經(jīng)常會(huì)看到這樣的語句:
#if !defined (HSE_VALUE) #define HSE_VALUE 24000000U #endif
如果沒有定義HSE_VALUE這個(gè)宏,則定義HSE_VALUE宏,并且HSE_VALUE的值為24000000U。條件編譯也是C語言的基礎(chǔ)知識(shí)吧。
這里提一下,24000000U中的U表示無符號(hào)整型,常見的,UL表示無符號(hào)長整型,F(xiàn)表示浮點(diǎn)型。
這里加了U以后,系統(tǒng)編譯時(shí)就不進(jìn)行類型檢查,直接以U的形式把值賦給某個(gè)對(duì)應(yīng)的內(nèi)存,如果超出定義變量的范圍,則截取。
04extern變量申明
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;
extern的使用比較簡單,但是也會(huì)經(jīng)常用到,需要掌握。
05typedef類型別名
typedef用于為現(xiàn)有類型創(chuàng)建一個(gè)新的名字,或稱為類型別名,用來簡化變量的定義。typedef在HAL庫用得最多的就是定義結(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 */
但這樣很繁瑣,HAL庫中有很多這樣的結(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使用起來方便很多。
上一篇:STM32單片機(jī)引腳介紹及功能 STM32單片機(jī)的工作原理和基本組成
下一篇:如何使用代碼清除STM32單片機(jī)上的PCROP
推薦閱讀最新更新時(shí)間:2025-06-26 21:42






設(shè)計(jì)資源 培訓(xùn) 開發(fā)板 精華推薦
- Microchip 升級(jí)數(shù)字信號(hào)控制器(DSC)產(chǎn)品線 推出PWM 分辨率和 ADC 速度業(yè)界領(lǐng)先的新器件
- 意法半導(dǎo)體STM32MP23x:突破成本限制的工業(yè)AI應(yīng)用核心
- 意法半導(dǎo)體推出用于匹配遠(yuǎn)距離無線微控制器STM32WL33的集成的匹配濾波芯片
- ESP32開發(fā)板連接TFT顯示屏ST7789跳坑記
- 如何讓ESP32支持analogWrite函數(shù)
- LGVL配合FreeType為可變字體設(shè)置字重-ESP32篇
- 使用樹莓派進(jìn)行 ESP32 Jtag 調(diào)試
- ESP32怎么在SPIFFS里面存儲(chǔ)html,css,js文件,以及網(wǎng)頁和arduino的通訊
- ESP32 freeRTOS使用測試
- LTC3772EDDB 演示板,550kHz 降壓型 DC/DC 轉(zhuǎn)換器,VIN = 2.75V-8V,VOUT = 3.3V @ 2A
- 用于大功率通用離線電源的 NCP1379 準(zhǔn)諧振電流模式控制器的典型應(yīng)用
- 用于 CRT 顯示器的 92W、-15V、5V、6.3V、15V、80V、200V AC 到 DC 多輸出電源
- 來自多個(gè)輸入源的 LTC3622EDE-23/5 雙路輸出降壓型穩(wěn)壓器的典型應(yīng)用電路
- AKD4644-B,帶有內(nèi)置 MIC/HP/RCV 放大器的 AK4644 立體聲編解碼器評(píng)估板
- 使用 Analog Devices 的 AD8033AKS 的參考設(shè)計(jì)
- LT6657BHMS8-1.25 負(fù)分流模式基準(zhǔn)的典型應(yīng)用電路
- CN0130
- 用于便攜式的 12 位 8 通道 DAC
- 使用 ROHM Semiconductor 的 BD12IA5WEFJ 的參考設(shè)計(jì)
- PCIe M.2接口測試的現(xiàn)狀、挑戰(zhàn)與泰克解決方案
- ABB在中國推出面向電子制造業(yè)的兩大全新機(jī)器人系列
- ABB在中國推出PoWa協(xié)作機(jī)器人系列
- 西門子 NX 新增 AI 助手等多項(xiàng)功能
- 貿(mào)澤即日起開售適用于數(shù)據(jù)中心和網(wǎng)絡(luò)應(yīng)用的 全新TE Connectivity QSFP 112G SMT連接器
- ABB推出三大全新機(jī)器人系列,強(qiáng)化中國機(jī)器人市場領(lǐng)導(dǎo)地位
- 新思科技關(guān)于美國解除近期對(duì)華出口限制的聲明
- Wolfspeed 1700 V MOSFET 技術(shù),助力重塑輔助電源系統(tǒng)的耐用性和成本
- 英飛凌大中華區(qū) 2025 生態(tài)創(chuàng)新峰會(huì),究竟探討了哪些創(chuàng)新與生態(tài)合作?
- Microchip攜手Nippon Chemi-Con和NetVision 打造日本汽車市場首個(gè)ASA-ML攝像頭開發(fā)生態(tài)系統(tǒng)
- 新能源汽車的下一個(gè)風(fēng)口,超全面解析(產(chǎn)業(yè)篇)
- 百度飛槳將聯(lián)手華為麒麟芯片 共同開闊AI市場
- AI、HPC的助推器,下一代并行文件系統(tǒng)解決方案—EXA5
- 微埃智能:AI焊接的硬科技創(chuàng)業(yè)團(tuán)隊(duì)
- 確立市場定位,歐時(shí)電子亞太區(qū)總裁談如何 “創(chuàng)建不凡”
- 聯(lián)通專家兩會(huì)建言:盡快出臺(tái)5G低頻規(guī)劃 加速700MHz優(yōu)質(zhì)資源釋放
- Little Caesars發(fā)布披薩餅機(jī)器人專利
- 淺談:RF電路設(shè)計(jì)
- 2025年全球太陽能電纜市場收益有望超16億美元
- 微流體技術(shù)+碳納米管纖維=更安全的腦內(nèi)植入
- 四門課程帶你全方位了解AM335x
- STEVAL-IDB007V1—體驗(yàn)測評(píng)第二帖 @【ST MEMS 傳感器技術(shù)論壇】
- 首款符合PICO-ITX規(guī)格的A20開源硬件開發(fā)平臺(tái)
- E金幣兌換的kindle保護(hù)套
- 想用fpga做一點(diǎn)東西誰能告訴我i做什么啊啊啊~~~急求
- M8while循環(huán)的怪問題
- 關(guān)于diy顯卡的問題
- Wndows驅(qū)動(dòng)怎么移植到linux下
- 求STM32F429IGT項(xiàng)目初始化平臺(tái)。獎(jiǎng)勵(lì)E金幣
- 尋找zigbee組網(wǎng)定位解決方案