Домашняя страница библиотеки_c AVR

Синтаксис языка C

Библиотека языка C GNU glibc

Страницы развития библиотеки_с AVR

Главная страница

Инструкция пользователя

Содержание библиотеки_c

Часто задаваемые вопросы

Содержание по алфавиту

Демонстрационные проекты


<avr/sfr_defs.h>: Работа с битами

Детальное Описание

При работе с микроконтроллерами, многие задачи сводятся к управлению периферийными устройствами, для этого необходимо управлять устройствами, содержащимися в микроконтроллере (теми, которые связываются с периферийными устройствами). В AVR Libc поддержаны два варианта решения этой задачи:

Можно получить доступ к регистру ввода / вывода с помощью функций, подобных outb():

 #include <avr/io.h>
 outb(PORTA, 0x33);

или присвоить какое либо значение символьному обозначению регистра ввода / вывода.

 PORTA = 0x33;

Какой метод компилятора использовать, решает программист. Но, например, если он напишет

 PORTA |= 0x40;

компилятор может оптимизировать это в использование sbi инструкции.

Например, следующие два утверждения эквивалентны:

 outb(DDRD, inb(DDRD) & ~LCDBITS);
 DDRD &= ~LCDBITS;

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

Обратите внимание, что особая осторожность должна быть предпринята при работе с некоторым регистрами ввода / вывода 16-битных таймеров, где возможен доступ и из главной программы и в подпрограмме обслуживания прерывания. См. Почему некоторые 16-и разрядные регистры таймеров иногда громятся?

В новых версиях компилятора инструкции манипуляций с битами - sbi/cbi больше не поддерживаются.

 

Теперь sbi (sfr,bit) следует заменять на sfr |= _BV(bit), а cbi (sfr,bit) - на sfr &= ~(_BV(bit));

Например, вместо: sbi(PORTB, PB1); принято писать: PORTB |= _BV(PB1);

Управление битами

#define 

_BV(bit)   (1 << (bit))

 

Макроопредеения управления битами регистров ввода/вывода

#define 

bit_is_set(sfr, bit)   (_SFR_BYTE(sfr) & _BV(bit))

#define 

bit_is_clear(sfr, bit)   (!(_SFR_BYTE(sfr) & _BV(bit)))

#define 

loop_until_bit_is_set(sfr, bit)   do { } while (bit_is_clear(sfr, bit))

#define 

loop_until_bit_is_clear(sfr, bit)   do { } while (bit_is_set(sfr, bit))


Документация макроопределений.

#define _BV

(

bit 

 

 ) 

   (1 << (bit))

#include <avr/io.h>

Конвертирует номер разряда в байтовое значение.

Примечание: Изменение бита выполняется компилятором, затем результат вставляется в код. Таким образом, время на выполнение _BV() не расходуется.

Примеры использования:

TCCR1A = _BV(PWM10) | _BV(PWM11) | _BV(XCOM11); // Устанавливаем 10-разрядную, не инвертирующую ШИМ,

TIMSK = _BV(TOIE1); // Устанавливаем флаг разрешения прерываний от Т/С1

PORTA &= ~(_BV(PA7)); // Сбрасываем в 0 разряд 7 порта A

#define bit_is_clear

(

sfr,

 

 

 

bit 

 

 ) 

   (!(_SFR_BYTE(sfr) & _BV(bit)))

#include <avr/io.h>

Проверяет, содержит ли разряд bit в регистре ввода/вывода sfr лог. 0. Если да, то возвращается результат отличный от нуля, если указанный разряд содержит лог.1, то возвращается 0.

#define bit_is_set

(

sfr,

 

 

 

bit 

 

 ) 

   (_SFR_BYTE(sfr) & _BV(bit))

#include <avr/io.h>

Проверяет, содержит ли разряд bit в регистре ввода/вывода sfr лог. 1. Если да, то возвращается результат отличный от нуля, если указанный разряд содержит лог.0, то возвращается 0.

#define loop_until_bit_is_clear

(

sfr,

 

 

 

bit 

 

 ) 

   do { } while (bit_is_set(sfr, bit))

#include <avr/io.h>

Ожидает до тех пор, пока bit в регистре sfr содержит лог.1.

#define loop_until_bit_is_set

(

sfr,

 

 

 

bit 

 

 ) 

   do { } while (bit_is_clear(sfr, bit))

#include <avr/io.h>

Ожидает до тех пор, пока bit в регистре sfr содержит лог.0.

Hosted by uCoz