Администрация форума не несёт ответственности за достоверность информации и оставляет за собой право редактировать или в особых случаях даже удалять посты без предупреждения. Спасибо за понимание.

Программирование ATMEL в BASCOM.

Информация о пользователе

Привет, Гость! Войдите или зарегистрируйтесь.



ATTINY + GPRS

Сообщений 31 страница 45 из 45

31

И вообще почитайте про протокол обмена (низкое состояние сигнализирует о старте передачи данных).

0

32

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-ом в прерывании тоже какой-то гемор. Чем дальше, тем меньше остается энтузиазма.

0

33

Mrshilov
Спасибо, сразу не обратил внимание.
В общем конструкция
B = Inkey()
A = A + Chr(b)

и
A = A + Chr(UDR)
работают в моем случает одинаково. Для примера приведу как работает, если подключаю виртуал терминал к COMPIM напрямую:

Код:
АТ

ОК

И если я читаю из COMPIM через микроконтроллер

Код:
AЄ

CЎ©«Kй

Отредактировано Sheleh (2013-09-12 15:42:46)

0

34

Я ранее описал способ, который практически одной строкой решает проблему приёма. Коль разобрались с ногами, попробуйте его ещё раз.

0

35

RDW
Попробовал
Вот таков сей был ответ: CЎяjХIю

Хочу попробовать другой модем, там только надо паять преобразователь уровней.
Есть по идее вариант пообщаться с 3G-модемом, но он в системе не отображается как сом-порт, а висит в виде модема на COM-8, что мешает изменить порт. А в протеусе можно виртуальный порт ассоциировать только с первыми четырьмя.

Вот казалось бы элементарные вещи. На Delphi я разобрался с BcomPort за 15 минут. И никаких проблем, а тут фигня какая то.

Отредактировано Sheleh (2013-09-12 15:39:54)

0

36

Если в протеусе устройства работают в одном пространстве (всё виртуальное), то вероятность рассинхрона - минимальна, но вы пытаетесь к виртуальному симулятору подцепить реальный порт - не факт, что он вообще корректно работает. Да и поди у вас не последняя купленная (обновленная) версия, а левак.. Это очень критично, когда используется не аппартные возможности МК, а симуляция (которая кстати выходит двойная (вначале эмулируется сам порт в МК, а потом вся схема эмулируется на ПС)).

О глюках протеуса всем известно...

Давно бы уже собрали на коленках или на макетке схему и экспериментировали в реале.

Отредактировано RDW (2013-09-12 15:57:50)

0

37

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)

0

38

Суть моего способа (использования прерывания от ноги INT) очень проста, как только на входе появляется низкий уровень (сигнал начала передачи стартового бита), МК запускает прерывание, в котором сразу активируется софтовый приём данных через INPUT. Да вероятность задержки есть, но если правильно сконфигурировать МК (отключить пред делитель, указать правильно его частоту и частоту скорости обмена), то должно работать. Далее как приняли данные с порта - выходим из прерывания и можно дальше обрабатывать принятые данные в основном теле программы.
Пробовал нечто подобное проделывать по байтно (используя INKEY), вот этот способ на разных схемах иногда не работал из-за доп. задержек (неоптимизированности баскома), нужно было писать вставку на ассемблере..

Отредактировано RDW (2013-09-12 17:06:38)

0

39

А у программного USART Input есть какой нибудь TimeOut? Пытаюсь читать по прерыванию, но на input все зависает.

Просто сей час нашел железку с atmega8 на борту. Аппаратный юарт используется для связи с внешним оборудованием, с ним проблем нет. А вот программный идет на модем. При чем программный висит на выводах PB0(ICP) и PB1. Т.е. не на INT0. Попробовал сделать прерывание по ICP без input просто для установления факта самого прерывания - работает. Но вот если добавляю input, то все виснет, и видимо на этой функции. Интересно, как было реализовано у создателей этой железки, наверное они замутили какое-нибудь собственное низкоуровневое чтение по времени между импульсами.

Отредактировано Sheleh (2013-12-11 07:22:47)

0

40

В программном таймаут есть, надо только подобрать значение.

0

41

$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 остается пустой, да и вообще код зависает.

0

42

Я в своё время пробовал кучу разных способов на софтварном уарте + прерывании, итог был плачевный, делать нужно полностью на инпуте (принемать целый пакет), ибо любые плясания с обработкой по 1 входному байту приводят к накаплению ошибки (смешению во времени приема битов, бэйсик создает не оптимизированный код) и как следствии - ловим глюки или вообще ничего не успеваем принимать + на разных партиях чипов/устройствах не будет стабильно работать.
В общем принимать надо пакет и завершать прием по известным нам концу строки или таймауту.
И это всё применимо к небольшим скоростям передачи данных (про потолок не знаю, но МК должен иметь запас скорости на обработку приёма данных).

0

43

Ура ТОВАРИЩИ!!! Методом долгого ковыряния и научного тыка я нашел офигенный рабочий способ чтения с программного юарта безо всяких прерываний и зависаний еще и с тайм аутом.

Код:
 
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)

0

44

Ну в коде есть ошибки алгоритма.
Впрочем есть два момента:

1. Любой GSM модуль может отдавать большой объём данных (пришла смс или передается поток данных) или ддос - надо ставить защиту от переполнения переменных. Иначе МК будет глючить.
2. (уже выше говорил об этом и видимо было не воспринято в серьёз) Это всё будет работать индивидуально, только на одном железе и только при определенных обстоятельствах (скорость, нюансы режима роботы GSM модуля, особенности схемотехники и серии партии чипов). У меня есть подобный код, который работает на одной тиньке, но когда я сделал плату на заводе и залил код в неё - ничего не работало (висело).

Ну и вообще, GSM-модуль шлет асинхронные данные (так или иначе) и никаких задержек при опросе порта не должно быть (Waitms 1000)!

В общем так совпало, что у вас всё пока работает. :D

0

45

Не разделяю вашего скепсиса, опробовал на трех микрухах разных партий. Все работает как часы. Уже реализовал алгоритм инициализации модема, подключения по GPRS к серверу.
По поводу больших входящих данных реализую проверку. Главное способ работает на сфтварном юарте, и отпала необходимость в более навороченной меге с двумя аппаратными юартами.

Ну и вообще, GSM-модуль шлет асинхронные данные (так или иначе) и никаких задержек при опросе порта не должно быть (Waitms 1000)!

Это таймаут между попытками опроса модема: опросил, ничего не пришло, ждем, и заново. Ничего не получается если долбить модем командами сразу одна за одной, ему нужно время подумать. Если модем во время паузы что-нибудь отправит, я об этом и не узнаю, да и не особо то и нужно значит. Если надо будет ожидать данные, то тут можно просто добавить прерывание, а читать не через Input, а через InKey. Сама идея была просто отказаться от глючного, зависающего Input'а.

0