2012-02-29 6 views
2

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

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++ совместимый код, и я удалить тег

+1

Определение '@' и 'bit' отсутствует. – hirschhornsalz

+2

Это не простой старый C или простой старый C++. Символа '@' нет (кроме строк). Это, вероятно, специфическая для вендора. Вам необходимо проконсультироваться с документацией компилятора. Я предполагаю, что он указывает абсолютный адрес переменной, но не цитируйте меня на этом. –

ответ

3
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 также не является стандартным, но должен быть понятным.

Синтаксис @ снова используется здесь, чтобы объявить о месте, но самое интересное в том, что, видимо, смещение в типовых приращений, так как адрес ADCON1 умножается на 8. (A раз размер . 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, который вы видите в структуре, указывает бит размера члена. Элементы Nameless-структуры просто недоступны.

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

+0

Благодарим за всесторонний ответ, особенно за обращение битовых полей, связанных с типом. Для меня это странное понятие. Прояснение того, что два блока кода не связаны, было неожиданностью, но сейчас имеет смысл. –

1

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

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

Вся серия не очень стандартный C или C++ - это «C» микроконтроллером

+0

Концепция битового массива была самой странной для меня. Теперь это имеет смысл, но, независимо от того, я теперь могу его использовать! –