Прямой (низкоуровневый) доступ к портам. Библиотека
- Войдите на сайт для отправки комментариев
Чт, 17/01/2019 - 15:27
Иногда возникает потребность побыстрее рулить портами или читать их. Чтобы не путаться при отладке в этих битовых закорючках , для наглядности пользуюсь такими функциями для атмеги 328
void digital_Write (byte pin, bool state) { if (pin>=0 && pin<=7) { if (state) PORTD |= (1<<pin); else PORTD &=~(1<<pin); } else if (pin>=8 && pin<=13) { if (state) PORTB |= (1<<pin-8); else PORTB &=~(1<<pin-8); } else if (pin>=14 && pin<=19) { if (state) PORTC |= (1<<pin-14); else PORTC &=~(1<<pin-14); } } bool digital_Read (byte pin) { if (pin>=0 && pin<=7) {return ((PIND &(1<<pin))>>pin);} else if (pin>=8 && pin<=13) {return ((PINB &(1<<pin-8))>>pin-8);} else if (pin>=14 && pin<=19){return ((PINC &(1<<pin-14))>>pin-14);} }
Есть несколько вопросов.
1. Правильно ли я сделал эти функции, или можно поизящнее выполнить?
2. Насколько примерно задержка при пользовании такими функциями по сравнению с просто например PORTD |= (1<<5); ?
3. Наверняка это велосипед. Но с ходу чето не нашёл оформленного в виде библиотеки, чтобы на разные атмеги подходило. направьте, если такое есть.
https://github.com/pythonista/CyberLib ?
Есть СyberLib, но там нельзя использовать переменные в качестве номеров пинов, а только константы.
Есть DigitalPins, там можно и то, и другое, но с константами получается всё мгновенно (как в CyberLib) а с переменными - вычисления типа Ваших. Там правда есть ещё одна вкусная фича - одновременное переключение пинов в пределах порта (одной командой). Это бывает полезно, когда что-то надо делать строго синхронно. Но у неё большой минус - она только для 328p и тинек 25-45-85. Никакие другие контроллеры она не поддерживает.
Есть ещё arhat.h, но она довольно глючная и, по заявлениям автора, заточена только на ATmega2561.
Есть ещё какая-то, сейчас не помню названия, но очень интересная - она построена на шаблонах классов - очень красиво получилось. Если хотите, поищу ссылку.
Других не знаю, но наверняка их существует ещё over9k.
Кстати, Ваши строки 23-24. Формально всё правильно, приоритеты операций именно таковы, но всё равно я бы скобки расставил - глаза режет.
ок, пасиб
Есть ещё какая-то, сейчас не помню названия, но очень интересная - она построена на шаблонах классов - очень красиво получилось. Если хотите, поищу ссылку.
Если не затруднит...
всё пытаюсь понять особнности поведения WAVGAT
Кстати, Ваши строки 23-24. Формально всё правильно, приоритеты операций именно таковы, но всё равно я бы скобки расставил - глаза режет.
Я бы где то убрал, а где то добавил.)
Есть ещё какая-то, сейчас не помню названия, но очень интересная - она построена на шаблонах классов - очень красиво получилось. Если хотите, поищу ссылку.
Если не затруднит...
Решение очень красивое
http://easyelectronics.ru/rabota-s-portami-vvoda-vyvoda-mikrokontrollero...
https://github.com/KonstantinChizhov/Mcucpp
Если не затруднит) мне в академических целях
Если в академических, то это к Евгений П.)
Аналогично.
Осталось pinMode еще написать. Да и работа с аналоговыми пинами не освещена.
Если в академических, то это к Евгений П.)
спасибо за оптимизацию. Разобраться надо конечно. Ну не программист я ниразу.
Хотел даже сказать «А вот нижние ифы надо все же на елсе ифы переделать» но потом мозг все таки заработал - дак ведь return))
А что этуфункция вернёт, если аргумент > 19 ?
Функция разорвет кристалл, не иначе.
Люди! Ау! Вы совсем с головой не дружите? Зачем менять ардуиновское чтение и писание портов на недокостыль? Ну объясните пожалуйста. Это не операционка. Это проект, однажды залитый в процессор и никогда не меняющий динамически ноги. Если уж хочется ускорится просто напишите прямо в порт в нужную ногу. Не надо их перебирать ифами. Вы ведь точно знаете какая нога куда идёт.
Функция разорвет кристалл, не иначе.
"Вдребезги напополам!") Да, хотя бы return false нужно добавить, иначе компилер должен ругаться.
Люди! Ау! Вы совсем с головой не дружите? Зачем...
Кто как хочет, так и др. Сказано же "в академических целях".)
"У нас есть ТАКИЕ приборы! Но мы вам о них не расскажем." (C)
"У нас есть ТАКИЕ приборы! Но мы вам о них не расскажем." (C)
В целом, даже опубликованный arhat.h вполне можно довести до состояния "замена Wiring" с небольшими ограничениями, в части работы с пинами, таймерами и прерываниями (кстати, там есть весь набор примитивов для PCINT тоже, чего нет в Cyberlib). Если учесть, что в конечном скетче пины назначены "железно", то можно иметь такой алгоритм разработки: пишем и отлаживаем на Wiring, а когда оно заработало переводим под arhat.h или Cyberlib с назначением пинов константно.
Люди! Ау! Вы совсем с головой не дружите? Зачем менять ардуиновское чтение и писание портов на недокостыль? Ну объясните пожалуйста. .......
Если уж хочется ускорится просто напишите прямо в порт в нужную ногу. Не надо их перебирать ифами. Вы ведь точно знаете какая нога куда идёт.
на этапе написания и отладки на макетной плате с дырками-соплями я не всегда знаю, какая нога куда пойдет после отладки и пайки, поэтому предложенные варианты могут быть удобны.
не всегда знаю, какая нога куда пойдет после отладки и пайки,
Тоже и у меня. Зачастую окончательное распределение ног устаканивается только в впроцессе разводки платы, когда стараешься развести поаккуратнее и с меньшим количеством перемычек. Хотя, даже не знаю, чем мне так не угодили перемычки - деталь как делаь, но почему-то всегда трахаюсь с минимзацией их количества.
Ну а вайринг чем неудобен?
Ну а вайринг чем неудобен?
Всем удобен, пока нет каких-то особых требований.
Вот мой нынешний проект:
1. АЦП в режиме подавления шума (wiring не поддерживает)
2. PCINT (wiring не поддерживает)
3. Таймер для равномерного (с частотой 2кГц) замера АЦП (wiring не поддерживает)
Против digitalWrite/digitalRead в этом проекте ничего не имею, но раз уж всё равно столько всего писать руками, взял и для них DigitalPins (благо там синтаксис witing'овский, только подчерк перед названием функции добавлять надо, а так всё тоже - номера пинов там и т.п.).
В результате, всё компилируется хоть в IDE, хоть в АВР-студии, и меня это по ряду причин удобно, специально так делал. Если бы я использовал wiring, в студии с компиляцией были бы проблемы - пришлось бы wiring целиком туда тащить.
Ну а вайринг чем неудобен?
а макросы из Ciberlib несколько неудобны, если нужно поменять пины в программе.
Обсуждаемые функции обе эти проблемы решают.
а макросы из Ciberlib несколько неудобны, если нужно поменять пины в программе.
Так бери DigitalPins. Там синтаксис вайринговский, типа
_digitalWrite(LED_BUILTIN, LOW);
т.е. пины менять вполне удобно.
Если пин - константа, то результат точно как у Cyberlib, если переменная, вставляется очень короткий код для вычисления.