新聞中心

        EEPW首頁 > 嵌入式系統 > 設計應用 > 寄存器物理地址映射到結構體封裝的寄存器的過程

        寄存器物理地址映射到結構體封裝的寄存器的過程

        作者: 時間:2016-11-26 來源:網絡 收藏
        一、 STM32頭文件中 結構體封裝寄存器的方式

        typedef struct
        {
        vu32 CR;
        vu32 CFGR;
        vu32 CIR;
        vu32 APB2RSTR;
        vu32 APB1RSTR;
        vu32 AHBENR;
        vu32 APB2ENR;
        vu32 APB1ENR;
        vu32 BDCR;
        vu32 CSR;
        } RCC_TypeDef;

        本文引用地址:http://www.104case.com/article/201611/321901.htm

        #define PERIPH_BASE((u32)0x40000000)

        #define AHBPERIPH_BASE(PERIPH_BASE + 0x20000)

        #define RCC_BASE(AHBPERIPH_BASE + 0x1000)

        #define RCC((RCC_TypeDef *) RCC_BASE)

        在頭文件中這樣定義后,就可以在程序中以

        RCC->CR|=0x00010000;來直接操作某一寄存器了。

        二、對這一方式的分析與總結也就是關于單片機寄存器封裝問題:

        最近在學習嵌入式linux過程中,看到 DM368寄存器地址映射到結構體封裝的寄存器的系統文件。因為嵌入式linux開發沒有像單片機一樣的編譯軟件,系統文件不是編譯軟件本身自帶的。嵌入式編程需要自己找到需要用的模塊的頭文件,來操作相應的寄存器,編寫相應的驅動。于是乎,在看別人的程序時,迷迷糊糊的就從主程序看到了驅動程序,又看到了底層操作寄存器的程。為了徹底搞懂嵌入式程序,終于注意到了以前單片機編程時沒怎么注意過的結構體封裝寄存器,映射物理地址。看了好半天也沒有看明白 宏定義是如何映射地址的,關鍵是這樣語法的一句話:

        #define RCC((RCC_TypeDef *) RCC_BASE)

        RCC_BASE的定義是 #define RCC_BASE(AHBPERIPH_BASE + 0x1000)  是物理地址經過代換(AHBPERIPH_BASE + 0x1000)=0x40021000

        經過思索和討教,對這種封裝寄存器的來龍去脈終于恍然大悟。

        首先,碰到#define一定要牢記C語言老師的教誨--‘僅僅是替換’。因此在使用結構體封裝的寄存器來操作寄存器時,如RCC->CR =0x00實際上等價于 ((RCC_TypeDef *) RCC_BASE)->CR=0x00。 進一步,將RCC_BASE替換為 (AHBPERIPH_BASE + 0x1000) ,這里AHBPERIPH_BASE是地址,也是常量。于是整句話就被還原為 ((RCC_TypeDef *)0x40021000)->CR=0x00 。

        也就是 先對地址常量 (AHBPERIPH_BASE + 0x1000) 進行強制類型轉換為 (RCC_TypeDef )類型的結構體指針。由結構體指針的相關知識可知,將一個地址指向結構體,那么該地址后面的地址會自動按結構體中定義的結構體成員來劃分。所以 ,作為該結構體的第一個成員CR,((RCC_TypeDef *)0x40021000)->CR也就是代表 (AHBPERIPH_BASE + 0x1000) 。 以此類推 ,,((RCC_TypeDef *)0x40021000)->CFGR 則代表

        RCC_BASE(0x40021000)的下一段地址 即0x40021004 (手冊中 RCC_CFGR寄存器的地址)

        可以看到這種結構體封裝寄存器方式訪問寄存器的實質仍然是直接對寄存器所在的物理地址操作!!

        至于為什么用這種方式來封裝結構體。可以參考51單片機寄存器的定義方式。keil中51單片機每一個寄存器是直接給出對應的存儲器地址,而沒有用這種結構體方式封裝。因為操作寄存器的實質永遠都是對寄存器所在的地址操作。 STM32 中寄存器很多,如果像51一樣 對每一個寄存器地址給定一個寄存器名稱,太繁雜而且沒有直觀性。結構體封裝,可以直觀的看出每個模塊中有哪些寄存器,方便編程。

        圖:keil中51寄存器的定義方式



        評論


        技術專區

        關閉
        主站蜘蛛池模板: 黄梅县| 金坛市| 海晏县| 姜堰市| 廊坊市| 古蔺县| 罗城| 鸡东县| 东莞市| 开阳县| 北宁市| 罗源县| 东平县| 乃东县| 乐清市| 姜堰市| 阜宁县| 莲花县| 广饶县| 闵行区| 闻喜县| 永寿县| 红河县| 贡嘎县| 兰考县| 大庆市| 合阳县| 嘉善县| 横山县| 诸暨市| 镇坪县| 公主岭市| 体育| 福清市| 旺苍县| 沙湾县| 高碑店市| 汝州市| 郁南县| 石棉县| 佛坪县|