UART+Interrupt
- Войдите на сайт для отправки комментариев
Ср, 20/01/2016 - 22:11
Меня, как всегда, тянет изобретать велосипед... По UART необходимо организовать обмен. Опрос в цикле не подходит. В скетче используется прерывание по таймеру- 10 ms. Хочется нему прикрутить проверку буфера UART, при появлении в буфере данных выставляю флажок, пока он висит - формирую строку:
void intTimer() { .....Что-то там... if (Serial.available() > 0 && readSerialFlag==0) //пришли данные из PC {readSerialFlag=1;readSerialStr();} }
Обработка полученных данных:
void readSerialStr() { recString=""; while (Serial.available()) { char c = Serial.read(); //читаем символ recString += c; //добавляем к строке if (c=='\n') { //--тут анализ строки recString----- } readSerialFlag=0; }//----while }
В результате часть данных при приеме теряется, просто обрезается текст. Для пробы поставил таймер на 100мс - и стало почти всё нормально, дальнейшее увеличение времени таймера , равно как и уменьшение- становится только хуже. Ткните ,в чем проблема, а то зациклился уже.
я думаю, что теряется у тебя при отправке, а не приёме - при отправке проверяй не равно ли место в буфере сериала нулю.
и, зачем прерывание, если и без прерывания всё должно корректно приниматься - если не принялось, то отправитель должен подождать, т.к. ты не сразу впуливаешь в сериал, а проверяешь не забит ли буфер ещё не отправленным.
в DigiUSB так делаю, как в Сериале не нашёл, но должен быть аналог tx_remaining
я думаю, что теряется у тебя при отправке, а не приёме - при отправке проверяй не равно ли место в буфере сериала нулю.
Ну такая же ситуация когда отправляю с терминала IDE Arduino.
и, зачем прерывание, если и без прерывания всё должно корректно приниматься - если не принялось, то отправитель должен подождать.
Да самому мне не нравится идея с прерыванием, но у меня для каждого из режимов работы устройства своя подпрограмма. Мне в нескольких местах вставлять проверку буфера UART - как-то тоже не очень красиво.
Ну такая же ситуация когда отправляю с терминала IDE Arduino.
сделай скетч, где у тебя отправляется строка из терминала ИДЕ в контроллер и отправляется обратно в терминал - смотри, где у тебя что теряется.
я тебе подсказал, что может теряться, когда забивается буфер в ноль.
Прерывания.
Замечание по использованию
Внутри функции обработки прерывания не работает delay(), значения возвращаемые millis() не изменяются.
Возможна потеря данный передаваемых по последовательному соединению (Serial data) в момент выполнения функциии обработки прерывания.
Переменные, изменяемые в функции, должным быть объявлены как volatile.
А еще есть разница между аппаратным и программным сериалом, прерывания там по разному работают. Это уже было тут гдето на форуме. там даже для аппаратного сериала файлики в среде правили вроде. И еще, у сериала свое прерывание есть ведь которое срабатывает при появлении данных в буфере.
Чего то я ваял с прерываниями и уартом, пока на софтварном уарте отлаживал, все работало нормально, как только после отладки перешел на аппатантый, начались глюки с приемом/передачей и прерываниями. Чего делал не помню, но запустит все удалось в итоге.
Спасибо за ответы. Тут разговор только об аппаратном сериале. То, что у сериала свое прерывание есть -да, видел, №18, думается это самый правильный вариант был бы.. файлики в среде для этого правили - тоже смотрел, но там вроде бы только для старых версий IDE ? Т.е. штатно доступно только 2 внешних прерывания получается:-(
Спасибо за ответы. Тут разговор только об аппаратном сериале. То, что у сериала свое прерывание есть -да, видел, №18, думается это самый правильный вариант был бы.. файлики в среде для этого правили - тоже смотрел, но там вроде бы только для старых версий IDE ? Т.е. штатно доступно только 2 внешних прерывания получается:-(
я не понимаю, почему ты рогом упёрся в прерывания - что у тебя такого срочного должен сериал отправить, что для этого нужно всё бросать?
Нет, конца света нет чтоб всё бросать... Повторюсь, в зависимости от команд извне, выполняется та или иная подпрограмма, т.е. в основной цикл loop она может и не вернется, так как по приходу новой команды начнется выполнение другой подпрограммы ( долго или в цикле). Поэтому не хочется во всех местах расставлять чтение буфера UART. Возможно такой вариант не ахти - из одной процедуры кидаться в другую, но это уже другой вопрос.
в зависимости от команд извне, выполняется та или иная подпрограмма, т.е. в основной цикл loop она может и не вернется, так как по приходу новой команды начнется выполнение другой подпрограммы ( долго или в цикле).
это плохая архитектура программы
*смотри в инетах "конечные автоматы".
У меня похожий вопрос возник.
Хочу повесить прерывание на таймер с целью опроса D1820, раз в секунду и управления релюшкой.
С разделением запроса и ответа, что бы не вешать основную программу.
В один из входов в прерывание делаем сброс далласа, на через секунду получаем значение.
Возник вопрос как это скажеться на работе библиотеки serial ?
Не будет ли пропускать символы.
Цель отвязать регулятор температуры от работы с GSM либо еще какими модулями через Serial.
Возник вопрос как это скажеться на работе библиотеки serial ?
Не будет ли пропускать символы.
Цель отвязать регулятор температуры от работы с GSM либо еще какими модулями через Serial.
Смотря как реализуете и какая скорость Serial. Я так понимаю Ware хотите програмный из обработчика прерывания таймера. Если обработчик прерывания таймера будет отрабатывать дольше чем время передачи 1 байта Serial то возможны проблемы. Можна организовать разрешение прерывания Serial при нахождении в обработчике прерывания таймера, но это тоже плохо.
Правильный путь подсказывает спецификация Ware. Передача каждого 0 и 1 требует выдерживать интервалы, а вот паузы между ними могут гулять в широком диапазоне. Потому если каждый вызов обработчика прерывания таймера отправит или приймет 1 бити завершится настроив таймер на некоторую паузу то все будет работать. Можно и еще сложней - таймер использовать для формирования длительностей высокого и низкого уровней (и ещё кое чего), т.е. два вызова обработчика таймера для отправки 1 бита. Это понятно не просто писать, конечный автомат в обработчике не для новичка задача, но если интересно могу отписать подробней.
Была такая идея переписать обработку 1-wire.
Пока теплиться надежда, что проще скорость сериал снизить, все равно это не критично.
Был бы FIFO в меге. Цены бы ей не было.
А можно Ваши контакты ?
Вообще, когда необходимо что то выполнить и чтоб это точно выполнилось и никто не помешал, глобально запрещают прерывания, выполняют необходимую работу и вновь разрешают прерывания.
А мы хотим, что бы две сравнительно медленные задачи выполнились.