code:code

CODE

Сводная страница по программированию

Raspberry Pi

Среда программирования для php Создание exe Программ из php кода http://develstudio.ru

COM TERMINAL

Самая лучшая программа COM терминала https://sites.google.com/site/terminalbpp/

Атмел и Ардуино

Все порты AVR (под AVR обычно подразумеваются микроконтроллеры популярных серий megaAVR и tinyAVR компании Atmel, например ATmega32A, примененный в макетной плате AVR-USB-MEGA16) обладают функционалом чтение-модификация-запись (read-modify-write) при работе с выводами микроконтроллера как обычными портами ввода вывода (general purpose I/O ports, GPIO). При этом можно поменять направление (задать что это - вход или выход) для каждой отдельной ножки GPIO (вывода порта AVR). Каждая ножка также имеет симметричный выходной буфер (два CMOS-ключа, один на +, другой на -), который может выдавать выходной ток от плюса питания (VCC, обычно +5V, drive source), или от земли (GND, минус источника питания, sink source). Мощность выходного драйвера более чем достаточна для прямого управления светодиодом (LED). Также для всех выводов портов, настроенных как вход, можно селективно подключить внутренний верхний нагрузочный резистор (pull-up), встроенный прямо в кристалл микроконтроллера. Все выводы имеют защищающие от перенапряжения диоды, подключенные к VCC и GND.

  • DDRx Настройка разрядов порта x на вход или выход.
  • PORTx Управление состоянием выходов порта x (если соответствующий разряд настроен как выход), или подключением внутреннего pull-up резистора (если соответствующий разряд настроен как вход).
  • PINx Чтение логических уровней разрядов порта x.

Как работать с портами AVR как со входами

download
DDRD = 0; //настройка всех выводов порта D как входов
i = PIND; //прочитать все 8 ножек порта D и сохранить значение в i

Как работать с отдельными ножками порта AVR как с выходами

Есть возможность получить доступ к отдельным ножкам порта AVR. Это позволяет гибко использовать разряды порта для разных применений.

Некоторые из выводов 8-разрядного порта могут быть сконфигурированы и работать как выходы, причем остальные выводы порта могут работать как входы. Т. е. разные разряды одного порта могут выполнять разные функции в зависимости от потребностей пользователя.

Например, нам нужно, чтобы у порта D разряды 0, 2, 4, 6 (PD0, PD2, PD4, PD6) работали как входы (input), и разряды 1, 3, 5, 7 (PD1, PD3, PD5, PD7) работали как выходы (output). Тогда мы можем использовать код наподобие следующего:

download
DDRD=0;                                      // Сброс всех битов в 0 (00000000).
DDRD |= (1 << 1)|(1 << 3)|(1 << 5)|(1 << 7); // Использование операции сдвига
                                             // битов << и логической ИЛИ (OR)
                                             // чтобы установить биты 1, 3, 5, 7
                                             // в лог. 1. Остальные разряды 
                                             // останутся в состоянии лог. 0

Теперь мы можем вывести любое значение в разряды ножек порта (выходы) 1, 3, 5 и 7. Вот как можно установить эти разряды в лог. 1:

download
PORTD |= (1 << 1)|(1 << 3)|(1 << 5)|(1 << 7);

А так можно сбросить эти ножки в лог. 0:

download
PORTD &= ~((1 << 1)|(1 << 3)|(1 << 5)|(1 << 7));

Можно также использовать имена битов, соответствующие их номерам разрядов. Вот например, как можно работать с разрядами порта D через имена:

download
PORTD |=   (1 << PD5)|(1 << PD7);  // установка битов 5 и 7
PORTD &= ~((1 << PD5)|(1 << PD7)); // сброс битов 5 и 7
PORTD |=   (1 << PD1);             // установка бита 1
PORTD &= ~ (1 << PD1);             // сброс бита 1

Можно также для удобства назначать собственные мнемонические имена для разрядов и регистров. Вот как к примеру можно управлять светодиодом, подключенным к разряду 2 порта D:

AVR-LED-connect-example

download
#define LED PD2
#define LED_ON() PORTD |= (1 << LED)
#define LED_OFF() PORTD &= ~(1 << LED)

