一、封裝外設
用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...