位域結構體詳細解析

2021-05-27 12:58:37 字數 2395 閱讀 2143

這一節,我們針對大家提出的有關定義暫存器結構體的問題進行解析。在nios ii軟體開發過程中,如果使用我們提出的暫存器操作方式的話,首先需要定義乙個暫存器結構體,之所以這樣做是為了在軟體書寫過程中操作方便,更是為了增強程式的可讀性。我們就拿uart來舉例說明。

首先,我們看一下uart的暫存器說明,如下表所示

我們通過上表可以看到,uart包括6個暫存器(由於最後乙個暫存器一般不用,所以建立的結構體中沒有加入它),假設基位址為0x00的話,那麼他們的位址分別為0x00,0x01,0x02,0x03,0x04,0x05。也就是說,各個暫存器之間是存在順序的。那麼,在我們建立結構體過程中也要注意他們的順序問題。建立的結構體如下所示

typedef struct bits;

volatile unsigned long int word;

} rxdata;

union bits;

volatile unsigned long int word;

} txdata;

union bits;

volatile unsigned long int word;

} status;

union bits;

volatile unsigned long int word;

} control;

union bits;

volatile unsigned long int word;

} divisor;

}uart_str;

對於這樣乙個大的結構體,我們來逐層分析一下:

第一, 整個結構體由5個共用體組成,共同體的順序是由暫存器的偏移量決定的,這一點前面已經有所敘述。

第二, 每個共用體由乙個結構體和乙個volatile unsigned long int型的變數組成。

第三, 共用體中的結構體由位域構成,位域中的內容也是存在順序的,這個順序是由暫存器的結構決定,而且是由低到高排列。其中,nc表示該位為空位或保留,不能對其進行操作。

1. 為什麼裡面的變數都定義成unsigned long int

首先需要說明一點,在nios ii中,unsigned long int是32位,跟unsigned int是一樣的,unsigned long long int才是64位的。

有人會問,在暫存器的**中,暫存器的位數是0到15的,也就是16位,那你為什麼定義成32位的呢?其實,這個問題涉及到了nios ii的位址對齊問題,它是屬於硬體構架的範疇。

當系統中存在資料寬度不匹配的主從埠時就要考慮位址對齊的問題。位址對齊分為兩類,一類是靜態位址對齊,另一類就是動態位址對齊。一般來說儲存器外設使用動態位址對齊,而暫存器外設使用靜態位址對齊,之所以是這樣,是由動態位址對齊和靜態位址對齊的特點決定的,在靜態位址對齊方式下,主端單次傳輸對應從埠的一次傳輸,而在動態位址對齊方式下,乙個主埠讀傳輸,則要引起多次從埠讀傳輸。想要更加具體的了解他們特點的,大家自行查詢吧,我在這裡就不詳細敘述了。

我們要將暫存器定義為unsigned long int型別,就跟這個靜態位址對齊有關係了。現在我們是uart埠16位,而nios ii主埠32位的情況,在這種情況下,nios ii主埠與16位uart埠進行資料傳輸時,只有32位的低16位有效,但是高16位也占用了位址空間,也就是說,uart埠的16位實際上是占用了32位的。假設我們現在的基位址是0x00,那麼6個暫存器他們相對基位址的偏移分別為0x00,0x01,0x02,0x03,0x04,0x05;那麼,從主埠看,這6個暫存器的位址分別為0x00,0x04,0x08,0x0c,0x10,0x14,而不是0x00,0x01,0x02,0x03,0x04,0x05,也不是0x00,0x02,0x06,0x08,0x0a,0xc,這一點大家要特別注意。

2. 為什麼要建立這樣乙個共用體呢,又有位域結構體又有乙個volatile unsigned long intword變數,word有啥用呢?

共用體的特點就是其中的成員占用同乙個儲存空間。也就說,由位域組成的結構體跟word是占用同一儲存空間,而且他們都是volatile unsigned long int型別,那麼,結構體中的每乙個位域成員都對應word的乙個位。當我們需要單獨處理乙個位的時候,我們就可以用位域,如下所示  

rs232->control.bits.irrdy=1;//接收準備好中斷使能

如果我們想要對狀態暫存器整體清零呢,我們就可以用到word了,如下所示  

rs232->status.word=0;//清除狀態暫存器

對於其他的暫存器都是一樣的,在這裡不再重複了。

位結構體和位域

1.位域的定義 有些資訊在儲存時,並不需要占用乙個完整的位元組,而只需佔幾個或乙個二進位制位。例如在存放乙個開關量時,只有0和1 兩種狀態,用一位二進位即可。為了節省儲存空間,並使處理簡便,c語言又提供了一種資料結構,稱為 位域 或 位段 所謂 位域 是把乙個位元組中的二進位劃分為幾個不同的區域,並...

結構體和位域

c 陣列允許定義可儲存相同型別資料項的變數,結構是 c 程式設計中另一種使用者自定義的可用的資料型別,它允許您儲存不同型別的資料項。結構用於表示一條記錄,假設您想要跟蹤圖書館中書本的動態,您可能需要跟蹤每本書的下列屬性 為了定義結構,您必須使用struct語句。struct 語句定義了乙個包含多個成...

結構體及位域

結構體 結構體是一種集合,它裡面包含了多個變數或陣列,它們的型別可以相同,也可以不同,每個這樣的變數或陣列都稱為結構體的成員 member 結構體定義 struct st 這個結構體定義了整形變數a,浮點型變數 b,等等 注意 大括號後面的封號不能省略 2,結構體變數 類似於這些整形變數等等 定義結...