LED_ON();  //Зажечь светодиод
LED_OFF(); //Погасить светодиод

Здесь макросы LED_ON и LED_OFF заданы для удобного управление одним разрядом порта D. Они позволяют включать и выключать светодиод, подключенный к ножке порта PD2, и делают программу наглядной и простой.

Для составления масок есть также удобные макросы наподобие _BV(n).

Чтение отдельных разрядов порта AVR

Чтение отдельных разрядов порта (ножек микроконтроллера) AVR также осуществляется очень просто. К примеру, настройте отдельные ножки (разряды 1 и 3) порта D как входы, и прочитайте их состояние в переменную:

download
DDRD &=~ ((1 << 1)|(1 << 3)); // Очистка битов 1 и 3 регистра направления порта D.
i = PIND;                     // Прочитать состояние всех 8 ножек порта D.

Теперь Вы можете узнать логическое состояние отдельных разрядов (1 или 3) с помощью использования битовых масок, наложенных на значение переменной.

download
if ((1 << PD3) & i)
{
   //Здесь можно выполнить некоторые действия, если PD3==1
   ..
}
else
{
   //Здесь можно выполнить некоторые действия, если PD3==0
   ..
}

Точно так же можно узнать состояние ножки PD1, если наложить на i маску (1«PD1):

download
if ((1 << PD1) & i)
{
   //Здесь можно выполнить некоторые действия, если PD1==1
   ..
}
else
{
   //Здесь можно выполнить некоторые действия, если PD1==0
   ..
}

Второй способ - сдвинуть i вправо нужное число раз (для нашего примера 1 или 3 раза), и затем проверить значение младшего разряда i.

download
i >> =3;
if (1 & i)
{
   //Здесь можно выполнить некоторые действия, если PD3==1
   ..
}
else
{
   //Здесь можно выполнить некоторые действия, если PD3==0
   ..
}

Есть также удобные библиотечные макросы наподобие bit_is_set() или bit_is_clear(), имеющихся в файле sfr_defs.h, которые упрощают задачу проверки отдельных бит.

Бит PUD

Имеется также специальная возможность отключения всех внутренних нагрузочных резисторов AVR на всех портах сразу, если установить бит PUD (аббревиатура расшифровывается Pull-Up Disable) в регистре SFIOR (Special Function I/O Register). По умолчанию (после сброса или включения питания) этот бит сброшен, и не оказывает влияние на настройку нагрузочных резисторов.

В Си существуют 6 операторов для манипулирования битами:

  • « — сдвиг влево
  • » — сдвиг вправо
  • ~ — поразрядная инверсия
  • | — поразрядное ИЛИ
  • & — поразрядное И
  • ^ — поразрядное исключающее ИЛИ

Номера битов отсчитываются справа налево, начиная с нуля. 0 — это младший бит (справа), 7 — это старший бит (слева).

Если нужно записать сразу несколько бит:

download
unsigned char x = 0;
x = 1<<номер_бита | 1<<номер_бита | 1<<номер_бита .... ;

Если нужно записывать 1 в определенные биты, не стирая другие:

download
// Чтобы записать единицу в бит n:
x |= (1 << n);

// Чтобы записать ноль в бит n:
x &= ~(1 << n);

// Если нужно инвертировать состояние бита:
x ^= (1 << n);

//Если нужно прочитать отдельный бит:

unsigned char x = (1 << 2) | (1 << 3) | (1 << 7);
if (x & (1 << 2)) {  /* во второй бит вписана единица */ }
if (x & (1 << 3)) {  /* в третий бит вписана единица */ }
if (x & (1 << 7)) {  /* в седьмой бит вписана единица */ }

// Если нужно определить, что в X на N-й позиции:
bool b = (bool((1 << n)  &  x))

Если нужно обнулить один или несколько битов

download
// Для обнуления отдельных битов используется оператор &

int x = 58;       // 00111010
int y = x & 0x0F; // 00001010

// Обнулить несколько битов можно и так:


x = x & (~((1<<3)|(1<<5)|(1<<6))); //обнуляем третий, пятый и шестой биты
  • code/code.txt
  • Последние изменения: 2020/03/30 16:55
  • — truadmin