Одновременное обращение к цифровым пинам.

Vitalmsk
Offline
Зарегистрирован: 04.05.2018

Вопрос начинающего.

Ардуинка UNO цифровыми выводами 2,3,4,5 должна перебрать адреса внешнего устройства. Считывая данные аналоговыми контактами. Как на цифровых выводах одновременно выставлять адреса, не изменяя состояние остальных цифровых выводов.

sadman41
Offline
Зарегистрирован: 19.10.2016

Насколько одновременно?

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

Выводы 2, 3, 4 и 5 подсоединены к одному и тому же порту. Соответственно, можно устанавливать их одновременно, изменяя содержимое порта по маске.

Собственно, в соседнем разделе прикрепленная тема: http://arduino.ru/forum/obshchii/pin-mapping-sootvetstvie-vyvodov-i-registrov

Vitalmsk
Offline
Зарегистрирован: 04.05.2018

Просто 0000, 0001,0010,0011 .... 1100,1101,1110,1111 , а не сначала на пине 2, затем на пине 3, и тд.

 

b707
Offline
Зарегистрирован: 26.05.2017

Vitalmsk пишет:

Просто 0000, 0001,0010,0011 .... 1100,1101,1110,1111 , а не сначала на пине 2, затем на пине 3, и тд.

 

можно

Vitalmsk
Offline
Зарегистрирован: 04.05.2018

Правильно ли DDRD =| B00111100; // Инициализирую

Затем в цикле PORTD = adr; / Где adr адрес на внешнем устройстве

или

                      PORTD |= adr;

b707
Offline
Зарегистрирован: 26.05.2017

Vitalmsk пишет:

Правильно ли DDRD =| B00111100; // Инициализирую

Затем в цикле PORTD = adr; / Где adr адрес на внешнем устройстве

или

                      PORTD |= adr;

чему равен adr ?

sadman41
Offline
Зарегистрирован: 19.10.2016

Не преувеличена ли опасность наличия гапа? 4 пина, прямой записью в регистры... Комар моргнуть не успеет даже.

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

Vitalmsk пишет:

Правильно ли DDRD =| B00111100; // Инициализирую

Затем в цикле PORTD = adr; / Где adr адрес на внешнем устройстве

или

                      PORTD |= adr;

Нет.

У Вас ведь младший бит адреса выводится не в 0-й, а во 2-й разряд порта. Значит, нужен сдвиг на 2 влево. И, если Вы собираетесь выводить адрес неоднократно, нужно не забывать и обнульять единицы от прошлых операций. Следовательно что-то вроде PORTD = (PORTD & 0xC3) | (adr << 2);

Vitalmsk
Offline
Зарегистрирован: 04.05.2018

adr меняется от B00000100 до B00111100. Или что эквивалентно от 4 до 60 в десятичной системе.

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

В сообщениях №3 и №9 взаимоисключающая информация.

Vitalmsk
Offline
Зарегистрирован: 04.05.2018

Точнее значения adr  B0, B100, B1000, B1100, ..., B111100 или в десятичной системе 0, 4, 8, 12 .... 60.

Green
Offline
Зарегистрирован: 01.10.2015

Через обнуление: PORTD &= B11000011; PORTB |= adr<<2;
Либо с переменной, если нужно строго изменение: uint8_t x = PORTD; x &= B11000011; x |= adr<<2; PORTD = x;
При этом, на время операций с портом желательно запрещать прерывания.

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

Green пишет:

Через обнуление: PORTD &= B11000011; PORTB |= adr<<2;
Либо с переменной, если нужно строго изменение: uint8_t x = PORTD; x &= B11000011; x |= adr<<2; PORTD = x;
При этом, на время операций с портом желательно запрещать прерывания.

Вы перепутали PORTD c PORTB, не читали сообщения №8 или и то и другое?

И зачем запрещать прерывания?

Green
Offline
Зарегистрирован: 01.10.2015

Vitalmsk пишет:

Ардуинка UNO цифровыми выводами 2,3,4,5 должна перебрать адреса внешнего устройства.


Та вроде не перепутал.)
Прерывания - затем, что бы никто не мог изменить состояние порта, пока мы с ним играемся. Очевидно же.
Но если всё под контролем, тогда не надо.)
"Сержант, стройте взвод. Нафига? Тогда не надо.")

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

