Страница 1 из 2
Прием передача даных (организация командной строки)
Добавлено: Вт фев 17, 2009 12:59:03
Melkij
Кто сталкивался и делал такое?
Никак не могу понять как организовать командную строку, которая не будет мешать остальному коду.
Ситуация значит такая:
Работает код в цикле while()
Нужно получить от МК по com, припустим команду "t" в ответ эхо "t" дальше "myhour = новое значение" (ввожу новое значении часов) потом присваиваю rtc_set_time(myhour,mymin,mysec).
Делаю так:
На примере кода что сгенерил cvavr:
ATMega32 4Mhz(внутрений)
Код: Выделить всё
char command;
while (1)
{
PORTB.2 = 0;
if ( (command = getchar()) == 't')
{
putchar('t');
}
PORTB.2 = 1;
};
Ну пусть пока так будет.
Значит что выходит:
PORTB.2 = 0
потом он висит и ждет пока не прийдет команда, после чего аж только
PORTB.2 = 1
и по кругу
А мне нужно:
PORTB.2 = 0
PORTB.2 = 1
по кругу
и проверка что там пришло с сом
Подскажите как это организовать.
Есть догадка что нужно таймером делать.
Если можно то примерчик

Добавлено: Вт фев 17, 2009 14:07:44
pirotehnick
Я делал что-то подобное, т.е. организовывал самодельный протокол через USART.
См. здесь
http://radiokot.ru/forum/viewtopic.php? ... ight=usart
Если нужна более обновлённая версия проги, то могу скинуть...
Добавлено: Вт фев 17, 2009 15:01:01
ARV
самое простое (и самое неудачное) решение - перед
if сделать еще одну проверку - на прием символа:
Код: Выделить всё
if(UCSRA & (1<<RXC)){// тут уже ваша проверка принятой команды
}
то есть считывать принятый символ только тогда, когда он на самом деле пришел.
Добавлено: Вт фев 17, 2009 15:26:30
Melkij
ARV писал(а):самое простое (и самое неудачное) решение - перед if сделать еще одну проверку - на прием символа
А если удачное, то как?
В чем тогда проблема этого решения?
Добавлено: Вт фев 17, 2009 16:34:36
ARV
Melkij писал(а):ARV писал(а):самое простое (и самое неудачное) решение - перед if сделать еще одну проверку - на прием символа
А если удачное, то как?
В чем тогда проблема этого решения?
проблема в том, что когда в вашей команде будет больше одного символа, все равно начнутся задержки на прием всей строки.
а решение такое: все "непрерывные" процессы делать по прерываниям таймера (в вашем случае это переключение уровня на пору), а в основном цикле терпеливо ждать и обрабатывать символы команды.
можно, как давно-давно рекомендовал Yellow Tiger, сделать наоборот: по прерываниям от СОМ-порта принимать строку-команду в буфер, а когда примется вся команда - устанавливать флажок для основного цикла, что пора провести анализ команды. этот вариант все равно приведет к тому, что периодичность "главного" процесса будет нарушаться в момент анализа
Добавлено: Вт фев 17, 2009 21:50:26
asteroid7
Melkij
Такие задачи делаются по прерыванию "пришёл байт". В прерывании, если нужно, соединяете символы в строку, её и сравниваете с нужной. Там же, отдаёте эхо.
...
ATMega32 4Mhz(внутрений) ...
Даже и не думайте про внутренний RC с аппаратным UART, задолбаетесь не по детски. Только UART-овский кварц.
На кварце 7372800, уарте 115200 и С коде легко сравниваются строки в 15 символов.
Добавлено: Вт фев 17, 2009 22:55:38
mackerel
Ну, не стоит преувеличивать. Если есть частотомер - никаких проблем, программно частота настраивается достаточно точно. Тем более, для такой смешной скорости, как 9600.
В своё время на внутреннем 8 MHz с программной подстройкой делали 38400 без всяких проблем. Во всём требуемом диапазоне температур и напряжений питания.
Ну, без частотомера - нереально, да.
Добавлено: Ср фев 18, 2009 00:59:44
Lonleystranger
Сам когда-то делал: прерывание по приему символа, проверка на 13 символ(новой строки), до поступления этого символа -->в буфер в ОЗУ(фикс макс размер, который тоже проверяем при вводе символа). Когда поступает 13 символ-обрабатываем, стираем буфер. Вот собсна и все.
Добавлено: Ср фев 18, 2009 07:07:22
Mamonth
Если команды будут определенной длины то есть смысл создать глобальный массив и последовательно пихать в него данные. Плюс инкрементировать счетчик. Как только набрали полный пакет - обрабатываем. Данные ловить через прерывание по приему, проверяя пришел ли байт. См. выше.
Если длина пакета не определена, то есть смысл определять конец посылки по символу (в вашем случае "ввод"). Т.е. опять же складываем в массив данные, инкрементируем счетчик (чтобы не забыть куда писали) и проверяем, является ли принятый символ "ввод". Опять же все по прерыванию.
Затем, либо с обработчика прерывания вызываем процедуру обработки команды, либо выставляем "флаг" - глобальная переменная, например AllowOperateCommand. В основном цикле (main) уже проверяем этот флаг и если необходимо - обрабатываем. Дальше возможны вариации и прочее...
Добавлено: Ср фев 18, 2009 10:15:25
asteroid7
mackerel
Нисколько не преувеличил.

