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

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

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

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



ATTINY + GPRS

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

1

Всем привет, ни разу сам не писал под микроконтроллеры, но уже в конец прижало, надо начинать.
В общем ТЗ.
Есть устройство ПКП (охранный прибор) известной фирмы. Работает как автономно, так и в составе сети RS485 под управлением либо аппаратной "бошки", либо ПК.
Собственно необходим контроллер, который бы с одной стороны подключается к такому прибору по RS485, а с другой управлял бы каким-нибудь SIM300, налаживал связь с сервером и передавал бы на него все, что происходит на входе, и наоборот, принимал бы сообщения с сервера и отправлял бы на вход.

Код:
$regfile = "attiny13.dat"                                   'МК Attiny13
$crystal = 9600000                                          'Рабочая частота МК 9.6МГц
$hwstack = 16
$swstack = 16
$framesize = 16
Open "comb.1:9600,8,n,1" For Output As #1                   'Программный UART 1 на PB.3 TXD
Open "comb.2:9600,8,n,1" For Input As #2                    'Программный UART 2 на PB.4 RXD

Open "comb.3:9600,8,n,1" For Output As #3                   'Программный UART 3 на PB.3 TXD
Open "comb.4:9600,8,n,1" For Input As #4                    'Программный UART 4 на PB.4 RXD

Print #1 , "Program UART 1"
Print #3 , "Program UART 2"

Do

Loop
End

Эмулирую в протеусе, Выводит нормально. Но как к примеру для начала реализовать одновременное ожидание на двух портах?
Что бы если что то пришло в первый, было передано во второй и наоборот? К примеру в делфи есть события типа OnRead, и для каждого пишется свой обработчик. Просто пока я обрабатываю данные на одном порту, как не пропустить что происходит на другом?

0

2

Обмен в любом случае будет асинхронным.
Можно взять контроллер с аппаратным UART и  принимать в прерывании от "охранного прибора". С SIM300 работать уже по своей программе, беря данные из буфера и складывая их в буфер.
SIM300 как и что должен принимать/передавать? SMS или GPRS?

0

3

Я еще не разбирался в протоколе охранного прибора. Скорее всего от него не будет прерываний, его надо будет циклично опрашивать на наличие новых событий. А вот со стороны SIM300 по GPRS могут неожиданно прийти команды оправления прибором.
В общем, я так понимаю, если софтварный USART, то на нем невозможно обрабатывать RX по прерыванию, а в аппаратном уже можно. Теперь надо найти код на васике, вешающий это прерывание на аппаратный вход.

0

4

Sheleh написал(а):

Я еще не разбирался в протоколе охранного прибора. Скорее всего от него не будет прерываний, его надо будет циклично опрашивать на наличие новых событий. А вот со стороны SIM300 по GPRS могут неожиданно прийти команды оправления прибором.
В общем, я так понимаю, если софтварный USART, то на нем невозможно обрабатывать RX по прерыванию, а в аппаратном уже можно. Теперь надо найти код на васике, вешающий это прерывание на аппаратный вход.

Для начала наверное нужно все же определить передает ли охранный прибор сам свое состояние или он его возвращает в ответ на команду. Если возвращает в ответ на запрос, то можно в цикле ждать от SIM300 и дождавшись выставить SIM300 сигнал "не готов принимать" провести обмен принятого.
Пример работы с прерываниями и с буффером в аппаратном UART есть в папке samples

0

5

Как вариант, можно RX подключить на один из INT и по прерыванию делать чтение данных.

0

6

Как вариант, можно RX подключить на один из INT и по прерыванию делать чтение данных.

Интересно, а как конкретно?
В общем накидал схемку в протеусе - соединил через макс232 ATtiny13 c физическим COM-портом. К этому порту подключил SIMTerminal. Если я отправляю в ГиперТерминале "АТ", то он отвечает "ОК", а вот когда запускаю схему в протеусе, посылая с виртуального микроконтроллера "АТ", то глухо как в танке. Что не так?
http://photo.qip.ru/photo/she1eh/4234801/middle/104666049.gif

Отредактировано Sheleh (2013-09-02 17:32:23)

0

7

Sheleh написал(а):

Интересно, а как конкретно?

Очень просто, ждем срабатывание прерывания по спаду и начинаем приём данных (после приёма возвращаемся из прерывания к основным процессам).

0

8

Кто-нибудь уже работал из протеуса с физическим ком-портом? У меня даже такая схема не работает
http://she1eh.users.photofile.ru/photo/she1eh/4234801/xlarge/104675595.gif

0

9

RDW написал(а):

Очень просто, ждем срабатывание прерывания по спаду и начинаем приём данных (после приёма возвращаемся из прерывания к основным процессам).

