у меня есть адрес памяти определенного регистра (адрес, LCDCW1 является C000).
c коды:
#define LCDCW1 0xC000
*LCDCW1=0x31;
я просто хочу записать данные в этот регистр. Коды имеют проблемы, как исправить его?
Спасибо!
Вы можете, как предлагали другие, объявить соответствующий указатель, например,
volatile uint32_t *reg = (volatile uint32_t *)0xc000;
Обратите внимание, что я добавил квалификатор volatile
. Это всегда хорошая идея при чтении или записи аппаратных регистров, потому что это гарантирует, что каждый доступ, который вы выполняете в своем коде C, действительно отображается в сгенерированном коде.
Однако я обычно предпочитаю писать такие макросы
#define READ_LCDCW1() ...
#define WRITE_LCDCW1(value) ...
, а затем заполнять их соответствующими командами gcc. Мне это нравится больше, чем прямое использование указателей, потому что:
asm
s, я точно знаю, как я получаю доступ к регистру. Иногда для доступа к регистру требуются специальные инструкции или адресные пространства, которые обычно не могут быть сгенерированы компилятором C. В вашем случае простейшие определения должны быть такими:
#define LCDCW1_ADDR 0xc000
#define READ_LCDCW1() (*(volatile uint32_t *)LCDCW1_ADDR)
#define WRITE_LCDCW1(val) ((*(volatile uint32_t *)LCDCW1_ADDR) = (val))
Предполагая, что регистр имеет тот же размер, что и long
:
volatile long * ldccw1 = (long*)0xc000;
*lcdcw1 = myValue;
Я не знаю, что означает LCDCW1, но для записи на постоянный адрес:
*(int*)0xC000 = 42;
Отрегулируйте по своему усмотрению (ваш регистр может не иметь размер int ).
Я считаю, что следует сделать одно предостережение относительно использования ключевого слова volatile.
Иногда (часто) компилятор считает, что volatile означает не то, что задумал программист (и наоборот). Рекомендуется всегда проверять результирующий машинный код при использовании ключевого слова volatile, чтобы избежать сюрпризов.
Дополнительные ссылки см., Например, http://www.cs.utah.edu/~regehr/papers/emsoft08-preprint.pdf
LCDCW1
- это просто целое число. Вы не можете сделать *
на этом. Вам нужно преобразовать его в целочисленный (или требуемый тип) указатель, а затем использовать его. Например:
* (int *) LCDCW1 = 0x31;