Здравствуйте, прошу помощи, совета по приёму данных по uart порту. Суть заключается в том что устройство передаёт 3 байта раз в 100 мсек на скорости 600 бит, нет ни начала ни конца пакета. Приём организовал в прерывании по байтам - каждый в свою переменную. Работает, но иногда при включении начинаю принимать с середины пакета. Думаю что нужно таймером как-то считать время тишины, а потом уже начинать приём.... Но не могу с этим разобраться. Буду очень благодарен за алгоритм подобного приёма либо за пример. Спасибо.
приём данных по uart
Сообщений 1 страница 12 из 12
Поделиться22020-06-15 22:00:43
А передающее устройство включается вместе с контроллером? Если да, то можно фузами поиграться. Там можно выставить разное время запуска контроллера. Или сделать задержку на запуск устройства.
Поделиться32020-06-15 22:19:02
к сожалению могут включаться в разное время
Поделиться42020-06-15 22:29:55
Тут без шифра и де-шифра не обойтись 
Нужен стар-байт - какой душе угодно (от 000 до 255)
Еще нужна бы контрольная сумма передачи данных
Т.е. посылка будет иметь вид - стар-байт, 1-й байт данных, 2-й байт данных, 3-й байт данных, контрольная сумма.
На приемной стороне проверяешь, если стар-байт совпадает, то принимаешь всю посылку и по контрольной сумме проверяешь правильность принятого. А если нет - то нет...
Как то так, если не так - старшие товарищи поправят... 
Поделиться52020-06-15 23:41:55
А успеет ли это все контроллер принять и обработать за 100 мсек?
Поделиться62020-06-16 00:07:26
успеет
и задача простая. Сразу на вскидку несколько вариантов придумал.
Вот один,самый простой:
включили МК
таймер=0
ждём символ (варианты зависят от вашего алгоритма: через прерывание, через inputbin)
пришел символ
запуск таймера с максимально медленным счетом (делители побольше), чтобы хватало на длину одного байта при этой скорости, а лучше на три байта
ждём второй символ И опрос таймера: если время вышло, а символа нет - выход в начало программы с очиской буфера и отключением таймера
Если пришел символ - сброс таймера и то же самое для третьего символа
Поделиться72020-06-16 00:08:33
Т.е. посылка будет иметь вид - стар-байт, 1-й байт данных, 2-й байт данных, 3-й байт данных, контрольная сумма.
На приемной стороне проверяешь, если стар-байт совпадает, то ...
если человек своё делает - да
Но если у него в руках какой-то аппарат, который он хочет скрестить со своим МК - почему-бы и да? 
Отредактировано Александр Д. (2020-06-16 00:10:05)
Поделиться82020-06-16 09:16:12
устройство передаёт 3 байта раз в 100 мсек на скорости 600 бит, нет ни начала ни конца пакета.
У вас так четко никогда работать не будет. Ибо вы можете включить МК и начать принимать скажем с середины 2-го байта или начиная с третьего (в общем когда угодно). При этом весь пакет естественно сбивается (полностью вся, все 3 байта).
В таких ситуациях нужен хедар (правда и он не всегда поможет) или контрольная сумма в конце передачи.
Если этого всего нет, то максимум, что можно сделать - это придумать реалтайм анализатор этой последовательности, с описанием входного/выходного окна и четкий приём только 3-х байт. Иными словами, ждать "тишины" между пакетами, если она была, то начинать ожидание приёма 3-х байт, естественно ещё добавить обязательно таймаут при ожидании приёма (вдруг во время передачи произойдёт сбой, остановка передачи).
Или (если есть) активировать синхронную передачу данные при помощи RTS/CTS (если устройство поддерживает).
Поделиться92020-06-16 13:39:28
RTS/CTS не поддерживает, там токовая петля. Через пару часов буду пробовать. Я так понял, в общем цикле я запускаю таймер на счёт, в прерывании по приёму символа останавливаю и если время тишины к примеру больше 80 мсек начинаю принимать 3 байта. Я правильно рассуждаю?
Поделиться102020-06-16 16:36:31
Включается МК, ждет тишины 80 мс, затем только начинает ожидать приёма 3-х байт, если пришли не 3 байта, а что-то другое (это можно понять по стоповому биту и четности), то сбрасывается на ожидание паузы. Время ожидание паузы кстати можно поиграться, взять чуть меньше, но не меньше приёма 1/2 байта.
Поделиться112020-06-16 18:21:59
Вот так работает неплохо, может конечно что-то неверно написал... При включении бывает прилетает 5-10 значений нулевых, но в течении секунды восстанавливается.
Getchar:
tim = timer1
timer1 = 0
comchar = inkey()if tim > 1050 then
incr modc
Mbuf(modc) = Comcharif modc = 3 then
stop timer1
mbuf(4) = mbuf(1)
mbuf(5) = mbuf(2)
mbuf(6) = mbuf(3)
mbuf(1) = 0
mbuf(2) = 0
mbuf(3) = 0
modc = 0
sbor = 0
end if
else
modc = 0
mbuf(1) = 0
mbuf(2) = 0
mbuf(3) = 0
mbuf(4) = 0
mbuf(5) = 0
mbuf(6) = 0
waitms 2
end if
return
Поделиться122020-06-17 18:56:23
Спасибо всем кто откликнулся. 