Кому-то может не хватить тринадцати цифровых входов Arduino, и для таких людей сегодня я расскажу, как превратить шесть аналоговых входов в цифровые. Нам опять потребуется немного низкоуровневой магии, но пусть вас это не пугает.
Каждый бит этого регистра содержит значение соответствующего пина. Прочитать значение можно независимо от значения DDxn.
Чтобы включать и выключать светодиод, будем записывать то 1, то 0 в бит PORTC0 регистра PORTC:
void loop(){
PORTC = PORTC | (1 << PORTC0);
delay(1000);
PORTC = PORTC ^ (1 << PORTC0);
delay(1000);
}
Всё!
Blink, способ 2
Есть более читерский способ, который сокращает программу еще на 2 строчки. В гайде ATmega328 пишут, что запись единицы в PINxn переключает значение PORTxn, независимо от значения DDRxn. Ну то есть если там был 0, то становится 1, а если был 1, то становится 0. За сим накалякаем следующий код:
void setup(){
DDRC = (1 << DDC0);
}
void loop(){
PINC = PINC | (1 << PINC0);
delay(1000);
}
Вот и весь код. Работает прямо так же, как на предыдущем видео. Можно было бы еще избавиться от строчки с DDRC=(1<
Более продвинутая установка
Чтобы было весело, займем все 6 аналоговых входов. На 0-4 повесим светодиоды, а на 5 - кнопку:
Теперь назначим пины PC0...4 как выходы, а PC5 как вход. Помня, что выход - это 1 в DDCn, а вход - это 0, можно написать строчку, которая все сделает, так:
Для того, чтобы сделать что-то по нажатию кнопки, надо сдетектировать это самое нажатие. Ждем единицу на PINC5, и по ней запускаем бегущие огни - записываем по очереди единицы в PORTCn, а потом записываем нули точно так же. Полный код:
Программа в основном цикле содержит сколько же строк, сколько было бы при использовании стандартных цифровых выходов и конструкций digitalWrite(). Поэтому единственная сложность возникает лишь в ненаглядности функций.
PORTC
Пока АЦП не работает, доступны другие функции ног процессора, занятых под преобразование.
Смотрим на картинку и видим, что аналоговые входы 0...5 находятся на ногах 23...28. Однако основная функция этих ног - PC0...5.
PC означает PORTC, или по-русски "Порт Цэ". Порт - это устройство ввода-вывода, где каждый бит может вводиться или выводиться отдельно, а может и в составе байта. У процессора ATmega328 три семибитных порта: B, C и D. Каждый пин порта управляется тремя битами в трех регистрах: DDxn, PORTxn, PINxn. Нам сейчас не интересны порты B и D, поэтому поглядим на регистры порта C.
DDRC - регистр направления данных порта C
Каждый бит в этом регистре отвечает за направление данных на соответствующем пине:
7 bit | 6 bit | 5 bit | 4 bit | 3 bit | 2 bit | 1 bit | 0 bit | |
DDRC | - | DDC6 | DDC5 | DDC4 | DDC3 | DDC2 | DDC1 | DDC0 |
0 - вход,
1 - выход.
Значение по умолчанию - 0.
PORTC - регистр данных порта C
Если пин сконфигурирован как вход, то при записи 1 в соответствующий бит этого регистра активируется подтягивающий резистор. При записи 0 подтягивающий резистор отключается.
7 bit | 6 bit | 5 bit | 4 bit | 3 bit | 2 bit | 1 bit | 0 bit | |
PORTC | - | PORTC6 | PORTC5 | PORTC4 | PORTC3 | PORTC2 | PORTC1 | PORTC0 |
Если пин сконфигурирован как выход, то при записи 1 в соответствующий бит этого регистра пин подтягивается к питанию. При записи 0 пин притягивается к земле.
Значение по умолчанию - 0.
PINC - Адреса входов порта C
7 bit | 6 bit | 5 bit | 4 bit | 3 bit | 2 bit | 1 bit | 0 bit | |
PINC | - | PINC6 | PINC5 | PINC4 | PINC3 | PINC2 | PINC1 | PINC0 |
Значение по умолчанию - не определено.
Blink, 1 способ
Напишем всем известную программу Blink для аналогового входа (гы-гы). Подключим светодиодик к аналоговому входу 0:
Для начала назначим бывший аналоговый вход A0 как цифровой выход. Для этого запишем единицу в бит DDC0 регистра DDRC:
void setup(){
DDRC = (1 << DDC0);
}
DDRC = (1 << DDC0);
}
void loop(){
PORTC = PORTC | (1 << PORTC0);
delay(1000);
PORTC = PORTC ^ (1 << PORTC0);
delay(1000);
}
Blink, способ 2
Есть более читерский способ, который сокращает программу еще на 2 строчки. В гайде ATmega328 пишут, что запись единицы в PINxn переключает значение PORTxn, независимо от значения DDRxn. Ну то есть если там был 0, то становится 1, а если был 1, то становится 0. За сим накалякаем следующий код:
void setup(){
DDRC = (1 << DDC0);
}
void loop(){
PINC = PINC | (1 << PINC0);
delay(1000);
}
Более продвинутая установка
Чтобы было весело, займем все 6 аналоговых входов. На 0-4 повесим светодиоды, а на 5 - кнопку:
Теперь назначим пины PC0...4 как выходы, а PC5 как вход. Помня, что выход - это 1 в DDCn, а вход - это 0, можно написать строчку, которая все сделает, так:
DDRC = B00011111;
void setup(){
DDRC = B00011111;
}
void loop(){
if (PINC & (1 << PINC5)){
for (int i=0;i<5 br="" clear="none" i=""> PORTC = PORTC | (1 << i);
delay(100);
}
for (int i=0;i<5 br="" clear="none" i=""> PORTC = PORTC ^ (1 << i);
delay(100);
}
}
}5>5>
}
void loop(){
if (PINC & (1 << PINC5)){
for (int i=0;i<5 br="" clear="none" i=""> PORTC = PORTC | (1 << i);
delay(100);
}
for (int i=0;i<5 br="" clear="none" i=""> PORTC = PORTC ^ (1 << i);
delay(100);
}
}
}5>5>
Источник: http://greenoakst.blogspot.ru/
Комментариев нет:
Отправить комментарий
Создайте свой комментарий.