# 4.Регистры ввода вывода (DDRX,PINx,PORTx)
### TODO:
- [X] Система ввода вывода (наверное все что хотел написал)
- [X] Описание регистров ввода/вывода
- [ ] Примеры кода
[15.Порты ввода/вывода](/mOXnuCxYSP-OA_Vh5FU9Uw)
## Описание работы регистров

В каждом регистре 8 занятых битов, так как каждый порт состоит из 8 пинов, то каждый бит управляет своим пином соответственно. Пины номеруются так же как и биты от 7 до 0.
Далее x - порт
### DDRx
Доступен как на запись так и на чтение.
**DDRx** - это регистр направления порта. Порт в конкретный момент времени может быть либо входом либо выходом (но для состояния битов PIN это значения не имеет. Читать из PIN реальное значение можно всегда).
Значение по умолчанию = 0 (вход). 1 - выход
### PINx
PINx – Из него можно только читать значения на пинах портов. В регистре PINx содержится информация о информации на выводах порта. Прочитать можно не зависимости от настроек порта (на вход, на выход, не важно). Так что если хотим узнать что у нас на входе — читаем соответствующий бит регистра PINx Причем существует две границы: граница гарантированного нуля и граница гарантированной единицы — пороги за которыми мы можем однозначно четко определить текущий логический уровень.
> [name=Дарья Воронская] ох ля, спросит ведь про эти границы,
### PORTx
Доступен как на запись так и на чтение.
PORTX - режим управления состоянием вывода.
Регистр PORTx управляет состоянием выводов порта «x». В зависимости от выбранного направления работы (вход или выход) порта или отдельно взятого вывода значение, записанное в регистр PORTx того же порта, может
присваивать выводу различные состояния.
Если в разряд DDRx записан 0 и в соответствующий разряд PORTx также записан 0, то порт сконфигурирован как вход с высоким входным сопротивлением, что соответствует отключенному выходному состоянию (третье состояние). Если в разряд PORTx записана логическая 1 и в соответствующий разряд DDRx записана логическая 1, то порт сконфигурирован как выход и на выходе будет логическая 1. То есть биты PORTx управляют состоянием выходного порта при условии, что в соответствующий порту разряд DDRx записана логическая 1.
## Примеры кода c даташита
обрати внимание, что там есть nop для синхронизации, нужно почитать про то, как по времени работает система ввода вывода (если я это вообще распишу)
:::warning
Если мы настраиваем на вход, то сначала пишем в регистр DDRx, потом в portx, если нам нужно подключить pull-up резистор. Делается это для того, чтобы мы своей записью в portx не изменили значение пина.
если на выход, то наоборот, сначала в portx закидываем значение выходного сигнала, потом изменяем направление. Если сделать наоборот, то, сначала на пине будет значение portx, предназначенное для настройки pull-up, и только потом то, которое мы записали.
Возможна и смешанная настройка порта: части пинов задать вход, части выход, всем раздать какие-то значения через portx. В таком случае лучше сначала загрузить в portx, потом в ddrx. Если мы сначала загрузим все входы, потом все выходы, то программа будет работать на несколько тактов дольше.
Также крайне нежелательно смешивать команды ldi, out. Сначала сделай все записи в ldi, потом все записи в out. Каждая ldi выполняется 2 такта, так что запуская их между out мы увеличиваем время, в течение которого на портах неактуальная информация
:::
```cp=...
; Define pull-ups and set outputs high
; Define directions for port pins
ldi r16,(1<<PB7)|(1<<PB6)|(1<<PB1)|(1<<PB0)
ldi r17,(1<<DDB3)|(1<<DDB2)|(1<<DDB1)|(1<<DDB0)
out PORTB,r16
out DDRB,r17
; Insert nop for synchronization
nop
; Read port pins
in r16,PINB
...
```