Можно и так, только нужно в прерывании выставлять флаг что данные идут, а по приему снимать, иначе будет дергаться на каждый принимаемый бит. Да еще и таймаут вводить, вдруг посылка придет не полная или вообще это была помеха? В самом прерывании принимать нельзя, будут трудноустранимые глюки.
Мне лично больше нравится аппаратный прием. Меньше забот. И совсем уж за гранью добра и зла работать на 13 таньке с внутренним тактовом и программным UART на два устройства, ошибок будет вагон. 
Хотя две 13-х вязал между собой, но там передающая отправляла вначале 55h по которым приемная подстраивала частоту генератора  что бы был именно 55h и уже после этого пуляла строчку с инфой.

0

10

Sheleh написал(а):

Кто-нибудь уже работал из протеуса с физическим ком-портом? У меня даже такая схема не работает

Когда то пытался, но понял, что это "виртуальный секс" максимум что надежно делалось это подрыгать DTR DSR. Проще залить в кристалл и прогнать вживую.

0

11

IgorL написал(а):

Можно и так, только нужно в прерывании выставлять флаг что данные идут, а по приему снимать, иначе будет дергаться на каждый принимаемый бит. Да еще и таймаут вводить, вдруг посылка придет не полная или вообще это была помеха? В самом прерывании принимать нельзя, будут трудноустранимые глюки.

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

0

12

По поводу отладки используя реальный модем. Так и не смог заставить это работать через max232. Уже было отчаялся, но попробовал подключить контроллер напрямую к ком-порту, и заработало.
http://she1eh.users.photofile.ru/photo/she1eh/4234801/xlarge/104699576.gif

0

13

Очень просто, ждем срабатывание прерывания по спаду и начинаем приём данных (после приёма возвращаемся из прерывания к основным процессам).

Код:
$regfile = "attiny13.dat"                                   'МК Attiny13
$crystal = 9600000                                          'Рабочая частота МК 9.6МГц
$hwstack = 16
$swstack = 16
$framesize = 16

Config Int0 = Falling          'Прерывание по спаду на 0-м входе (с модема)

Open "comb.1:9600,8,n,1" For Output As #1                   'Вывод на модем
Open "comb.3:9600,8,n,1" For Output As #3                   'Вывод на виртуальный терминал
Open "comb.4:9600,8,n,1" For Input As #4                    'Прием с виртуального терминала

Dim Cmd As String * 8

On Int0 Int0input 

Enable Interrupts
Enable Int0

Do

Print #3 , "Command:"
Input #4 , Cmd
Print #1 , Cmd

Loop

Int0input:
Print #3 , "interupt"     'При возникновении ответа вывожу на терминал
Return

End

Код работает. Посылаю модему "АТ", а в ответ выводится десяток "interupt". Прерывание по спаду мы дождались. А как в прерывании получить данные, дабы записать их в буфер?
Голова кругом, не могу найти подходящего примера, подскажите пожалуйста.

Отредактировано Sheleh (2013-09-04 19:08:57)

0

14

Так прерывание используем для определения приёма данных, т.е. при приходе прерывания делаем следующее:

1. запрещаем прерывание;
2. начинаем приём данных;
3. сбрасываем бит прерывания;
4. разрешаем прерывания;
5. выходим из подпрограммы прерываний.

0

15

