Как интерпретировать следующий C (включает битовые поля и структуру) - PullRequest
2 голосов
/ 29 февраля 2012

Следующий код взят из заголовочного файла микроконтроллера PIC, но я предполагаю, что это просто старый C. Я понимаю, что код должен использоваться для доступа к отдельным битам по адресу в памяти, но как новичок на C, я быкак некоторая помощь в понимании того, что здесь происходит, и как я буду использовать это в своем коде для установки или получения битов из ADCON1. ​​

volatile unsigned char           ADCON1              @ 0x09F;

volatile bit VCFG0               @ ((unsigned)&ADCON1*8)+4;
volatile bit VCFG1               @ ((unsigned)&ADCON1*8)+5;
volatile bit ADFM                @ ((unsigned)&ADCON1*8)+7;

volatile union {
    struct {
        unsigned                        : 4;
        unsigned    VCFG0               : 1;
        unsigned    VCFG1               : 1;
        unsigned    : 1;
        unsigned    ADFM                : 1;
    };
} ADCON1bits @ 0x09F;

с тегами C и C ++.Дайте мне знать, если это не C ++ совместимый код, и я удалю тег

Ответы [ 2 ]

3 голосов
/ 29 февраля 2012
volatile unsigned char ADCON1 @ 0x09F;

Это просто объявляет переменную ADCON1.volatile означает, что доступ не должен быть оптимизирован, потому что содержимое переменной может измениться во время выполнения.(т.е. аппаратное обеспечение обновляет значение.)

Я предполагаю, что синтаксис @ является нестандартным C;Я никогда не видел это раньше.Но я полагаю, это означает, что значение должно быть найдено по смещению 0x09F.

volatile bit VCFG0 @ ((unsigned)&ADCON1*8)+4;
volatile bit VCFG1 @ ((unsigned)&ADCON1*8)+5;
volatile bit ADFM  @ ((unsigned)&ADCON1*8)+7;

Они снова объявляют переменные.Насколько я знаю, тип bit также не является стандартным C, но должен быть понятен.

Синтаксис @ снова используется здесь для объявления местоположения, но интересно то, чтоочевидно, смещение выражено в приращениях типа, потому что адрес ADCON1 умножается на 8. (A char в 8 раз больше размера bit.)

Это почти так же, как выиндексировать массив или делать арифметику указателей на обычном C, например: char foo[4] - это массив размером 4 байта, а int bar[4] - это массив размером 32 байта.За исключением этого случая, ваш «массив» - это все адресное пространство процессора.

Таким образом, в основном, эти переменные представляют конкретные биты ADCON1, взяв символ-адрес (&ADCON1), преобразовав егобитовый адрес (*8), затем адрес конкретного бита (+4).

volatile union {
    struct {
        unsigned          : 4;
        unsigned    VCFG0 : 1;
        unsigned    VCFG1 : 1;
        unsigned          : 1;
        unsigned    ADFM  : 1;
    };
} ADCON1bits @ 0x09F;

Это объявление не зависит от вышеизложенного, но достигает примерно того же.

Объявляется объединение одной структуры, а переменная этого типа объявляется со смещением 0x09F.Синтаксис :4, который вы видите в структуре, указывает размер элемента в битах.Безымянные члены структуры просто недоступны.

Объединение, похоже, ничего не добавляет.Вы получите доступ к битам как ADCON1bits.VCFG0.

1 голос
/ 29 февраля 2012

Предположительно, есть регистр байтов в 0x09F, который управляет АЦП, «бит» - это логический тип, к которому можно обращаться как к битовому массиву, начинающемуся с 0 (отсюда * 8), поэтому к АЦП обращаются, например. 'ADFM = 0'.

Объединение является альтернативным средством доступа к регистру управления АЦП с использованием битовых полей (например, ADCON1bits.VCFG1 = 1).

Вся партия на самом деле не стандартная C или C ++ - это 'microController C'

...