C語言對暫存器封裝

2021-07-10 11:09:13 字數 1941 閱讀 8534

一、封裝外設

用c語言**把外設位址對映用巨集定義封裝

/* 外設基位址 */

#define periph_base ((unsigned int)0x40000000)

/* 匯流排基位址 */

#define apb1periph_base periph_base

#define apb2periph_base (periph_base + ox00010000)..

/* gpio外設基位址 */

#define gpioa_base (ahb1periph_base + 0x0000)

#defien gpiob_baae (ahb1periph_base + 0x0400)..

/* 暫存器基位址,以gpioa為例 */

#define gpioa_moder (gpioa_base+0x00)

#define gpioa_otyper (gpioa_base+0x04)

..

二、封裝暫存器

typedef

unsigned

int uint32_t; //無符號32位變數

typedef

unsigned

short

int uint16_t; //無符號16位變數

/* gpio暫存器列表 */

typedef

structgpio_typedef;

上面這段**用typedef關鍵字宣告了名為 gpio_typedef的結構體型別。

使用巨集定義定義各個gpio埠的首位址

/* 使用gpio_typedef把位址強制轉換成指標 */

#define gpioa ((gpio_typedef *) gpioa_base)

#define gpiob ((gpio_typedef *) gpiob_base)..

/* 使用定義好評的巨集直接訪問 */

/* 訪問gpioa埠的暫存器*/

gpioa->bsrrl = 0xffff; //通過指標訪問並修改gpioa_bsrrl暫存器

gpioa->moder = oxfffffff; //修改gpioa_moder暫存器

總結:用結構體封裝一類暫存器,然後強制轉換成指標,通過巨集定義執行埠基位址,再加上相應的偏移位址就可以直接訪問相應的暫存器。

修改暫存器的某一位

在51微控制器中通過關鍵字sbit來實現位定義,但是m4中沒有這個關鍵字。下面先說說c語言如何操作某一位。

1、把變數的某位清零

//定義乙個變數a = 1001 1111b (二進位制)

unsigned

char a = 0x9f;

//對bit2清零

a &= ~(1

<<2);

//括號中的1左移兩位,(1<<2)得二進位制:0000 0100b

//按位取反,~(1<<2)得1111 1011b

//假如a中原來的值為二進位制:a=1001 1111b

//所有的數與a作「位與&」運算,a=(1001 1111b) & (1111 1011b)

//運算後,a = 1001 1011b

2、把變數的某幾個連續位清零

//若把a中的二進位制位分為2個一組

a &= ~(3

<<2*1);

//括號中的3左移兩位, 然後在取反,得到1111 0011b

//然後「位與&」,得到 1001 0011b

這裡面涉及到運算子的優先順序*的優先順序高於<<,所以(3<<2*1)是把3左移3位。

下次在學習m4中的位帶操作,因為裡面涉及的知識比較多。

C語言對暫存器的位操作

1 位與 邏輯與 1 1 1 1 0 0 0 0 0 0 1 0 2 位或 邏輯或 1 1 1 1 0 1 0 0 0 0 1 1 3 位取反 邏輯取反 4 位異或 不同為1,相同為0 1 1 0 1 0 1 0 0 0 0 1 1 總結 5 移位操作 暫存器的操作要求 操作暫存器時,要求改變某一特...

C語言暫存器變數

暫存器存在於cpu內部,運算速度非常快,因為記憶體中的資料必須載入暫存器才能計算。如果直接定義乙個變數為暫存器變數,則少了載入等過程自然會快。對於頻繁使用的變數可以把它放在暫存器中來提速度。對於vc編譯器會自動優化,即使沒有宣告暫存器變數,vc也會自動優化。對於gcc編譯器就不會自動優化。定義乙個暫...

暫存器(通用暫存器)

因為學習使用的是王爽的 組合語言 第3版 因此也只能提到8086cpo的暫存器。對於其他而言,原理都是相通的。對於8086暫存器,有14個暫存器,主要是 ax bx cx dx si di sp bp ip cs ss ds es psw。一 通用暫存器 8086的通用暫存器有ax bx cx dx...