写数据到寄存器

时间:2010-04-16 09:44:27

标签: c pointers embedded hardware

我有某个寄存器的存储器地址(地址LCDCW1是C000)。

c代码:

#define LCDCW1 0xC000

*LCDCW1=0x31;

我只想将数据写入此寄存器。代码有问题,如何纠正?

THX!

5 个答案:

答案 0 :(得分:18)

您可以像其他人所建议的那样,声明一个合适的指针,即

volatile uint32_t *reg = (volatile uint32_t *)0xc000;

请注意,我添加了volatile限定符。在读取或写入硬件寄存器时,这总是一个好主意,因为它确保您在C代码中执行的每次访问实际上都显示在生成的代码中。

但是,我通常喜欢写这样的宏

#define READ_LCDCW1() ...
#define WRITE_LCDCW1(value) ...

然后使用适当的gcc asms填充这些内容。我喜欢这些比直接使用指针更好,因为:

  • 我认为他们在代码中读得更好,识别我在做什么,阅读一个寄存器,而不是专注于我是如何做的。
  • 某些寄存器需要多步骤才能从硬件中读取数据。这很容易隐藏在这种风格的宏中,我的大部分代码仍然是指我感兴趣的寄存器,而不是硬件让我触摸它们的复杂方式。
  • 最后,通过使用asm,我确切地知道我是如何访问寄存器的。有时需要特殊指令或地址空间才能到达寄存器,这通常不能由C编译器生成。
  • 即使你不同意使用asm语句的动机,我仍然建议将你的寄存器访问包装在这些宏(或内联函数)中。

在您的情况下,最简单的定义应该是:

#define LCDCW1_ADDR       0xc000
#define READ_LCDCW1()     (*(volatile uint32_t *)LCDCW1_ADDR)
#define WRITE_LCDCW1(val) ((*(volatile uint32_t *)LCDCW1_ADDR) = (val))

答案 1 :(得分:4)

我相信关于使用关键字volatile的一个警告是有序的。

有时(经常)编译器认为易失性的意思不是程序员想要的(反之亦然)。最好在使用volatile关键字时始终检查生成的机器代码,以避免出现意外。

有关详细参考,请参阅例如http://www.cs.utah.edu/~regehr/papers/emsoft08-preprint.pdf

答案 2 :(得分:1)

假设寄存器的大小与long相同:

volatile long * ldccw1 = (long*)0xc000;

*lcdcw1 = myValue;

答案 3 :(得分:1)

LCDCW1只是一个整数值。你无法做到*。您需要将其转换为整数(或您需要的类型)指针,然后使用它。例如: *(int*)LCDCW1=0x31;

答案 4 :(得分:0)

我不知道LCDCW1是什么意思,而是写入一个恒定地址:

*(int*)0xC000 = 42;

调整以适合(您的寄存器可能不是整数)。