2011-04-15 97 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++访问硬件,您需要知道编译器如何处理这样的事情,并确保您认真对编译器说谎。

相关问题