В интернете существует множество примеров кода для AVR-GCC, написанного с использованием функций и макросов, которые больше не поддерживаются в новых версиях компилятора. Чтобы использовать эти примеры и понять с помощью них суть работы с портами микроконтроллера, необходимо переписывать код или использовать специальные макроопределения.
Для начинающих осваивать программирование микроконтроллеров AVR такой подход может оказаться сложным. В результате многие переходят на другие компиляторы и больше никогда не используют ставшую для многих культовой среду разработки WinAVR. Хотя существует простой способ решить все проблемы и вновь вернуть отвергнутые разработчиками функции в AVR-GCC. Для этого можно использовать специально созданный патч [1].
Прежде чем мы перейдем к описанию патча, рассмотрим, какие же функции он возвращает. В последних версиях библиотеки avr-libc, входящей в состав компилятора AVR-GCC, использующегося в WinAVR, больше не поддерживаются функции inp, outp, sbi и cbi. Сделано это для оптимальной интерпретации исходного текста программы при ее компиляции и определения, как обращаться к порту - как к регистру или как к ячейке памяти.
Поддержка этих функций отсутствует уже начиная с версии WinAVR-20050214. В том числе отсутствует поддержка столь популярных и бывших для многих удобными bit_is_set и bit_is_clear. Эти функции можно встретить во множестве примеров программ для начинающих, в том числе в популярном проекте сайта "РобоКлуб" под названием "Делаем робота вместе".
Конечно же, никто не призывает пользоваться исключительно "старыми" функциями, патч предназначен вернуть обратную совместимость программам на AVR-GCC. Используя патч, вы не лишаетесь возможности работы с новой нотацией, а только возвращаете возможность использования исключенных функций. Например, проверив в работе какой-либо из найденных в интернете примеров, можно потренироваться, переписав его с использованием нового синтаксиса.
В заключение рассмотрим несколько примеров возможных замен.
"старая" нотация |
возможная замена |
выполняемое действие |
outp(0xff,DDRB); |
DDRB = 0xff; |
все выводы порта B сконфигурировать как выходы |
outp(0xff,PORTB); |
PORTB = 0xff; |
во всех битах порта B установить "1" |
sbi(DDRB, DDB2); |
DDRB |= 1 << 2; |
сконфигурировать линию 2 порта В как выход |
cbi(DDRB, DDB2); |
DDRB &= ~(1 << 2); |
сконфигурировать линию 2 порта В как вход |
sbi(PORTB,PB2); |
PORTB |= _BV(PB2); или просто PORTB |= 1 << 2; возможно и так PORTB |= 1 << PINB2; |
установить "1" на линии 2 порта В |
cbi(PORTB,PB2); |
PORTB &= ~_BV(PB2); или просто PORTB &= ~(1 << 2); возможно и так PORTB &= ~1 << PINB2; |
установить "0" на линии 2 порта В |
if (bit_is_set(PIND,3)) { ... } |
if (PIND & (1 << PIND3)) { ... } |
проверить "1" на линии 3 порта D |
if (bit_is_clear(PIND,3)) { ... } |
if (!(PIND & (1 << PIND3))) { ... } |
проверить "0" на линии 3 порта D |
Обратите внимание: использование _BV() более предпочтительно, так как в этом случае компилятор сам выполняет поразрядный сдвиг и вставляет результат в компилируемый код. Это обеспечивает отсутствие затрат времени во время непосредственного выполнения кода в микроконтроллере.
Как вы видите, возможности синтаксиса в AVR-GCC достаточно широки, чтобы считать его одним из самых удобных и гибких средств программирования микроконтроллеров Atmel AVR.
[Ссылки]
1. myROBOT AVR-GCC PATCH for WinAVR site:myrobot.ru. 2. AVR-GCC :: СОВМЕСТИМОСТЬ КОДА site:myrobot.ru - оригинал статьи. |
Комментарии
#define bit_is_set(sfr, bit) (_SFR_BYTE(sfr) & _BV(bit)). По сути эта реализация тоже самое, что вы предлагаете в вашей таблице.
RSS лента комментариев этой записи