Порты ввода/вывода (ВВ) МК AVR состоят из определенного количества физических выводов (пинов, ножек). Полными эти порты считаются тогда, когда количество пинов составляет 8 (поскольку МК 8-разрядный), а сокращенными – когда пинов меньше 8. Таким образом, наша Tiny2313 имеет в своем составе один полный порт port B (PB7-PB0) и два сокращенных порта port A (3 пина PA2-PA0) и port D (6 пинов PD6-PD0).
Упрощенная схема порта ввода/вывода, а точнее его одного пина приведена на рисунке 1. Тут же можно пронаблюдать его алгоритм работы. Назначения портов ВВ – это ввод и вывод дискретной информации. Из этого следует что порты ВВ могут работать в двух основных режимах:
- режим, когда ножка порта настроена на ввод дискретной информации. То есть, например, контроль состояния дискретного датчика.
- режим, когда ножка порта настроена на вывод дискретной информации. То есть, например, зажигаем диод или открываем оптрон.
Для работы с портом x, служат специальные регистры инициализации порта. Их три
DDRx, PORTx, PINx. Тут х – означает имя порта. Для Tiny2313 x=A, B или D. Соответственно, для МК Mega128 x=A, B, C, D, E, F, G.
Рисунок 1 Принципиальная схема одного вывода порта.
Назначения данных регистров следующие:
DDRx – регистр направления передачи данных определяет назначения вывода порта: вход или выход. Если в этот регистр записать все единицы 0b11111111, то порт будет работать на вывод данных, а если записать в него все нули 0b00000000, то порт будет принимать данные. Соответственно, если вы запишите в него такой код 0b01010111, то пины 7,5,3 будут работать на ввод информации, а 6,4,2,1,0 – на вывод.
Пример:
ldi R20,0xff
out DDRC,R20 ; инициализация порта С на выход
PORTx – регистр данных порта. Сюда посылаем любую константу, а потом наблюдаем на физических выводах порта эту константу. Если хотите чтобы светодиоды, горели через один, записываете в PORTx константу 0b10101010 b получаете результат.
Пример:
ldi R20,0xf0
out PORTC,R20 ; вывод данного f0 (11110000) на порт С
PINx – регистр чтения данных с порта. Если регистр PORTx служит для записи кода в порт, то регистр PINx для чтения данных из порта.
Пример:
in R20,PINC ; считывания данного из порта С
Вот в принципе и весь набор регистров при работе с дискретными портами ввода/вывода. Теперь рассмотри программу в качестве примера.
Программа осуществляет инициализацию порта D на вход, а порта В на выход. Таким образом, данные считываем из порта D и посылаем их на выход порта B. Принципиальная схема иллюстрирующая работу данной программы изображена на рисунке 2.
Текст программы:.include "tn2313def.inc"
.list
.def temp=R16
.CSEG
.ORG 0x0000
rjmp RESET
;тут будет таблица векторов прерыванияRESET:
ldi R20,RAMEND
; инициализация стека out SPL,R20
; -------------------M:
ldi temp,0b00000000
; инициализация порта D на вход out DDRD,temp
;-------------------- ldi temp,0b11111111
; инициализация порта В на выход out DDRB,temp
; ------------------- in temp,PIND
; чтения данных с порта D out PORTB,temp
; вывод считанного данного на порт Brjmp M
; организуем цикл Рисунок 2 Схема к программе например может быть такой
Если стоит задача снимать информацию только с одного контакта или управлять только одним светодиодом, нет смысла задействовать весь порт для этих нужд. В МК есть возможность обратится отдельно к любому биту регистров инициализации, и инициализировать только один пин порта. Такие биты называются соответственно DDxn, PORTxn, PINxn. Тут n – номер бита данного регистра. Пример программы приведен ниже.
Алгоритм: если на ножке 2 порта D имеется «1», то устанавливаем «1» на ножке 5 порта B. Соответственно, если читаем «0», то и на выход пишем «0».