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

2021-01-07 電子產品世界

一、 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.eepw.com.cn/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寄存器的定義方式


相關焦點

  • 什麼是CPU的寄存器
    數據寄存器的名稱和相互間的。在程序設計時需要注意,邏輯上不同的寄存器在物理上可能相互覆蓋。例如,當我們修改AL寄存器的內容時,同時也修改了AX寄存器的低8位。這裡還需說明一點,同一個寄存器可能屬於不同的寄存器組,例如BX寄存器,它既屬於數據寄存器組,也屬於地址指針寄存器組,後面小編我還將介紹它作為地址指針寄存器的用途。
  • STM32中關於Contex-M3寄存器說明
    在STM32中用到了Cortex-M3定義的三組寄存器,有關這三組寄存器的說明不在STM32的技術手冊中,需要參考ARM公司發布的Cortex-M3
  • 愛了愛了,這篇寄存器講的有點意思
    那麼這個過程勢必涉及到從存儲器中讀取和寫入數據,因為它涉及通過控制總線發送數據請求並進入存儲器存儲單元,通過同一通道獲取數據,這個過程非常的繁瑣並且會涉及到大量的內存佔用,而且有一些常用的內存頁存在,其實是沒有必要的,因此出現了寄存器,存儲在 CPU 內部。
  • 寄存器和移位寄存器
    1.邏輯電路: 2.工作原理3.右移位寄存器的狀態表㈡ 4位左移位寄存器。5.優缺點:二、扭環計數器同環形計數器的分析過程7.4.4 順序脈衝發生器一、基本概念二、由環形計數器實現三、由雙向移位寄存器CT74LS194構成㈠ 順序正脈衝㈡ 順序負脈衝四、還可以用計數器+解碼器實現 現代教學方法與手段:DLCCAI或EWB演示移位寄存器和順序脈衝發生器的邏輯功能7.4 寄存器和移位寄存器
  • 彙編中各寄存器的作用
    寄存器是CPU內部的元件,寄存器擁有非常高的讀寫速度,所以在寄存器之間的數據傳送非常快。寄存器用途  1.可將寄存器內的數據執行算術及邏輯運算;  2.存於寄存器內的地址可用來指向內存的某個位置,即尋址;  3.可以用來讀寫數據到電腦的周邊設備。
  • 累加器是寄存器嗎?寄存器、累加器、暫存器有什麼區別?
    什麼是寄存器本文引用地址:http://www.eepw.com.cn/article/201804/378722.htm  寄存器,是集成電路中非常重要的一種存儲單元,通常由觸發器組成。在集成電路設計中,寄存器可分為電路內部使用的寄存器和充當內外部接口的寄存器這兩類。
  • 移位寄存器的特點_移位寄存器工作原理
    移位寄存器概要   在數字電路中,移位寄存器(英語:shiftregister)是一種在若干相同時間脈衝下工作的以觸發器為基礎的器件,數據以並行或串行的方式輸入到該器件中,然後每個時間脈衝依次向左或右移動一個比特,在輸出端進行輸出。
  • GPIO內部結構、工作原理及相關寄存器詳解(以STM32為例)
    2.    1,CPU寫入位設置/清楚寄存器BSRR,映射到輸出數據寄存器ODR  2,聯通到輸出控制電路(也就是ODR的電平)  3,ODR電平通過輸出控制電路進入N-MOS管截止,被上拉到高電平,IO口輸出為高電平1  當輸出控制電路輸出0時:  P-MOS管截止N-MOS管導通,被下拉到低電平,IO口輸出為低電平0  同時IO口輸出的電平可以通過輸入電路讀取  8,GPIO輸出工作模式4-復用推輓輸出模式
  • 51特殊功能寄存器
    這128個單元中,特殊功能寄存器僅佔用了21個單元,其餘單元51單片機不能對它們進行讀/寫操作(即不能作內部數據存儲器使用)。單元地址可被8整除的SFR可位尋址。如圖1)累加器A或特殊功能寄存器ACC累加器為8位寄存器,用於存放操作數,也可用來存放運算的中間結果。A和ACC雖是同一個寄存器,但是在指令中它們卻是有區別的。
  • 單片機的特殊功能寄存器
    在單片機中有一些獨立的存儲單元是用來控制這些器件的,被稱之為特殊功能寄存器(SFR)。<特殊功能寄存器地址映象表(一)><特殊功能寄存器地址映象表(三)>這是個什麼東西,可不能從名字上理解,它是一個寄存器,而不是一個做加法的東西,為什麼給它這麼一個名字呢?或許是因為在運算器做運算時其中一個數一定是在ACC中的緣故吧。它的名字特殊,身份也特殊,稍後我們將學到指令,能發現,所有的運算類指令都離不開它。2、B:一個寄存器。在做乘、除法時放乘數或除數,不做乘除法時,隨你怎麼用。3、PSW:程序狀態字。
  • 淺談彙編中的ds,cs與ip,ss與sp寄存器
    ,(基於8086CPU)(1)ds (Data Segment) 數據段寄存器當我們想讀取一個指定的內存單元上的數據時,我們可以通過把數據所在的內存段地址放入到ds寄存器中去,然後讀取或者寫入數據時就可以通過該ds寄存器內的段地址偏移得到我們的數據,或者偏移後寫入數據例如,我們現在想讀取1000:0這個地址上的數據並且往1000:1這個地址寫入一個數據時:
  • niosII中串口RS232程序使用結構體和聯合體結合的用法
    在NIOS II軟體開發過程中,如果使用我們提出的寄存器操作方式的話,首先需要定義一個寄存器結構體,之所以這樣做是為了在軟體書寫過程中操作方便,更是為了增強程序的可讀性。我們就拿UART來舉例說明。 首先,我們看一下UART的寄存器說明,如下表所示本文引用地址:http://www.eepw.com.cn/article/201612/330842.htm
  • 【乾貨分享】從0開始學ARM-ARM模式、寄存器、流水線
    未分組寄存器R0~R7在所有運行模式下,未分組寄存器都指向同一個物理寄存器,它們未被系統用作特殊的用途.因此在中斷或異常處理進行運行模式轉換時,由於不同的處理器運行模式均使用相同的物理寄存器,所以可能造成寄存器中數據的破壞。2. 分組寄存器R8~R14對於分組寄存器,它們每一次所訪問的物理寄存器都與當前處理器的運行模式有關。
  • 【STM32】ADC的基本原理、寄存器
    註: ADC1和ADC2的中斷映射在同一個中斷向量上,而ADC3的中斷有自己的中斷向量。閥值位於ADC_HTR和ADC_LTR寄存器的最低12個有效位中。通過設置ADC_CR1寄存器的AWDIE位以允許產生相應中斷。需要注意的是:閥值獨立於由ADC_CR2寄存器上的ALIGN位選擇的數據對齊模式。比較是在對齊之前完成的。也就是說,在數據保存到數據寄存器之前,就已經完成了比較(數據對齊在下文中有講解)!
  • SD卡讀CSD寄存器
    uint8 PermWrProtect; // 永久防寫 uint8 TempWrProtect; // 暫時防寫 uint8 FileFormat; // 文件系統 uint8 ECC; // ECC code uint8 CSD_CRC; // CSD CRC uint8 Reserved4; // 始終為 1} SD_CSD;本文引用地址
  • Cortex A9架構下,為什麼使用結構體效率會更高一些?
    作為過來人,我發現很多程序猿新手,在編寫代碼的時候,特別喜歡定義很多獨立的全局變量,而不是把這些變量封裝到一個結構體中,主要原因是圖方便,但是要知道,這其實是一個不好的習慣,而且會降低整體代碼的性能。
  • ARM的2種工作狀態,7種工作模式和37個寄存器
    任意時刻(也就是任意的處理器模式下),可見的寄存器包括15個通用寄存器(R0~R14)、一個或兩個狀態寄存器及程序計數器(PC)。在所有的寄存器中,有些是各模式共用的同一個物理寄存器;有一些寄存器是各模式自己擁有的獨立的物理寄存器。 系統模式和用戶模式共享相同的寄存器。
  • 單片機關鍵字寄存器和運算符
    break程序語句退出最內層循環case程序語句Switch語句中的選擇項char數據類型說明單字節整型數或字符型數據const存儲類型說明在程序執行過程中不可更改的常量值關鍵字用 途說 明bit位標量聲明聲明一個位標量或位類型的函數sbit位標量聲明聲明一個可位尋址變量Sfr特殊功能寄存器
  • IO埠映射和IO內存映射(詳解S3C24XX_GPIO驅動)
    (一)地址的概念本文引用地址:http://www.eepw.com.cn/article/201611/318060.htm1)物理地址:CPU地址總線傳來的地址,由硬體電路控制其具體含義。物理地址中很大一部分是留給內存條中的內存的,但也常被映射到其他存儲器上(如顯存、BIOS等)。
  • 在MCS51單片機中對特殊功能寄存器的C51定義
    MCS-51單片機中,除了程序計數器PC和4組工作寄存器組外,其它所有的寄存器均為特殊功能寄存器(SPR),分散在片內RAM區的高128位元組中,地址範圍為80H~0FFH。,是特殊功能寄存器「sfr-name」的字節地址,這個常數值的範圍必須在SFR地址範圍內,位於0x80~0xFF。