如何将内存地址声明为函数的参数?

时间:2013-09-24 13:13:23

标签: c

假设我在内存中映射了两个地址:

#define MY_REGISTER_1 (*(volatile uint8_t *)(0x1B))
#define MY_REGISTER_2 (*(volatile uint8_t *)(0x18))

我想创建一个在一个寄存器中设置一个位的函数,如下所示:

set_bit_low(MY_REGISTER_1, 3);

声明我的功能是否正确?

void set_bit_low(uint8_t, uint8_t);

5 个答案:

答案 0 :(得分:2)

让我们从您的定义开始:

#define MY_REGISTER_1 (*(volatile uint8_t *)(0x1B))

取消引用地址0x1b处的八位字节,因此它表示内存映射寄存器的内容,而不是其位置。最好有一个带寄存器位置的宏:

#define REGISTER_1 ((volatile uint8_t *) (0x1B)) /* Substitute _1 for some meaningful name */

然后您可以随意取消引用,您可以按如下方式声明您的功能:

void set_bit_low(volatile uint8_t *register, uint8_t bitpos);

/* Use like this: */
set_bit_low(REGISTER_1, 3);

答案 1 :(得分:1)

以下应该是声明你的功能的正确方法:

void set_bit_low(uint8_t *, uint8_t);

答案 2 :(得分:1)

没有。您想要更改内存位置的内容。所以,你必须把它作为指针传递。

函数标题应该是

void set_bit_low(uint8_t *, uint8_t);

功能如

void set_bit_low(uint8_t *my_reg, uint8_t bit_location)
{
   // do your bit manupulation here by assigning to *my_reg.
}

答案 3 :(得分:0)

此:

#define MY_REGISTER_1 (*(volatile uint8_t *)(0x1B))

在(mem映射)寄存器中产生值的副本。所以这个:

set_bit_low(MY_REGISTER_1, 3);

将该副本传递给set_bit_low()。然后,您可以在副本中设置(这将是函数的本地位)。如果要在寄存器中设置值的位,则必须传递地址本身:

#define MY_REGISTER_1_ADDR 0x1b

有意义吗?

答案 4 :(得分:0)

许多答案已经提到过,将MY_REGISTER_1的定义方式传递给函数会导致发送它的副本。但是,微控制器中经常使用的实际解决方案与其他答案所暗示的不同。

通常,寄存器按照你定义它们的方式定义,即

#define MY_REGISTER_1 (*(volatile uint8_t *)(0x1B))
#define MY_REGISTER_2 (*(volatile uint8_t *)(0x18))

没问题。但是,如果您希望通过该功能更改它们,则应注意不要将它们传递给函数。对这些寄存器执行位操作的最干净方法是通过宏。例如:

#define SET_BIT_LOW(reg, n) (reg) &= (uint8_t)~(1 << (n))
#define SET_BIT_HIGH(reg, n) (reg) |= (uint8_t)(1 << (n))

这不仅可以正确操作实际的寄存器,还可以避免函数调用。如果这些是函数,n将不会被知道,因此转换而不是操作必须以任何方式进行以及(相对)昂贵的函数调用。对于宏,如果n是常量,编译器可能已经计算了右侧表达式,并用1或2条指令替换该行。