Код:
Int0input:
Disable Int0
R = Ischarwaiting()
 If R = 1 Then
  F1 = Inkey(#0)
  Print #3 , F1
 End If
Enable Int0
Return

Это все до чего я допер. В inkey только нули. Ничего не понимаю (

Если написать R = Ischarwaiting(#0)  - то компилятор отвечает, что функция недоступна для софтварного юарта

Подскажите пожалуйста конкретную функцию приема данных

Отредактировано Sheleh (2013-09-04 20:26:02)

0

16

Вы хотите сквозняк сделать (принял/отправил) или принял-обработал-отправил?

0

17

у меня кусок кода выглядит так:

Код:
P_rx:
   Disable Int0
   Input #1 , C Noecho
...
...
   ' INT0 = 64 INT1 = 128 регистр событий прерываний, выставляются даже если запрещены прерывания (Gifr.intf0 = 1 - Clear Int0 flag)
   Gifr = 64
   Enable Int0
Return

В этом случае основные процесс в МК останавливаются на момент приёма текстовых данных.

0

18

Если так:

Код:
Int0_sw_rx:
Disable Int0
Input #1 , C Noecho
Print #3 , C
Gifr.intf0 = 1
Gifr = 64
Enable Int0
Return

То вообще никаких эмоций

0

19

Как выглядит инициализация потока #1 и 3?

0

20

Ещё учтите один момент, все терминалы по разному завершают передачу данных, надо точно знать как закрывается передча (#0D или #0A, или #0D и #0A, или #0A и #0D).
Для этого нужно ещё конфигурировать INPUT: Config Input1 = CR , Echo = CRLF и тому подобное.

И ещё не вижу настройки настройки срабатывания прерывания "Config Int0 = Falling".

Ещё чтобы INPUT не висел, надо использовать "$timeout", для выхода из него. Цифра подбирается относительно частоты МК.

Отредактировано RDW (2013-09-04 21:31:22)

0

21

Вот последний вариант. Висит при запуске.

Код:
$regfile = "attiny13.dat"                                   'МК Attiny13
$crystal = 9600000                                          'Рабочая частота МК 9.6МГц
$hwstack = 16
$swstack = 16
$framesize = 16
$timeout = 10000
Config Int0 = Falling

Open "comb.1:9600,8,n,1" For Output As #2                   'Программный UART 1 на PB.3 TXD
Open "comb.3:9600,8,n,1" For Output As #3                   'Программный UART 3 на PB.3 TXD
Open "comb.4:9600,8,n,1" For Input As #4                    'Программный UART 4 на PB.4 RXD
Open "comb.0:9600,8,n,1" For Input As #1

Dim C As String * 8

Enable Interrupts
Enable Int0

On Int0 Int0_sw_rx

Do
Print #3 , ">"
Input #4 , C
Print #2 , C
Loop

Int0_sw_rx:
   Disable Int0
   Input #1 , C Noecho
   Print #3 , C
   Gifr.intf0 = 1
   Gifr = 64
   Enable Int0
Return

End

Если input #1 поставить в основной цикл без прерываний. То ответ выводится. На конце какой-то возврат каретки

Отредактировано Sheleh (2013-09-04 21:56:07)

0

22

Читайте внимательно, что я написал ранее.

Ещё в коде не вижу конфигурирования портов (вход/выход).

Отредактировано RDW (2013-09-04 22:13:41)

0

23

Так и не получилось принять данные по прерыванию при помощи инпута. Но мне в голову пришла бредовая идея, что можно принять данные в 2-чном виде на более низком уровне
Т.е. регистрировать каждый спад и подъем напряжения на ножке, с измерением времени между ними. И даже начало кое чего получаться, как вдруг мне не хватило памяти.
В связи с этим я решил перенести программу на tiny2313, но на ней чет ничего не работает.

Код:
$regfile = "attiny2313.dat"
$crystal = 9600000
$hwstack=40
$swstack=16
$framesize=32

Config Int0 = Falling
Config Timer0 = Timer , Prescale = 1                        'конфигурируем таймер 0

Open "comb.1:9600,8,n,1" For Output As #1                   'Программный UART 1 на PB.3 TXD
Open "comb.2:9600,8,n,1" For Input As #2                    'Программный UART 3 на PB.3 TXD
Open "comb.3:9600,8,n,1" For Output As #3                   'Программный UART 4 на PB.4 RXD


Dim C As String * 8 , I As Integer , L As Byte , S As Byte

Enable Interrupts
Enable Int0

On Int0 Int0_sw_rx
On Timer0 Pulse

Do
L = 1
Print #3 , ">"
Input #2 , C Noecho
Print #1 , C

Loop


Int0_sw_rx:
   Enable Timer0
   If L = 1 Then
      Config Int0 = Rising
      L = 0
   Else
      Config Int0 = Falling
      L = 1
   End If

   While I > 25
     Print #3 , L ;
     I = I - 9
   Wend

   I = 0
   If L = 1 Then
      Print #3 , 0 ;
   Else
      Print #3 , 1 ;
   End If
Return

Pulse:
  If I = 80 Then
   Print #3 , ""
   Disable Timer0
   I = 0
  End If
  I = I + 1
Return


End

0

24

Sheleh написал(а):

но на ней чет ничего не работает.

А кварц точно 9,6 МГц? Если тактируется от внутреннего генератора, то в Т2313 он 8 МГц.

0

25

И че делать? Когда я ставлю $crystal = 8000000 тоже ничего не работает.

0

26

А какие фьюзы прошиты?

0

27

Никакие, это я в протеусе эмулирую.

0

28

Насколько помню, они там тоже выставляются.

0

29

Хочется все же добить прием данных методом считывания единиц и нулей.
Проблема на этот раз такая: на INT0 я подал положительный уровень, и подключил кнопку, замыкающую пин на массу. По логике вещей должно сработать прерывание Falling, но ничего не происходит. В чем может быть затык?

Код:
$regfile = "attiny13.dat"                                   'МК Attiny13
$crystal = 9600000
$hwstack = 16
$swstack = 16
$framesize = 16
Config Pinb.0 = Input
Config Int0 = Falling
Open "comb.3:9600,8,n,1" For Output As #3
Enable Interrupts
Enable Int0
On Int0 Int0_sw_rx

Do
Loop

Int0_sw_rx:
     Print #3 , "OK"
Return

End

0

30

Sheleh написал(а):

Хочется все же добить прием данных методом считывания единиц и нулей.
Проблема на этот раз такая: на INT0 я подал положительный уровень, и подключил кнопку, замыкающую пин на массу. По логике вещей должно сработать прерывание Falling, но ничего не происходит. В чем может быть затык?

Все, что надо - скачать

Ошибка в том, что Вы перепутали INT0 и PCINT0!

http://s5.uploads.ru/t/2W6xH.jpg

Отредактировано sasha_1973 (2013-09-11 09:11:07)

0