# 9. Регистр для работы с АЦП (ACSR, ADMUX, ADCSRA, ADCX) [20. Схема АЦП (Аналогово-цифровой преобразователь)](/HzYWPqA4QVyVa8iLTkDjWQ) ## ACSR - регистр управления аналогового компаратора Аналоговый компаратор - позволяет сравнивать 2 числа и выносить вердикт, какое из них больше: 0 - первый больше второго, 1 - второй больше первого. ![](https://i.imgur.com/U6hjaDx.png) Биты: > **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=Дарья Воронская] Разобраться бы на что это всё влияет ![](https://i.imgur.com/mOyn2kX.png) **Биты REFS1 (7) и REFS0 (6)** устанавливают какой источник опорного напряжения будет выбран: 00 - опорное напряжение на входе AREF (21 ножка) 01 - Vпитания (вход AREF должен быть отключен. или к нему можно подключить фильтрующий конденсатор) 10 - резерв 11 - внутренний ИОН 1.1 В (к входу AREF можно подключить фильтрующий конденсатор) ![](https://i.imgur.com/U9Fw5x1.png) **Бит 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 ![](https://i.imgur.com/UH3J8uv.png) Бит ADEN (7) регистра ADCSRA включает или выключает АЦП (1-включен). Бит ADSC (6) регистра ADCSRA запускает преобразование если в него записать 1 (для многоразового режима запуск первого преобразования). Бит ADATE (5) регистра ADCSRA позволяет запускать преобразование по прерыванию от переферийных устройств микроконтроллера если установить в 1. Бит ADIF (4) регистра ADCSRA - флаг прерывания от АЦП. Бит ADIE (3) регистра ADCSRA - разрешает прерывания от АЦП если установлен в 1. Биты ADPS2 - ADPS0 (2 - 0) регистра ADCSRA выбирают режим работы предделителя тактовой частоты ![](https://i.imgur.com/O5FUujf.png) ## 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 ```