13 мая 2014 г.

Как работать с портами ввода вывода AVR микроконтроллера и для чего они предназначены

Немного информации про порты ввода вывода и для чего предназначены различные ножки микроконтроллера. Как работать с портами расскажу на примере AtMega8.
В принципе всю информацию можно взять и из документации.





У этого МК 3 порта. B C и D. К примеру порту B соответствуют выводы: PB0 PB1 ... PB7. Здесь у каждого порта кроме C (у него 7 ) по 8 выводов. (может быть меньше, к тому же у некоторых специальное предназначение, но об том потом). На то что в скобках пока что не обращаем внимания.
Каждый вывод порта может работать либо как вход, либо как выход. Для того чтобы выбрать режим работы ножки микроконтроллера необходимо прописать нужные биты в сооттветсвующие регистры.

Для работы с портами есть 3 регистра PINx  PORTx  и  DDRx.
где x буква обозначающая порт. DDRA для порта А

В регистре PINx хранится состояние порта, он считывает на какой ножке логическая 1 ( + 5 В) на какой лог 0, и сохраняет эти значения. Этот регистр доступен только для чтения.

В регистре DDRx мы определяем работает ли вывод как вход или как выход. Если выставим 1 в какой либо бит, то соответствующая ножка порта будет работать как выход. Если 0, то как вход.

В регистре PORTx  мы определяем режим работы.


DDRx.n
PORTx.n
(По умолчанию)
Высокоимпедансный вход
0
0
Вход с pull up резистором
0
1
Выход соединён с землей
1
0
Выход соединён с VCC (+5 В)
1
1
Высокоимпедансный вход - Это режим по умолчанию, МК в этом случае лучше всего защищён, вывод соединён с большим сопротивлением внутри микроконтроллера.

Вход c pull up резистором - вывод МК соединён через резистор 30 К с питанием VCC


# define F_CPU 8000000UL             // Выбираем частоту МК
#include <avr/io.h>                  // Для работы с портами
#include <util/delay.h>              // для задержки

int main(void)
{
      // 2 и 3 выводы порта B как выход
      DDRB = 0b00001100;                              // двоичный код
      DDRB = 0x0C;                                    // 16 - чный код
      DDRB = 12;                                      // 10 - чный код
      DDRB |= ( 1 << 2 ) | ( 1 << 3 );                // побитовое или
      // Это всё означает одно и то же

      // на 2 и 3 выводы подаем логическую 1 ( + 5В )
      PORTB |= ( 1 << 2 ) | ( 1 << 3 );
 
      while(1)
      {
            // мигаем 2 и 3 выводом
            PORTB = PORTB ^ 0b00001100;       // инвертирующее или
            PORTB ^= 0b00001100;              // тоже самое короче
            _delay_ms(200);
      }
}

Результат

 // работа с кнопкой
 DDRB = 0x00;                                       // вход
 PORTB |= ( 1 << 2 ) | ( 1 << 3 );      // резистор до VCC
 // на выводах 2 и 3 Порта B + 5В
    while(1)
    {
        // кнопки нужно соединить 1 выводом к ножке МК
        // 2 выводом к земле
        if ( PINB == 0b00000110 )  // кнопки не нажаты ?
        if ( PINB == 0b00000100 )  // нажата кнопка 2 вывода ?
        if ( PINB & 0b00000100 )  // побитовое и, НЕ нажата 3 кнопка ?
  
        // инвертируем регистр PINB если было 0b00000110 стало 0b11111001
  
        if ( !PINB & 0b00000100 )  // нажата 3 кнопка ?
        if ( !PINB & ( 1 << 3 ) )  // то же самое
    }
Про бегущий огонь
 

        // Еще 1 полезная вещь называется битовый сдвиг

        // записали 1 в 1 бит
        PORTB = 0b00000001;

        PORTB = PORTB << 1;        // PORTB == 0b00000010;
        // сдвинули 1 влево на 1 шаг можно на 2, 3 и т.д

        PORTB = PORTB >> 1;        // PORTB == 0b00000001;
        // сдвинули 1 вправо на 1 шаг

        // но после 0b10000000 если единичка сдвинется влево будет 0x00
        // нужно самому вручную выставлять заново



Теперь про выводы МК на примере 32 АтМеги (т.к у неё много ножек и тот же DIP корпус)
Всё что здесь будет описано относится конкретно к данному микроконтроллеру, большая часть совпадает с другими AVR-ками, но лучше читать документацию.
VCC - питание (зависит от МК обычно от 2.7 В до 5.5 В)
GND - земля
RESET - По умолчанию тут 1, если заземлить на 2 мкс МК перезагрузиться.
XTAL1 - вход внешнего генератора тактовой частоты.
XTAL2 - его выход. (между этими ножками ставиться кварц с конденсаторами, ему не важно какой стороной его ставить)
AVCC - сюда подается напряжение для работы АЦП
AREF - эталон напряжения для АЦП (с каким значением сравнивать АЦП)


ADC(0...7) - Ножки на которые подается напряжение которое нужно преобразовать с помощью АЦП, 8 каналов,

Порт B

(SS, MOSI, MISO, SCK) - используются для передачи данных по SPI, через них также программируется МК.
(T1, T0) - сюда подключается внешний источник тактов и таймеры T1 и T0 подсчитывают внешние такты.
(AIN0, AIN1) - соответсвенно положительный и отрицательный выводы аналогового компаратора .
INT2 - вывод для проверки прерываний, к примеру если настроить и подать 1 на этот вывод в МК произойдет прерывание.
OC0 - Вывод ШИМ
XCK - используется при передаче данных с USART


Порт C

TOSC2, TOSC1 - если настроен сюда подключается тактовый генератор, от которого работает МК
TDI, TDO, TMS, TCK - используется для отладки JTAG
SDA - вывод для работы последовательного интерфейса, ДАТА
SCL - вывод для работы последовательного интерфейса, подав сюда импульс передаём 1 бит информации по выводу SDA.


Порт D

OC2 - вывод для ШИМ
ICP1 - (Input Capture PIN) когда на этом выводе происходит какое либо событие, в регистр ICR1 записывается значения таймера (вкратце время) и можно вычилсять частоту и период колебаний на выводе.

OC1A - вывод для ШИМ, при совпадении таймера с OCR1A
OC1B - вывод для ШИМ, при совпадении таймера с OCR1B
INT1 - ножка для внешних прерываний 1
INT0 - ножка для внешних прерываний 0
TXD - вывод данных по USART
RXD - чтение данных по USART




Комментариев нет :

Отправить комментарий