i have the memory address of certain register(the address 开发者_JS百科LCDCW1 is C000).
c codes:
#define LCDCW1 0xC000
*LCDCW1=0x31;
i just want to write data to this register. The codes have problems, how to correct it?
thx!
You can, as others have suggested, declare an appropriate pointer, ie,
volatile uint32_t *reg = (volatile uint32_t *)0xc000;
Note that I've added the volatile
qualifier. This is always a good idea when reading or writing hardware registers, because it ensures that each access you perform in your C code actually shows up in the generated code.
However, I usually prefer to write macros like this
#define READ_LCDCW1() ...
#define WRITE_LCDCW1(value) ...
and then fill these in with the appropriate gcc asms. I like these better than direct use of pointers because:
- I think they read better in the code, identifying what I'm doing, reading a register, instead of focusing on how I'm doing it.
- Some registers require a multi-step process to read from the hardware. This is hidden easily in macros of this style, and the bulk of my code still refers to the registers I'm interested in, not the complicated way the hardware makes me touch them.
- Finally, by using
asm
s, I know exactly how I'm accessing the register. Sometimes there are special instructions or address spaces needed to get to a register, which usually can't be generated by the C compiler. - Even if you disagree with the motivation for using asm statements, I'd still suggest wrapping your register accesses in macros (or inline functions) like these.
In your case, the simplest definitions should be:
#define LCDCW1_ADDR 0xc000
#define READ_LCDCW1() (*(volatile uint32_t *)LCDCW1_ADDR)
#define WRITE_LCDCW1(val) ((*(volatile uint32_t *)LCDCW1_ADDR) = (val))
I believe one word of caution about the use the keyword volatile is in order.
Sometimes (often) what the compiler thinks volatile means is not what the programmer intended (and vice versa). It is good practice to always check the resulting machine code when the volatile keyword is used, in order to avoid surprises.
For further references, see e.g. http://www.cs.utah.edu/~regehr/papers/emsoft08-preprint.pdf
LCDCW1
is just an integer value. You can not do *
on that. You need to cast it to integer (or type you require) pointer and then use it. For example:
*(int*)LCDCW1=0x31;
Assuming that register has the same size as a long
:
volatile long * ldccw1 = (long*)0xc000;
*lcdcw1 = myValue;
I don't know what LCDCW1 means, but to write to a constant address:
*(int*)0xC000 = 42;
Adjust to suit (your register may not be int-sized).
精彩评论