2011-04-15 94 views
1

我的問題是如何通過引用一個函數來傳遞位域實例。我已經執行了如下所示,但是當我發送函數DAC_set_gain_code時,處理器會引發中斷錯誤。只要傳遞位域,我所做的是正確的?如何將一個位域(通過引用)傳遞給一個函數?

我創建了一個位域(見下面),它代表了DAC芯片上的一個24位寄存器,我想寫入並存儲在.h文件中。

typedef struct { 
    uint8_t rdwr_u8:  1; 
    uint8_t not_used_u8: 3; 
    uint8_t address_u8:  4; 
    uint8_t reserved_u8: 8; 
    uint8_t data_u8:  8; 
}GAIN_REG_st; 

我有初始化位域,像這樣的函數:

void init(void) 
{ 
    GAIN_REG_st GAIN_x; //Create instance of bitfield 

    //other code here... 

    DAC_set_gain_code(channel_u8, gain_code_i8, &GAIN_x); //Pass address of bitfield 

    return; 
} 

實際上填充位字段的功能如下所示:

void DAC_set_gain_code(uint8_t channel_u8, int8_t gain_code_i8, GAIN_REG_st *GAIN) 
{ 
    /* Populate ZERO_REG_st bitfield */ 
    GAIN->rdwr_u8  = 0; 
    GAIN->not_used_u8 = 0; 

    if(channel_u8==0){ 
     GAIN->address_u8 = GAIN_REGISTER_0; 
    } 
    else if(channel_u8==1){ 
     GAIN->address_u8 = GAIN_REGISTER_1; 
    } 
    else if(channel_u8==2){ 
     GAIN->address_u8 = GAIN_REGISTER_2; 
    } 
    else if(channel_u8==3){ 
     GAIN->address_u8 = GAIN_REGISTER_3; 
    } 

    GAIN->data_u8 = gain_code_i8; 

    return; 
} 

的函數原型hal_DAC_set_gain_code_uni是:

void DAC_set_gain_code(uint8_t channel_u8, int8_t gain_code_i8, GAIN_REG_st *GAIN); 

任何意見讚賞。

謝謝。

+2

您發佈的內容無法編譯,或者您沒有顯示實際使用的內容(函數名稱不匹配,未聲明的變量和/或全局變量未顯示以及未使用的參數) – Mat 2011-04-15 10:25:11

+0

仍然無法執行。 'ZERO'沒有在你發佈的內容中定義,'GAIN'沒有在'DAC_set_gain_code'中使用。 – Mat 2011-04-15 10:34:40

+0

對不起,有關帖子中的錯誤。現在應該與實際代碼相同。我的主要問題是,我是否正確地傳遞了位域的參考? – phil05 2011-04-15 10:42:56

回答

0

難道是一些對齊問題?

也許你可以玩你的編譯器的對齊選項? 或者在最後嘗試用虛擬uint8來填充你的結構?

+0

但是沒有轉換,所以它不能成爲對齊問題 – jeb 2011-04-15 12:12:54

+1

是的,可能會有對齊問題。當涉及到位域時,C允許編譯器完全無法使用並以完全任意的方式對齊。除非您深入閱讀編譯器後端文檔,否則無法知道位域是如何對齊的,或者中間是否有填充位/字節。還有endianess,位順序等等:無數未指定或實現定義的行爲。最好的解決方案是根本不使用位字段。 – Lundin 2011-04-15 23:31:25

+0

當我創建一個位域實例'GAIN_REG_st GAIN_x'並且通過引用傳遞'GAIN_x'時,是不是我只是將一個指針傳遞給位域?因此,我不會在內存中激活位域,因此不會是問題。 – phil05 2011-04-16 10:51:56

2

由於真正使用此代碼是寫一個硬件寄存器,比如填充和領域的定位/排序問題DOES問題。我懷疑編譯器使用32位整數,並且這個結構被填充到32位,但在被調試的實際代碼中,GAIN_X不是局部變量,而是傳遞0xNNNNNNN(或等價的) - 地址不在「右邊界」(很可能,因爲它是一個24位寄存器)。編譯器會假定你傳遞的是一個指向真正的GAIN_REG_st的指針,而不是一個類型打頭的地址,所以可能會做出關於對齊的假設。

要直接從C/C++訪問硬件,您需要知道編譯器如何處理這樣的事情,並確保您認真對編譯器說謊。

相關問題