Речь то идёт об аппаратном.
Программным UART-ом с 8MHz я нормально передавал и принимал на скорости 115200.
А стабильность внутреннего RC в мегах это уплыв частоты >1000Hz на 1 градус С или изменения питания на 10 мВ.
Добавлено: Ср фев 18, 2009 17:50:16
mackerel
asteroid7 писал(а):mackerel
Нисколько не преувеличил.

Речь то идёт об аппаратном.
Программным UART-ом с 8MHz я нормально передавал и принимал на скорости 115200.
А стабильность внутреннего RC в мегах это уплыв частоты >1000Hz на 1 градус С или изменения питания на 10 мВ.
Так и я про аппаратный, естественно!
А стабильность внутреннего генератора вполне достаточна (согласно DataSheet), причём ещё нужно учесть, что питание-то не особо и плывёт. Ну, если стабилизатор нормальный, конечно. Но даже пресловутые 1000Hz это всего 0.0125% от 8MHz. Я почему так уверенно говорю - в своё время пришлось это всё очень тщательно считать, изделие было достаточно серьёзное. (Работает до сих пор, тьфу-тьфу).
Не, ну, конечно, если задуть ему диапазон от -50 до +85 C...
Добавлено: Ср фев 18, 2009 22:43:29
asteroid7
Немного от темы уходим, но, надеюсь, модераторы не порежут эту ветку.
mackerel писал(а):
Так и я про аппаратный, естественно!
...
Вот тут становится интересно.
mackerel писал(а):
...
В своё время на внутреннем 8 MHz с программной подстройкой делали 38400 без всяких проблем.
...
Что за программную подстройку Вы имели ввиду? Давайте примем, что напряжение стабильное, а температура комнатная +10..+30С.
Добавлено: Ср фев 18, 2009 22:56:56
smac
asteroid7 писал(а):Что за программную подстройку Вы имели ввиду? Давайте примем, что напряжение стабильное, а температура комнатная +10..+30С.
Не могу утверждать что имел ввиду
mackerel однако существуют алгоритмы программной подстройки тактовой частоты (с помощью регистра OSCALL) при имеющемся часовом кварце, подключенном к выводам таймера (есть соответсвующий аппнот от атмела, если вам интересно могу найти ссылку или сами поищите на сайте атмела - по моему AVR055). Либо можно подстроить тактовую частоту по определенному символу (байту) переданному по уарт (самый удобный байт 0хАА) но в этом случае нужно изобретать какой-то алгоритм синхронизации. Также есть возможность подстраивать генератор скорости обмена уарт записью нужных значений в регистр UBRR.
Добавлено: Чт фев 19, 2009 00:25:40
mackerel
smac писал(а):asteroid7 писал(а):Что за программную подстройку Вы имели ввиду? Давайте примем, что напряжение стабильное, а температура комнатная +10..+30С.
Не могу утверждать что имел ввиду
mackerel однако существуют алгоритмы программной подстройки тактовой частоты (с помощью регистра OSCALL)
Да, естественно, с пом. регистра OSCCAL!
И, честно говоря, больше ничего не нужно - ну, кроме частотомера.
И UART настраивается на номинал (можно было, конечно и им поиграться, но в моём случае оказалось, что не нужно). Из "тонкостей (а они, конечно, есть, как и в любом деле) существенно учесть тенденцию изменения частоты при изменении температуры - т.е. , например выставить частоту при 25 C чуть меньше, зная, что при повышении температуры она изменится в "плюс". Ну, в таком роде...
Ещё раз повторяю - всё это уже пройдено и проверено экспериментально.
Добавлено: Пт фев 20, 2009 09:25:04
asteroid7
mackerel
Получается, что Вы использовали либо свой протокол обмена (например с синхроимпульсами), либо параллельно аппаратному UARTу делали программное слежение за началом-концом приёма байта.
Так это есть далеко не аппаратный UART.
Подобную задачу я обдумывал, но она была быстро отброшена, как неоправданная по затратам процессорного времени или узкого применения из за хитрого протокола по отношению к одному кварцу.
Добавлено: Пт фев 20, 2009 09:39:07
ARV
asteroid7 писал(а):mackerel
Получается, что Вы использовали либо свой протокол обмена (например с синхроимпульсами), либо параллельно аппаратному UARTу делали программное слежение за началом-концом приёма байта.
Так это есть далеко не аппаратный UART.
Подобную задачу я обдумывал, но она была быстро отброшена, как неоправданная по затратам процессорного времени или узкого применения из за хитрого протокола по отношению к одному кварцу.
какие-то странные выводы и утверждения.
девайс на Мк со связью через СОМ-порт делается под довольно узкие задачи, и, обычно, под особый протокол. ничего не мешает в этом протоколе предусмотреть по инициативе компьютера посылку каждую секунду байта 0x55 до тех пор, пока в ответ не придет заранее определенная строка, например, "READY". МК же после старта непрерывно измеряет период имульсов на линии RX (надеюсь, это не проблема). Зная, что ему посылается именно 0x55, он элементарно вычисляет по периоду импульсов частоту работы СОМ-порта со стороны компа и настраивает свой USART уже на эту скорость. при этом. т.к. замер частоты ведется с тем же самым тактовым генератором МК, что будет использоваться для тактирования USART, автоматически получаются правильные значения всех регистров и т.п. - вот вам и автонастройка на скорость.
не вижу огромных затрат процессорных ресурсов на такую автонастройку. не вижу проблемы в том, что это как бы "свой протокол". не вижу повода утверждать, что это не аппаратный UART.
Добавлено: Пт фев 20, 2009 21:33:20
mackerel
asteroid7 писал(а):mackerel
Получается, что Вы использовали либо свой протокол обмена (например с синхроимпульсами), либо параллельно аппаратному UARTу делали программное слежение за началом-концом приёма байта.
Так это есть далеко не аппаратный UART.
Подобную задачу я обдумывал, но она была быстро отброшена, как неоправданная по затратам процессорного времени или узкого применения из за хитрого протокола по отношению к одному кварцу.
Ну, вот те на... Какой "свой протокол"? Какое "программное слежение"? Где я хоть полслова про это писал??? Я же объяснил - самый что ни есть штатный аппаратный UART!
Просто предварительно (один раз на период жизни изделия) подстроена частота внутреннего RC генератора - причём самыми что ни есть штатными средствами - регистром OSCCAL (рекомендую почитать про него в Datasheet).
Если это почему-то кажется сложным (или частотомера нет - что, вообще-то нехорошо - вещь полезная) - можно использовать и способ, описанный
ARV. Тоже не бог весть какая сложность.
Ну и, конечно, им следует воспользоваться, если питание и температура меняются уж в очень больших пределах.
Добавлено: Сб фев 21, 2009 19:36:00
asteroid7
ARV
А какой смысл нагромождать протокол. И так скорость небольшая, ещё и байты лишние передавать. Про паузу не забыть.
По нагрузке ресурсов используется как минимум один 16 битный таймер и внешнее прерывание, имеющее высокий приоритет. Остальные прерывания должны не оказывать влияния на них. Получается, что связь становится основной программой, а остальное работает, как второстепенное приложение к ней.
Таймеры и прерывания никогда лишними не бывают. Тем более, уже есть полноценный железный UART. Почему над ним нужно извращаться из за одного копеечного кварца.
Добавлено: Сб фев 21, 2009 19:42:30
asteroid7
mackerel
А как у Вас общая частота менялась изменяя OSCCAL на единицу?
По ДШ это примерно 50-60KHz…
Добавлено: Сб фев 21, 2009 21:06:50
mackerel
asteroid7 писал(а):mackerel
А как у Вас общая частота менялась изменяя OSCCAL на единицу?
По ДШ это примерно 50-60KHz…
Если честно - просто не помню, не вчера это было, и даже не год назад.
Но "справедливо по порядку величины"
А по поводу "копеечного кварца" - в смысле, лучше его поставить и не мучаться - полностью согласен. Только, увы, не всегда это возможно. И даже не только по экономическим причинам (как в моём случае).