Вы можете, как и другие предложили, объявить соответствующий указатель, т.е.
volatile uint32_t *reg = (volatile uint32_t *)0xc000;
Обратите внимание, что я добавил volatile
. Это всегда хорошая идея при чтении или записи аппаратных регистров, поскольку она гарантирует, что каждый доступ, который вы выполняете в коде C, действительно отображается в сгенерированном коде.
Однако, я обычно предпочитаю писать макросы, как этот
#define READ_LCDCW1() ...
#define WRITE_LCDCW1(value) ...
, а затем заполнить их с использованием соответствующих Gcc ПКР. Мне это нравится лучше, чем прямое использование указателей, потому что:
- Я думаю, что они лучше читают в коде, идентифицируя, что я делаю, читая регистр, вместо того, чтобы сосредоточиться на том, как я это делаю.
- Некоторые регистры требуют многостадийного процесса для чтения с аппаратного обеспечения. Это легко скрывается в макросах этого стиля, и основная часть моего кода по-прежнему относится к регистрам, которые меня интересуют, а не к сложному способу, с помощью которого аппаратное обеспечение меня трогает.
- Наконец, используя
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))
какой компилятор/платформа? – Andrey
@Andrey: 8051, компилятор: ICC8051 – martin
Код as is не компилируется, потому что '0xc000' не является указателем, а для оператора' * 'требуется операнд указателя. –