Green пишет:

Прерывания - затем, что бы никто не мог изменить состояние порта, пока мы с ним играемся. Очевидно же.

Что значит "пока играемся", если изменение состояния ног порта происходит один раз и одномоментно?

Green
Offline
Зарегистрирован: 01.10.2015

Играемся - от момента когда считали значение с порта и до момента когда его записали. А это, как раз, не одномоментно, к сожалению.

DetSimen
DetSimen аватар
Offline
Зарегистрирован: 25.01.2017

andriano пишет:

изменение состояния ног порта происходит один раз и одномоментно?

Не совсем. Всё равно компилятор сначала считывает значение порта в регистр, потом делает логическую операцию, потом записыват взат. Если прерывание, в котором изменяются ноги этого же порта случится сразу ПОСЛЕ того, как мы его считали, но ДО того, как записали взат, то после нашей записи мы потеряем то, что изменилось в прерывании.  Поэтому, операция изменения регистра порта просто обязана быть атоммарной. 

Vitalmsk
Offline
Зарегистрирован: 04.05.2018

Немного не так. После выставления адреса происходит считывание данных и дальнейшая обработка. Посл обработки выставление нового адреса, считывание и новая обработка. Главное выставить одномоментно адрес на ногах. Я все понимаю, но почему нельзя просто обращаясь к регистру D т.е. PORTD нельзя выставить адрес без сдвигов и т.п. без затрагивания других ног. На других ногах стоят иные сигналы управления.

Green
Offline
Зарегистрирован: 01.10.2015

Сдвиги чисто для вашего удобства. Для того что бы вы в своей голове не вычисляли действительное значение. Они не порождают никаких дополнительных команд.
Почему? Вы ведь сами говорите что "на других ногах стоят иные сигналы управления". Если вы знаете какие, тогда можете сразу выставлять данные с этими "другими сигналами". Но это не есть универсально (как любит говорить andiano))).

Vitalmsk
Offline
Зарегистрирован: 04.05.2018

Хорошо, а если перед установкой адресных данных считать состояние регистра, наложить маску и записать по новой с новым адресом?

Green
Offline
Зарегистрирован: 01.10.2015

Ну да, я ж вам пример приводил.
Либо с переменной, если нужно строго изменение: uint8_t x = PORTD; x &= B11000011; x |= adr<<2; PORTD = x;
Только обычно эта одновременность никому и нафиг не нужна.)

 

Vitalmsk
Offline
Зарегистрирован: 04.05.2018

Нужна, если время поджимает.

Green
Offline
Зарегистрирован: 01.10.2015

Говорите какое время - тогда будет понятно.

 

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Да, возьмите библиотеку DigitalPins - там есть групповые операции для пинов одного порта. Они именно эти и делают.

Vitalmsk
Offline
Зарегистрирован: 04.05.2018

Убедили, задавили, разъяснили...... Всем спасибо, пошел экспериментировать. Ещё раз всем спасибо и не обижайтесь, я только учусь, а это не стыдно!!

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Так библиотеку-то попробовали? Сработало?

Vitalmsk
Offline
Зарегистрирован: 04.05.2018

Ушел пробовать. Позднее отпишусь если интересно.

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

Vitalmsk пишет:

почему нельзя просто обращаясь к регистру D т.е. PORTD нельзя выставить адрес без сдвигов и т.п. без затрагивания других ног. На других ногах стоят иные сигналы управления.

Потому, что к порту подключено 8 ног, а изменить сигналы Вам нужно только на четырех. А на остальных четырех, где "иные сигналы управления", ничего меняться не должно.

Vitalmsk пишет:

Хорошо, а если перед установкой адресных данных считать состояние регистра, наложить маску и записать по новой с новым адресом?

Именно это я Вам советовал еще в сообщениях №2 и №8.

Vitalmsk
Offline
Зарегистрирован: 04.05.2018

Всем огромное спасибо!!! Все получилось. Собака порылась в том, что в сообщении № 13 говорилось об обнулении. У меня этого не было и получалось, что предыдущие значения оставались на ногах. Короче в цикле делалось Сброс вначале сброс значений на 4 ногах, затем установка нового значения, чтение аналогового сигнала, обработка и все по новой. 

Еще раз всем спасибо. Одна голова хорошо, а подзатыльник лучше!.