Как запретить компилятору Arduino объединять изменение выводов порта в одну операцию
Я хочу установить выходное значение одного вывода, а затем установить другое выходное значение вывода, чтобы два вывода меняли значение один за другим. Однако компилятор оптимизирует два вызова, чтобы сменить оба контакта за один раз.
ПОРТД |= _BV(0); // устанавливаем pd0 в высокое
ПОРТД |= _BV(1); // устанавливаем pd1 в высокое
ПОРТД &= ~(_BV(1)); // устанавливаем pd1 на низкий уровень
Два контакта одновременно становятся высокими. Я попытался вставить NOP между ними, но это не меняет поведение.
(Изначально я собирался включить снимок экрана осциллографа, чтобы показать, что происходит — так я узнал (или получил неправильное представление), что два контакта меняются одновременно. Но фотография не смещалась с моего Nexus 7, чтобы я мог получить к нему доступ с моего ноутбука.)
@mackenir, 👍1
Обсуждение1 ответ
Лучший ответ:
Конечно, я не могу повторять то, что вы говорите. Небольшой фрагмент кода:
void setup() {
PORTD |= _BV(0);
PORTD |= _BV(1);
PORTD &= ~(_BV(1));
}
void loop() {
}
компилируется в:
000000a6 <setup>:
a6: 58 9a sbi 0x0b, 0 ; 11
a8: 59 9a sbi 0x0b, 1 ; 11
aa: 59 98 cbi 0x0b, 1 ; 11
ac: 08 95 ret
000000ae <loop>:
ae: 08 95 ret
Очевидно, что это два отдельных набора битов, за которыми следует бит очистки.
Я использую UECIDE, для которого настроено использование GCC 4.3.2
Если вместо этого я переключусь на GCC 4.8.1, сгенерированный код будет идентичен.
Даже включив полную оптимизацию -O3, я все равно получаю те же результаты.
Так как же определить, что это происходит одновременно?
Что имеет смысл, поскольку ячейка памяти была объявлена как энергозависимая., @Ignacio Vazquez-Abrams
Я думаю, что использую Arduino IDE 1.06, но мне нужно будет проверить, когда я вернусь домой., @mackenir
Я наблюдал изменение двух контактов на осциллографе, но мне придется сделать шаг назад и провести тест с удаленным Arduino Micro из проекта, над которым я работаю. Похоже, я просто ошибаюсь., @mackenir
Тот же код, сгенерированный здесь с avr-gcc 5.4.0., @Edgar Bonet
- устаревшее преобразование из строковой константы в 'char*'
- Как запрограммировать ардуино на чистом C/C++?
- Количество элементов в массиве char
- Регистры ввода-вывода SAM3X8E (Arduino Due)
- как быстро loop() работает в Arduino
- Arduino: как получить тип платы в коде
- Как вызвать функции C из скетча ардуино?
- Как преобразовать полезную нагрузку byte* в строку
Я не могу повторить это поведение. Какая версия GCC используется?, @Ignacio Vazquez-Abrams
Какое приложение требует, чтобы эти контакты включались один за другим, но так быстро, что вам не нужен какой-либо код, чтобы вызвать задержку между ними?, @BrettAM
Круто - есть стековый обмен Arduino! Спасибо модам за перенос вопроса., @mackenir
Похоже, я просто запутался здесь, поскольку поведение, которое я видел, невоспроизводимо., @mackenir
(то есть другими)., @mackenir
Конечно, я не эксперт по O-скопам, но, учитывая, что смена выводов при отдельных вызовах все равно будет происходить за десятки наносекунд, сможет ли прицел точно определить разницу ?, @BrettAM
Что ж, при тестировании этого как собственного скетча я вижу, что все работает правильно - задержки между изменениями сигнала очевидны., @mackenir