C語言訪問MCU暫存器

2021-10-04 07:04:51 字數 1892 閱讀 1512

問題由來:

//下面這行**的意思是直接操作0x020c4068這個暫存器

//具體暫存器的作用是通過手冊得到的

#define ccm_ccgr0 *((volatile unsigned int*)0x020c4068)

//假設暫存器為32位

//要設定0x020c4068暫存器值為0x03,可以直接寫成

ccm_ccgr0=0x03

為什麼這個巨集定義可以直接操作這個位址??

將上述**拆解來看

1. 第一步

(unsigned int*)0x020c4068

//表示將0x020c4068強制轉換為unsigned int 型別的指標

//0x020c4068代表乙個16進製制的資料

2. 第二步

(volatile unsigned int*)0x020c4068

//由於記憶體訪問速度遠不及cpu處理速度,為提高機器整體效能,在硬體上引入硬體快取記憶體cache,加速對記憶體的訪問。

//當要求使用volatile宣告變數值的時候,系統總是重新從它所在的記憶體讀取資料,即使它前面的指令剛剛從該處讀取過資料。

//精確地說就是,遇到這個關鍵字宣告的變數,編譯器對訪問該變數的**就不再進行優化,從而可以提供對特殊位址的穩定訪問;

//如果不使用valatile,則編譯器將對所宣告的語句進行優化。

//用volatile定義的變數會在程式外被改變,每次都必須從記憶體中讀取,而不能重複使用放在cache或暫存器中的備份

//注意:頻繁地使用volatile很可能會增加**尺寸和降低效能,因此要合理的使用volatile。

//反例:

#define rurxh0 (*(unsigned char *)0x50000024) //uart 0 receive buffer

//這個就是序列的接收buffer,其位址為0x50000024。

//如果我們沒有將這個位址強行轉換成volatile,那麼我們在使用rurxh0時,可能直接從cpu的暫存器中取值。

//因為之前rurxh0被訪問過,也就是說之前就從記憶體中取出rurxh0的值儲存到某個暫存器中。

//之所以直接從暫存器中取值,而不去記憶體中取值,是因為編譯器優化**的結果(訪問cpu暫存器比訪問ram快的多)。

//用volatile關鍵字對0x50000024進行強制轉換,使得每一次被訪問rurxh0時,執行部件都會從0x50000024這個記憶體單元中取出值來賦值給rurxh0。

volatile用法參考鏈結1

volatile用法參考鏈結2

3.第三步

*((volatile unsigned int*)0x020c4068)

代表對 0x020c4068 這個位址進行解引用,相當於給這個位址賦值

加上巨集定義以後

*((volatile unsigned int*)0x020c4068) = 0x03 相當於 ccm_ccgr0 = 0x03

注意

#define ccm_ccgr0 *((volatile unsigned char*)0x020c4068)

#define ccm_ccgr0 *((volatile unsigned int*)0x020c4068)

#define ccm_ccgr0 *((volatile unsigned short*)0x020c4068)

三種寫法沒有區別,因為指標型別變數所占用的空間大小都與系統的定址能力有關

指標變數占用空間參考鏈結

mysql 訪問暫存器 暫存器 記憶體訪問

一 ds和 address cpu要讀寫乙個記憶體單元的時候,必須先給出這個記憶體單元的位址,在8086pc中記憶體位址有段位址和偏移位址組成。ds 資料暫存器 中通常存放要訪問資料的段位址。比如要讀取1000h單元的內容,可以用下面這段 mov bx,1000h mov ds,bx mov al,...

暫存器(記憶體訪問)

1 記憶體中字的儲存 高位址儲存高位,低位址儲存地位。任何兩個位址連續的記憶體單元,n號單元和n 1號單元,可以將它們看成兩個記憶體單元,也可以看成乙個位址為n的字單元中的高位位元組單元和地位位元組單元。2 ds和 adress cpu要讀取乙個記憶體單元的時候,必須先給出這個記憶體單元的位址。在8...

暫存器(記憶體訪問)

記憶體中字的儲存 ds和 address mov ax,1000h mov ds,axmov add的更多用法 指令描述 mov 暫存器,偏移位址 將位址為ds 偏移位址中的資料送入暫存器 mov 偏移位址 暫存器 將暫存器中的值送入ds 偏移位址 add 暫存器,偏移位址 將指定位址中的值加入暫存...