Ассемблерная вставка - почему не работает?
- Войдите на сайт для отправки комментариев
Пт, 18/01/2019 - 11:53
Доброго времени суток! Осваиваю ардуину, прошу помощи.
Имеется: плата "Pro Micro", среда программирования Arduino 1.8.8.
На контакт D2 платы, связанный с разрядом порта PORTD.1, подаётся внешний сигнал. Порт циклически опрашивается двумя способами.
register uint8_t result asm("r0"); void setup() { pinMode(17, OUTPUT); // (RXLED) pinMode(18, INPUT_PULLUP); // PORTF.7 pinMode(19, INPUT_PULLUP); // PORTF.6 pinMode(20, INPUT_PULLUP); // PORTF.5 pinMode(21, INPUT_PULLUP); // PORTF.4 pinMode( 7, OUTPUT); // PORTE.6 pinMode( 6, INPUT_PULLUP); // PORTD.7 pinMode( 4, INPUT_PULLUP); // PORTD.4 pinMode( 1, INPUT_PULLUP); // PORTD.3 pinMode( 0, INPUT_PULLUP); // PORTD.2 pinMode( 2, INPUT_PULLUP); // PORTD.1 = input pinMode( 3, INPUT_PULLUP); // PORTD.0 pinMode(10, INPUT_PULLUP); // PORTB.6 pinMode(14, INPUT_PULLUP); // PORTB.3 pinMode(16, INPUT_PULLUP); // PORTB.2 pinMode(15, INPUT_PULLUP); // PORTB.1 pinMode( 5, INPUT_PULLUP); pinMode( 8, INPUT_PULLUP); pinMode( 9, INPUT_PULLUP); Serial.begin(9600); } void loop() { __asm__ __volatile__("in r0, 0x0B"); // r0 <- PORTD Serial.write (result); delay(500); result = digitalRead(2); Serial.write (result); delay(500); }
"И сразу план? - видать что вы штабной!" (с)
"Осваиваю ардуину" - и сразу ассемблерная вставка? - интеграл прежде таблицы умножения? -не рано?
Прошу прощения, тема уже создалась, а вопрос не закончил. Так вот, при чтении порта функцией digitalRead видим входной сигнал, а при пересылке байта из порта командой in каждый раз получаем число 0xBF независимо от уровня на входе.
Что здесь не так?
И попутно ещё вопрос: нужно ли включать "подтяжку" на разрядах портов, не выведенных на внешние контакты платы, например PORTB.7, PORTD.7?
А что такое 0x0B в строке №28? А если попробовать правильно написать - 0x09 ? Не заработает? Я просто остальное не смотрел, попробуйте, если не заработает, то будем продолжать "посмотрушки".
Только зря Вы это затеяли. При таком описании перемнной result, Вы можете тупо на С писать
и это скомпилируется ТОЧНО В ТУ ЖЕ САМУЮ команду in, только порт правильно подставит.
_asm__ __volatile__("in r0, 0x0B"); // r0 <- PORTD
Viator, а кто вас этому научил? Вы пытаетесь отжать R0 у компилятора, это основной рабочий регистр, без него вообще работа МК невозможна. Компилятор просто выбросит вашу строчку как бред.
Компилятор просто выбросит вашу строчку как бред.
Да, не, компилирует, я проверял. Но подход, конечно :)
Да, дело в этом. Заработало. Спасибо!
Вы запомните PORTx - для вывода, а для ввода - PINx
Вот в этой статье
https://sites.google.com/site/vanyambauseslinux/arduino/arduino-assemble...
утверждается, что значение регистра r0 следует сохранять и восстанавливать, если ассемблерный код вызывает функцию C. Такого не предполагается.
А компилятор строчку не выбросил.
Вот в этой статье
Вы тут человек новый, пока никого не знаете, вот запомните, dimax из тех, про которых надо рассуждать так: "пофиг что там ХЗ кто написал в ХЗ какой статье, специалист то-то". Я так к нему и отношусь и ни разу не пожалел об этом.
Ну, а в данном случае его слова не противоречат статье. Регистр r0 советуют сохранять потому, что он самый "модный" у компилятора. Тот его пихает везде. Отжав его под свои нужды, Вы создали проблемы компилятору (сособенно оптимизатору), которые могут сказаться на качестве кода. не должны, но могут.
Так вообще поступать некрасиво. Всегда лучше оставить компилятору возможность самому назначить регистр. Да и порт, зачем самому адрес искать, всегда можно написать название. Я покажу как это делается на примере Вашей вставки, хотя, как я писал Вам выше, Ваша вставка не нужна вовсе, т.к. прямая запись result = PIND; прямо на С приведёт ровно к такому же коду.
А пример - держите.
В результате вставка скомпилировалась в
Обратите внимание какой регистр выделил компилятор.
Евгений! Можно дальше вставить оператор вывода в ком порт и посмотреть через какой регистр передастся значение?
Простите, я не понял вопроса. Напишите кусок кода и там укажите что именно Вы хотите посмотреть.
К вашей вставке добавить 29 строку первого сообщения. Сейчас я без компа и сам проверить не могу. Мне интересно перед вызовом serial.Write r24 в r0 перегонит или нет.
Как только добавил, он тут же стал выделять под result не 24, а 22 регистр и никуда его потом не перегружал
Спасибо. Забавно.
Как только добавил, он тут же стал выделять под result не 24, а 22 регистр и никуда его потом не перегружал
Евгений, как обычно, обос-ал всю интригу... Евгений - вы точно преподавали?
Да, даже в нескольких университетах и не только в России, но давно, сейчас только отдельные лекции иногда,типа раз в полгода, если позовут, читаю, а что?
Да, даже в нескольких университетах и не только в России, но давно, сейчас только отдельные лекции иногда,типа раз в полгода, если позовут, читаю, а что?
Евгений, да ёклмнэ, да я 2**10 не сомневаюсь в Вашей квалификации. Но неужели Вы выпускаете ТАКИХ студентов?
Студенты всякие бывают. Обычно 1-3 с потока очень серьёзнае ребята. Вполне себе состоялись как специалисты. Но и дрючил я их по полной. Дебила ведь неинтересно дрючить - что с него взять? Вот, почитайте, например про одного.
Студенты всякие бывают. Обычно 1-3 с потока очень серьёзнае ребята. Вполне себе состоялись как специалисты. Но и дрючил я их по полной. Дебила ведь неинтересно дрючить - что с него взять? Вот, почитайте, например про одного.
Евгений, кстати я - Герман. Эту вещугу я прочитал где-то около первого входа на форум. Порадовало... Это пример правильного отношения преподаватель-студент.