И вообще почитайте про протокол обмена (низкое состояние сигнализирует о старте передачи данных).
ATTINY + GPRS
Сообщений 31 страница 45 из 45
Поделиться322013-09-11 19:48:28
sasha_1973
Спасибо, действительно, перепутал ногу.
В общем прием на низком уровне освоить пока не могу. Очень не стабильно получается при замере времени между изменениями уровней. Наверное это надо делать на асме.
В общем дабы не терять времени, решил освоить хотя бы аппаратный порт. Но и тут фигня какая то.
$regfile = "attiny2313.dat" $crystal = 8000000 $baud = 9600 Dim A As String * 8 On Urxc Onrxread Enable Interrupts Enable Urxc Do If A <> "" Then Print A A = "" End If Waitms 100 Loop Onrxread: A = A + Inkey() Return End
Если символы идут по одному, то вроде читается. Но если в порт приходит несколько, например "ОК", то выглядит это как "є5я"
С input-ом в прерывании тоже какой-то гемор. Чем дальше, тем меньше остается энтузиазма.
Поделиться332013-09-12 07:50:42
Mrshilov
Спасибо, сразу не обратил внимание.
В общем конструкция
B = Inkey()
A = A + Chr(b)
и
A = A + Chr(UDR)
работают в моем случает одинаково. Для примера приведу как работает, если подключаю виртуал терминал к COMPIM напрямую:
АТ ОК
И если я читаю из COMPIM через микроконтроллер
AЄ CЎ©«Kй
Отредактировано Sheleh (2013-09-12 15:42:46)
Поделиться342013-09-12 11:02:58
Я ранее описал способ, который практически одной строкой решает проблему приёма. Коль разобрались с ногами, попробуйте его ещё раз.
Поделиться352013-09-12 15:30:29
RDW
Попробовал
Вот таков сей был ответ: CЎяjХIю
Хочу попробовать другой модем, там только надо паять преобразователь уровней.
Есть по идее вариант пообщаться с 3G-модемом, но он в системе не отображается как сом-порт, а висит в виде модема на COM-8, что мешает изменить порт. А в протеусе можно виртуальный порт ассоциировать только с первыми четырьмя.
Вот казалось бы элементарные вещи. На Delphi я разобрался с BcomPort за 15 минут. И никаких проблем, а тут фигня какая то.
Отредактировано Sheleh (2013-09-12 15:39:54)
Поделиться362013-09-12 15:56:10
Если в протеусе устройства работают в одном пространстве (всё виртуальное), то вероятность рассинхрона - минимальна, но вы пытаетесь к виртуальному симулятору подцепить реальный порт - не факт, что он вообще корректно работает. Да и поди у вас не последняя купленная (обновленная) версия, а левак.. Это очень критично, когда используется не аппартные возможности МК, а симуляция (которая кстати выходит двойная (вначале эмулируется сам порт в МК, а потом вся схема эмулируется на ПС)).
О глюках протеуса всем известно...
Давно бы уже собрали на коленках или на макетке схему и экспериментировали в реале.
Отредактировано RDW (2013-09-12 15:57:50)
Поделиться372013-09-12 16:03:59
RDW
Да я вот тоже думаю, что херня какая то с этой эмуляцией получается.
В общем удалось поменять ком-порт 3G модема (тупо в диспетчере устройств разрешил показывать скрытые устройства, и удалил все ком-порты, кроме аппаратного. В процессе перетыкивания 3Gмодема, он таки сел на COM4)
HдISЄJ’U5…
VФЪjJІjmЉ…•ФЪjJІjmЉ
…•ФЪjJІjmЉ
…•ФЪjJІjmЉ
…©«Kй
…•ФЪjJІjmЉ
…©«Kй
…©«Kй
…©«Kй
…•ФЪjJІjmЉ
…•Фф’uЄrTч1LbБ±„jљўВєХ¦Xђб
Хотя опять же таки если подцепить виртуальный терминал на ком-порт, то все вполне читабельно. Видимо косяк протеуса.
Отредактировано Sheleh (2013-09-12 16:08:42)
Поделиться382013-09-12 17:03:14
Суть моего способа (использования прерывания от ноги INT) очень проста, как только на входе появляется низкий уровень (сигнал начала передачи стартового бита), МК запускает прерывание, в котором сразу активируется софтовый приём данных через INPUT. Да вероятность задержки есть, но если правильно сконфигурировать МК (отключить пред делитель, указать правильно его частоту и частоту скорости обмена), то должно работать. Далее как приняли данные с порта - выходим из прерывания и можно дальше обрабатывать принятые данные в основном теле программы.
Пробовал нечто подобное проделывать по байтно (используя INKEY), вот этот способ на разных схемах иногда не работал из-за доп. задержек (неоптимизированности баскома), нужно было писать вставку на ассемблере..
Отредактировано RDW (2013-09-12 17:06:38)
Поделиться392013-12-11 05:33:06
А у программного USART Input есть какой нибудь TimeOut? Пытаюсь читать по прерыванию, но на input все зависает.
Просто сей час нашел железку с atmega8 на борту. Аппаратный юарт используется для связи с внешним оборудованием, с ним проблем нет. А вот программный идет на модем. При чем программный висит на выводах PB0(ICP) и PB1. Т.е. не на INT0. Попробовал сделать прерывание по ICP без input просто для установления факта самого прерывания - работает. Но вот если добавляю input, то все виснет, и видимо на этой функции. Интересно, как было реализовано у создателей этой железки, наверное они замутили какое-нибудь собственное низкоуровневое чтение по времени между импульсами.
Отредактировано Sheleh (2013-12-11 07:22:47)
Поделиться402013-12-11 10:18:18
В программном таймаут есть, надо только подобрать значение.
Поделиться412013-12-11 11:32:45
$timeout = 1000 - Этой строкой выставляется значение?
В общем кое чего начало получаься
$regfile = "m8def.dat" $crystal = 16000000 $hwstack = 40 $swstack = 16 $framesize = 32 $timeout = 1000 Config Portd.6 = Output 'Светодиод зеленый Config Portd.3 = Output 'питание модема Config Pind.0 = Input ' Конфигурация вывода RxD, приёмник USART Config Pind.1 = Output ' Конфигурация вывода TxD, передатчик USART Open "comd.2:9600,8,n,1" For Input As #1 'Программный UART 0 на PB.0 TXD Open "comb.1:9600,8,n,1" For Output As #2 'Программный UART 1 на PB.1 RXD Config Timer1 = Timer , Prescale = 256 Config Int0 = Falling On Int0 Int0_rx Enable Interrupts Enable Int0 Dim S As String * 40 Dim R As String * 40 Dim B As String * 40 Dim T As Word Portd.6 = 0 Portd.2 = 1 Portd.3 = 1 Do S = "" R = "ATE0" Print R Print #2 , R Waitms 200 S = ">" + S Print S Portd.6 = 1 Waitms 1000 Portd.6 = 0 Waitms 1000 Loop Int0_rx: Disable Int0 Input #1 , B Noecho Print B S = S + B Gifr.intf0 = 1 Gifr = 64 Enable Int0 Return
Вот этот код работает прямо в железе, НО! Если убрать Print B (а он там по идее нафиг не нужен) из Int0_rx переменная S остается пустой, да и вообще код зависает.
Поделиться422013-12-11 12:33:33
Я в своё время пробовал кучу разных способов на софтварном уарте + прерывании, итог был плачевный, делать нужно полностью на инпуте (принемать целый пакет), ибо любые плясания с обработкой по 1 входному байту приводят к накаплению ошибки (смешению во времени приема битов, бэйсик создает не оптимизированный код) и как следствии - ловим глюки или вообще ничего не успеваем принимать + на разных партиях чипов/устройствах не будет стабильно работать.
В общем принимать надо пакет и завершать прием по известным нам концу строки или таймауту.
И это всё применимо к небольшим скоростям передачи данных (про потолок не знаю, но МК должен иметь запас скорости на обработку приёма данных).
Поделиться432013-12-14 10:36:09
Ура ТОВАРИЩИ!!! Методом долгого ковыряния и научного тыка я нашел офигенный рабочий способ чтения с программного юарта безо всяких прерываний и зависаний еще и с тайм аутом.
Dim S As String * 40 Dim R As String * 40 Declare Function S_input(byval Timewait As Long) As String * 40 Do R = "ATE0" Print R 'отправляем на аппаратный юарт для целей наблюдения/отладки Print #2 , R 'отправляем на софтварный юарт, в модем S = S_input(40000) 'моя функция инпута 40000-количество циклов проверки inKey Print S Waitms 1000 Loop Function S_input(byval Timewait As Long) As String * 40 Local T As Word , B As Byte T = 0 S_input = "" While T < Timewait B = Inkey(#1) If B <> 0 And B <> 10 And B <> 13 Then S_input = S_input + Chr(b) 'если inkey не пуст, не перевод каретки T = T + 1 Wend If S_input = "" Then S_input = "TimeOut" 'если S так и не изменился за время работы цикла, то сообщаем о таймауте, хотя и не обязательно End Function Print S
Отредактировано Sheleh (2013-12-14 11:32:23)
Поделиться442013-12-14 12:00:01
Ну в коде есть ошибки алгоритма.
Впрочем есть два момента:
1. Любой GSM модуль может отдавать большой объём данных (пришла смс или передается поток данных) или ддос - надо ставить защиту от переполнения переменных. Иначе МК будет глючить.
2. (уже выше говорил об этом и видимо было не воспринято в серьёз) Это всё будет работать индивидуально, только на одном железе и только при определенных обстоятельствах (скорость, нюансы режима роботы GSM модуля, особенности схемотехники и серии партии чипов). У меня есть подобный код, который работает на одной тиньке, но когда я сделал плату на заводе и залил код в неё - ничего не работало (висело).
Ну и вообще, GSM-модуль шлет асинхронные данные (так или иначе) и никаких задержек при опросе порта не должно быть (Waitms 1000)!
В общем так совпало, что у вас всё пока работает. 
Поделиться452013-12-15 13:21:32
Не разделяю вашего скепсиса, опробовал на трех микрухах разных партий. Все работает как часы. Уже реализовал алгоритм инициализации модема, подключения по GPRS к серверу.
По поводу больших входящих данных реализую проверку. Главное способ работает на сфтварном юарте, и отпала необходимость в более навороченной меге с двумя аппаратными юартами.
Ну и вообще, GSM-модуль шлет асинхронные данные (так или иначе) и никаких задержек при опросе порта не должно быть (Waitms 1000)!
Это таймаут между попытками опроса модема: опросил, ничего не пришло, ждем, и заново. Ничего не получается если долбить модем командами сразу одна за одной, ему нужно время подумать. Если модем во время паузы что-нибудь отправит, я об этом и не узнаю, да и не особо то и нужно значит. Если надо будет ожидать данные, то тут можно просто добавить прерывание, а читать не через Input, а через InKey. Сама идея была просто отказаться от глючного, зависающего Input'а.