запишите данные для регистрации

у меня есть адрес памяти определенного регистра (адрес, LCDCW1 является C000).

c коды:

#define LCDCW1 0xC000

*LCDCW1=0x31;

я просто хочу записать данные в этот регистр. Коды имеют проблемы, как исправить его?

Спасибо!

8
задан Dale Hagglund 17 April 2010 в 14:21
поделиться

5 ответов

Вы можете, как предлагали другие, объявить соответствующий указатель, например,

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

Обратите внимание, что я добавил квалификатор volatile . Это всегда хорошая идея при чтении или записи аппаратных регистров, потому что это гарантирует, что каждый доступ, который вы выполняете в своем коде C, действительно отображается в сгенерированном коде.

Однако я обычно предпочитаю писать такие макросы

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

, а затем заполнять их соответствующими командами gcc. Мне это нравится больше, чем прямое использование указателей, потому что:

  • Я думаю, что они лучше читают код, идентифицируя то, что я делаю, читая регистр, вместо того, чтобы сосредоточиться на том, как я это делаю.
  • Некоторые регистры требуют многоэтапного процесса чтения из оборудования. Это легко скрывается в макросах этого стиля, и большая часть моего кода по-прежнему относится к регистрам, которые меня интересуют, а не к сложному способу, которым оборудование заставляет меня трогать их.
  • Наконец, используя asm s, я точно знаю, как я получаю доступ к регистру. Иногда для доступа к регистру требуются специальные инструкции или адресные пространства, которые обычно не могут быть сгенерированы компилятором C.
  • Даже если вы не согласны с мотивацией использования операторов asm, я все же предлагаю обернуть доступ к регистрам в макросах (или встроенных функциях), подобных этим.

В вашем случае простейшие определения должны быть такими:

#define LCDCW1_ADDR       0xc000
#define READ_LCDCW1()     (*(volatile uint32_t *)LCDCW1_ADDR)
#define WRITE_LCDCW1(val) ((*(volatile uint32_t *)LCDCW1_ADDR) = (val))
19
ответ дан 5 December 2019 в 06:37
поделиться

Предполагая, что регистр имеет тот же размер, что и long :

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

*lcdcw1 = myValue;
1
ответ дан 5 December 2019 в 06:37
поделиться

Я не знаю, что означает LCDCW1, но для записи на постоянный адрес:

*(int*)0xC000 = 42;

Отрегулируйте по своему усмотрению (ваш регистр может не иметь размер int ).

0
ответ дан 5 December 2019 в 06:37
поделиться

Я считаю, что следует сделать одно предостережение относительно использования ключевого слова volatile.

Иногда (часто) компилятор считает, что volatile означает не то, что задумал программист (и наоборот). Рекомендуется всегда проверять результирующий машинный код при использовании ключевого слова volatile, чтобы избежать сюрпризов.

Дополнительные ссылки см., Например, http://www.cs.utah.edu/~regehr/papers/emsoft08-preprint.pdf

4
ответ дан 5 December 2019 в 06:37
поделиться

LCDCW1 - это просто целое число. Вы не можете сделать * на этом. Вам нужно преобразовать его в целочисленный (или требуемый тип) указатель, а затем использовать его. Например: * (int *) LCDCW1 = 0x31;

1
ответ дан 5 December 2019 в 06:37
поделиться
Другие вопросы по тегам:

Похожие вопросы: