# 9. Регистр для работы с АЦП (ACSR, ADMUX, ADCSRA, ADCX)
[20. Схема АЦП (Аналогово-цифровой преобразователь)](/HzYWPqA4QVyVa8iLTkDjWQ)
## ACSR - регистр управления аналогового компаратора
Аналоговый компаратор - позволяет сравнивать 2 числа и выносить вердикт, какое из них больше: 0 - первый больше второго, 1 - второй больше первого.

Биты:
>
**ACD** включение компаратора 0 включен, 1 выключен. По дефолту там ноль, а значит при старте компаратор включен.
**ACBG** — подключение к прямому входу компаратора внутреннего источника опорного напряжения (ИОН) на 1.22+(-)0.05V. Если 0 то ИОН не подключен.
**ACO** — бит результата. Собственно, это и есть выход компаратора.
**ACI** — флаг прерывания. Я думаю, что ты уже привык к тому, что в AVR есть прерывание на каждый чих. Компаратор не исключение. Устанавливается по событию, сбрасывается после ухода на обработчик либо программно, как всегда, записью в него 1.
**ACIE** — где есть прерывание там должен быть и бит разрешения. Это он и есть. Установив в 1 мы разрешаем прерывания от компаратора. По дефолту, естественно, нуль.
**ACIC** — подключение компаратора к схеме захвата таймера1. При попадании сигнала на схему захвата текущее значение с таймера тут же тырится в специальный регистр захвата, а таймер продолжает считать дальше. А в привязке к компаратору это удобно когда нужно измерять длительности сигналов.
**Биты ACIS1:ACIS0** определяет условие возникновения прерывания от компаратора:
00 — любое изменение на входе.
01 — зарезервировано для следующих поколений
10 — переход с 1 на 0
11 — переход с 0 на 1
## ADMUX - регистр выбора входа мультиплексора
> [name=Дарья Воронская] Разобраться бы на что это всё влияет

**Биты REFS1 (7) и REFS0 (6)** устанавливают какой источник опорного напряжения будет выбран:
00 - опорное напряжение на входе AREF (21 ножка)
01 - Vпитания (вход AREF должен быть отключен. или к нему можно подключить фильтрующий конденсатор)
10 - резерв
11 - внутренний ИОН 1.1 В (к входу AREF можно подключить фильтрующий конденсатор)

**Бит ADLAR (5)** Порядок: если 1. То первые 8 бит в ADCH, последние 2 в ADCL, иначе первые 2 в ADCL, последние в ADCH. Ставь в еденицу, потому что последние 2 бита все равно шумят.
**Биты MUX3 - MUX0 (3 - 0)** - управляют мультиплексором:
0000 - вход ADC0 (23 ножка)
0001 - вход ADC1 (24 ножка)
0010 - вход ADC2 (25 ножка)
0011 - вход ADC3 (26 ножка)
0100 - вход ADC4 (27 ножка)
0101 - вход ADC5 (28 ножка)
0111 - резерв
1000 - датчик температуры
1001 - 1101 - резерв
1110 - 1.1 В
1111 - 0 В (земля)
## ADCSRA - регистр управления АЦП A

Бит ADEN (7) регистра ADCSRA включает или выключает АЦП (1-включен).
Бит ADSC (6) регистра ADCSRA запускает преобразование если в него записать 1 (для многоразового режима запуск первого преобразования).
Бит ADATE (5) регистра ADCSRA позволяет запускать преобразование по прерыванию от переферийных устройств микроконтроллера если установить в 1.
Бит ADIF (4) регистра ADCSRA - флаг прерывания от АЦП.
Бит ADIE (3) регистра ADCSRA - разрешает прерывания от АЦП если установлен в 1.
Биты ADPS2 - ADPS0 (2 - 0) регистра ADCSRA выбирают режим работы предделителя тактовой частоты

## ADCx - ADCL и ADCH - регистры с результатом преобразования АЦП (регситры данных)
АЦП генерирует 10-разрядный результат, который помещается в пару регистров данных АЦП ADCH и ADCL.
Так как у нас АЦП 10-разрядная, 8 непомещается. Используют 2 регистра ADCL/ADCH. Если бит ADLAR = 0, то в ADCH хранатся два бита,а остальные в ADCL.Если же ADLAR = 1, то в ADCL хранятся два младших бита, а все старшие биты лежат байтом в ADCH
## Примеры кода
:::spoiler Оригинал на С
```c=
ADMUX = 0b01100000; // Configure ADC to be left justified, use AVCC as reference, and select ADC0 as ADC input
ADCSRA = 0b10000111; // Enable the ADC and set the prescaler to max value (128)
ADCSRA = ADCSRA | (1 << ADSC);
while(ADCSRA & (1 << ADSC));// Wait until the ADSC bit has been cleared
....
```
:::
Перевод на assembler (вольный, кривой)
Сначала читаем у L, потом у H.
```cp=
in R16, ADCSRA
sbr R16, ADEN ; включаем ацп
sbr R16, ADSC; запускаем ацп
OUT ADCSRA, R16
waitForADC: sbic ADCSRA, ADSC ; пропустить следующую команду если ADSC = 0
jump waitForADC ; ждем пока ADSC = 0
in r17, ADCL ; забираем 1 бит
in r18, ADCH ; забираем 2 бит
in R16, ADCSRA
sbc R16, ADEN ; выключаем ацп
OUT ADCSRA, R16
```
Инициализация
```cp=
adcInit:
ldi r16, 0b01100000 ; Voltage Reference: AVcc with external capacitor at AREF pin
sts
, r16 ; Enable ADC Left AdjusЯt Result
; Analog Channel: ADC0
ldi r16, 0b10000101 ; Enable ADC
sts ADCSRA, r16 ; ADC Prescaling Factor: 32
ret
```
Что-то по компаратору, скорее всего для нас не очень актуальное
```cp=
; Инициализирую компаратор
LDI R16,(1<<ACBG)|(1<<ACIE)|(1<<ACIS1)|(1<<ACIS0)
OUT ACSR,R16 ; Забрасываем в регистр
IN R16,SFIOR ; Достаем SFIOR
ORI R16,(1<<ACME) ; Выставялем в нем бит ACME
OUT SFIOR,R16
; АЦП у меня по дефолту вырублен, поэтому пока не напрягаюсь с его отключением
LDI R16,5 ; подаю напругу на 5й вход АЦП
OUT ADMUX,R16
```