Как работать с портами ввода вывода 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 мы определяем режим работы.
Высокоимпедансный вход – Это режим по умолчанию, МК в этом случае лучше всего защищён, вывод соединён с большим сопротивлением внутри микроконтроллера.
Вход 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);
}
}
—————————————————–
Работа с кнопкой в Atmega
————————————————–
// работа с кнопкой
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




