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);

任何建议表示赞赏。

谢谢。

4

2 回答 2

3

由于此代码的实际用途是写入硬件寄存器,因此字段的填充和对齐/排序等问题确实很重要。

我怀疑编译器使用的是 32 位整数,并且这个结构被填充到 32 位,但是在被调试的实际代码中,GAIN_X 不是本地变量,你传递的是 0xNNNNNNN (或等效) - 和地址不在“正确”边界上(很可能,因为它是一个 24 位寄存器)。编译器将假定您传递的是指向真正 GAIN_REG_st 的指针,而不是类型双关地址,因此可能已经对对齐做出了假设。

要直接从 C/C++ 访问硬件,您需要知道编译器如何处理此类事情,并确保您小心地对编译器撒谎。

于 2011-04-25T19:01:16.023 回答
0

会不会是对齐问题?

也许您可以使用编译器的对齐选项?或者尝试在最后用一个假人填充你的结构uint8

于 2011-04-15T12:06:33.603 回答