日韩在线免费播放-日韩在线免费av-日韩在线免费-日韩在线毛片-国产高清不卡视频-国产高清不卡

 

Exynos4412特殊功能寄存器的封裝

作者:秦老師,華清遠(yuǎn)見(jiàn)教育科技集團(tuán)講師。

特殊功能寄存器英文縮寫(xiě)為SFR,是Special Function Register的縮寫(xiě)。特殊功能寄存器是芯片功能實(shí)現(xiàn)的載體,可以理解為芯片廠商留給嵌入式開(kāi)發(fā)人員的控制接口,用于控制片內(nèi)外設(shè),比如GPIO、UART、ADC等等。每個(gè)片內(nèi)外設(shè)都有對(duì)應(yīng)的特殊寄存器,用于存放相應(yīng)功能部件的控制命令,數(shù)據(jù)或者狀態(tài)。

對(duì)于特殊功能寄存器的封裝是每個(gè)嵌入式工程師都應(yīng)該掌握的。那如何封裝芯片的特殊控制寄存器呢,我們以Exynos4412的GPIO片內(nèi)外設(shè)為例說(shuō)明。

(1)查看Exynos4412芯片的地址映射表

查看Exynos4412芯片手冊(cè)的第二章2 Memory Map(30頁(yè))地址映射表,我們可以看到Exynos4412的特殊功能寄存器絕大部分都放到了0x1000_0000到0x1400_0000的地址空間。

(2)查看GPIO模塊的寄存器描述表

查看芯片手冊(cè),第四章4 General Purpose Input/Output (GPIO) Control,4.3節(jié)(41頁(yè))寄存器描述,有完整的GPIO模塊的寄存器描述表。我們可以得到GPIO模塊的基地址和每個(gè)寄存器相對(duì)基地址的偏移量。

GPIO模塊的基地址是:0x1140_0000
        GPA0組的配置寄存器GPA0CON的地址是: 基地址 + 偏移量
        0x11400000 + 0x0000 = 0x11400000

(3)封裝寄存器的第一種方式是直接一對(duì)一封裝

例如:

#define GPA0CON (*(volatile unsigned int *)0x11400000)

分析:

這是一個(gè)宏定義,宏定義在預(yù)處理階段進(jìn)行直接替換,為了方便理解,我們可以先把volatile去掉,關(guān)鍵是理解(*(unsigned int *)0x11400000)。

0x11400000 是一個(gè)16進(jìn)制的數(shù)據(jù),前面用(unsigned int *)修飾,表示把0x11400000強(qiáng)制轉(zhuǎn)換成了一個(gè)指向unsigned int型變量的指針。簡(jiǎn)單的說(shuō),(unsigned int *)0x11400000指向了內(nèi)存中從0x11400000開(kāi)始的連續(xù)的4個(gè)字節(jié)空間。(0x11400000—0x11400003)。

(*(unsigned int *)0x11400000)是在(unsigned int *)0x11400000又加了一個(gè)指針運(yùn)算符*,表示取內(nèi)存單元里的數(shù)據(jù)。

volatile是C語(yǔ)言的32個(gè)關(guān)鍵字之一,是一種類型修飾符,用它聲明的類型變量表示可以被某些編譯器未知的因素更改,比如:操作系統(tǒng)、硬件中斷或者線程等。遇到這個(gè)關(guān)鍵字聲明的變量,編譯器對(duì)訪問(wèn)該變量的代碼就不再進(jìn)行優(yōu)化,每次讀取這個(gè)變量的值都是要從內(nèi)存單元里讀取,而不是直接使用放在高速緩存或寄存器里的備份。從而可以提供對(duì)特殊地址的穩(wěn)定訪問(wèn)。

使用:

我們像unsigned int變量一樣訪問(wèn)特殊功能寄存器。

GPA0CON = (GPA0CON & ~(0xf<<4))| 1<<4; //將GPA0_1引腳設(shè)置為輸出功能

(4)封裝寄存器的第二種方式是結(jié)構(gòu)體封裝

例如:

/* GPA0 */
        typedef struct {
                unsigned int CON;
                unsigned int DAT;
                unsigned int PUD;
                unsigned int DRV;
                unsigned int CONPDN;
                unsigned int PUDPDN;
        }gpa0;
        #define GPA0 (* (volatile gpa0 *)0x11400000)

分析:

typedef 關(guān)鍵字聲明了名為gpa0的結(jié)構(gòu)體類型,結(jié)構(gòu)體內(nèi)又定義了 6個(gè)unsigned int類型的變量。unsigned int 類型變量為 32 位,在內(nèi)存內(nèi)存空間 中占4 個(gè)字節(jié)。

#define GPA0 (* (volatile gpa0 *)0x11400000)聲明了一個(gè)gpa0類型結(jié)構(gòu)體的宏,結(jié)構(gòu)體名是結(jié)構(gòu)體首成員的地址,GPA0這個(gè)結(jié)構(gòu)體的首成員CON地址為0x11400000,占4個(gè)字節(jié),在c語(yǔ)言中結(jié)構(gòu)體內(nèi)的成員變量是連續(xù)的,那么GPA0結(jié)構(gòu)體的第二個(gè)成員DAT得地址為:0x11400000+0x04 = 0x11400004。這個(gè) 0x04 偏移量,正是GPA0DAT寄存器相對(duì)于GPIO基地址的偏移地址。

結(jié)構(gòu)體內(nèi)其它成員的偏移量,也和相應(yīng)的寄存器偏移地址相符。因此,我們匹配了結(jié)構(gòu)體的首地址,就可以確定各寄存器的具體地址了。

使用:

我們用訪問(wèn)結(jié)構(gòu)體變量成員的方式,訪問(wèn)寄存器。

GPA0.CON = (GPA0.CON & ~(0xf<<4))| 1<<4; //將GPA0_1引腳設(shè)置為輸出功能

(5)使用集成開(kāi)發(fā)環(huán)境的芯片寄存器封裝

嵌入式開(kāi)發(fā)中我們把常用的寄存器寫(xiě)到一個(gè)頭文件中,每次使用的時(shí)候直接包含就可以。也有很多集成開(kāi)發(fā)環(huán)境會(huì)提供這樣的芯片特殊寄存器頭文件,比如在keil中創(chuàng)建arm7三星s3c2410芯片相關(guān)的工程,點(diǎn)擊鼠標(biāo)右鍵可以添#include <S3C2410A.H>頭文件。但不是所有芯片都支持。

主站蜘蛛池模板: 待到满山红叶时| 西藏秘密演员表全部| 都市频道节目表今天| 妹妹扮演的角色| 免费观看美女| 一年级数学一图四式的题| 欧美视频亚洲视频| 王梦婷| 贝加尔湖畔钢琴谱| 迷斯拉| 人总要有点爱好,生活才能继续 | 《兄弟》电影在线观看| 念亲恩简谱| 紧缚视频 | vk| 小镇姑娘高清电影| 相识韩国| 姐夫操小姨子| 最近好看电影推荐| 名星| 李子京| 新成长的烦恼| 免税车中企诚谊| 小早川怜子作品| 如果云知道歌词| 女同激情视频| 张静初三体电影| 女人的战争剧情介绍| 韩国一对一电影| 100克米饭多大一碗图片| 电影院线| 《ulises》完整版在线观看| 小小春| 在线黄色片| 新有菜免费在线观看| va在线观看视频| 狗报恩的10个征兆| 猎仇者演员表| 大唐诡事录之西行免费观看| 拔萝卜电影| 莫比乌斯电影在线观看全集高清| 孙东杓|