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

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

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

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


Вы здесь » Программирование ATMEL в BASCOM. » Связь проводная и бесп-ная, интерфейсы, протоколы » Как отправить через UART последовательно несколько переменных?


Как отправить через UART последовательно несколько переменных?

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

1

Мне необходимо отправить значение нескольких переменных. В Баскоме я новичек. Предпологаю что както с помощью PRINTBIN. Но для этого наверное необходимо создать массив переменных и дальше  Printbin будет последовательно в одной посылке пересылать данные. Ну вообщем как-то так я думаю. Как создать массив не могу понять.В моем куске кода есть две переменные Chislo и Chislo2 которые и необходимо постоянно пересылать на компутер.

0

2

Забыл дать кусок кода

     Dim W As Word , Channel As Byte , Chislo As Word , B1 As Word , Chislo2 As Word , B2 As Word

    Do
If Chislo = 0 Then
For B1 = 1 To 50
Incr Chislo
Waitms 20
End If
  Print Chislo
  Next
If Chislo = 50 Then
For B1 = 1 To 50
Decr Chislo
Waitms 20
  End If
  Print Chislo
   Next

   If Chislo2 = 0 Then
For B2 = 1 To 100
Incr Chislo2
Waitms 10
End If
  Print Chislo2
  Next
If Chislo2 = 100 Then
For B2 = 1 To 100
Decr Chislo2
Waitms 10
  End If
  Print Chislo2
   Next
   Loop
        End

0

3

Да использовать надо printbin, иначе нули зажовывать будет.
Почитайте хелп в бэйсике про него, там через массив очень удобно контроллировать объёмы данных и позицию.

0

4

Я начинающий товарищ в Баскоме поэтому прошу помочь мне сделать кусок кода для понимания Ваших слов. Хелп смотрю и пытаюсь читать, но без рабочего примера тяжело соорентироваться.

0

5

Можно создать массив (в Вашем случае из двух чисел) и передавать их в цикле For. Например так:
For i = 1 To 2
  Print Chislo(i);
Next
Правда это не очень хорошо. А можно так:
Printbin Chislo(1)

0

6

Все равно не понятно.А как быть со второй переменной Chislo2 ?

0

7

По поводу кода. Насколько я понял Вам нужно передавать инкремент и декремент числа 1 и 2.
Тогда код должен быть таким:

Код:
Dim W As Word , Channel As Byte , Chislo As Word , B1 As Word , Chislo2 As Word , B2 As Word


Do
 If Chislo = 0 Then
  For B1 = 1 To 50
   Incr Chislo
   Waitms 20
   Print Chislo
  Next
 End If

 If Chislo = 50 Then
  For B1 = 1 To 50
   Decr Chislo
   Waitms 20
   Print Chislo
  Next
 End If

 If Chislo2 = 0 Then
  For B2 = 1 To 100
   Incr Chislo2
   Waitms 10
   Print Chislo2
  Next
 End If

 If Chislo2 = 100 Then
  For B2 = 1 To 100
   Decr Chislo2
   Waitms 10
   Print Chislo2
  Next
 End If

Loop
End

В Вашем коде окончание операторов IF и FOR перепутаны местами.
В этом коде в СОМ будут последовательно переданы:
0, 1, 2 ... 49
49, 48, 47 ... 0
Второе число тоже самое , но от 0 до 99.
Числа 50 и 100 не будут достигнуты, т.к. цикл от 1 до 50 и от 1 до 100, а числа меняются от 0 до 49 и 99, соответственно.
Если хотите точно до 50 и до 100, то в каждом цикле нужно добавить по 1 в значение конца цикла. Т.е. например For B2 = 1 To 101.

Отредактировано sva-don (2011-12-23 16:40:53)

0

8

Только что проверил свой вариант кода. Компилятор говорит что все хокей. Сейчас попробую в симуляторе и на терминальной программе.
Сам код такой:

         $regfile = "m128def.dat"
$crystal = 8000000
$hwstack = 128                                              'Размер аппаратного стека
$swstack = 128                                              'Размер программного стека
$framesize = 128                                            'Размер области импользуемой для преобразования
                                                             'и временного храненияя данных
                                                             'Byte - 4 bytes, Integer - 7 bytes,
                                                             'Longs - 16 bytes, Single - 24 bytes
                                                             'String -длинна слияния (монтажа) строк
                                                             'Плюс локальные LOCAL переменные,
                                                             'плюс временные VALUE (BYVAL)

$sim

Dim Chislo(1) As Word , B1 As Word , Chislo2(2) As Word , B2 As Word
Dim Idx1 As Integer

    Do
If Chislo(1) = 0 Then
For B1 = 1 To 50
Incr Chislo(1)
Waitms 20
End If
  Next
If Chislo(1) = 50 Then
For B1 = 1 To 50
Decr Chislo(1)
Waitms 20
  End If
    Next
    If Chislo2(2) = 0 Then
For B2 = 1 To 100
Incr Chislo2(2)
Waitms 10
End If
  Next
If Chislo2(2) = 100 Then
For B2 = 1 To 100
Decr Chislo2(2)
Waitms 10
  End If
   Next

For Idx1 = 1 To 2                                          'fill part of array
  Chislo(idx1) = Idx1
  Chislo2(idx1) = Idx1
                                     'assign a string
Next

For Idx1 = 1 To 2                                           'print the first 10
  Printbin Chislo(idx1) ; Chislo2(idx1)
Next
   Loop
        End

0

9

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

Printbin Chislo(idx1) ; Chislo2(idx1)

Так нельзя.
Массив должен быть ОДИН!

For Idx1 = 1 To 2                                          'fill part of array
  Chislo(idx1) = Idx1
Next

Printbin Chislo(1)

При этом будет передан весь массив Chislo(1) и Chislo(2)

Забыл отметить, что если написать так:
Printbin A(1), 5
То будут переданы первые 5 значений массива A().

Отредактировано sva-don (2011-12-23 16:51:37)

0

10

Если используем софтовый UART.
Из хелпа это работает следующем образом (пример):

Dim A(8) As Byte
Dim F As Byte

For F=1 To 8
    A(F)=F     ' заполняем для примера массив/ячейки от 1 до 8
Next F

Printbin A(1)                     ' если сделать так, то ВСЁ содержимое массива А (8 байт) выводится автоматически в порт
Printbin A(1); 3                 ' если сделать так, то только 3 байта начиная с ячейки массива А №1 выводится автоматически в порт
Printbin A(1); 3 ; A(4) ; 2  ' если сделать так, то содержимое массива А будет выводится: начиная из №1 ячейки выводятся 3 байта, а потом в след из №4 2 байта.

Если использовать хардварный UART, то можно обойтись и обычным PRINT, но там чуть по другому вывод организован.

Отредактировано RDW (2011-12-23 17:02:37)

0

11

Все равно не понятно. Если задаем только Printbin Chislo(1), в таком случае как он увидеть значение в переменной Chislo(2)?

0

12

В этом случае выводится ВЕСЬ массив начиная с указанной позиции.
Т.е. если сделать цикл/переменную вместо цифры один, то получим не просто линейный вывод, а лестницу пакетов.)

12345678
2345678
345678
45678
5678
678
78
8

Вот что получим)

Отредактировано RDW (2011-12-23 17:14:47)

0

13

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

Все равно не понятно. Если задаем только Printbin Chislo(1), в таком случае как он увидеть значение в переменной Chislo(2)?

Это уже проблемы компилятора.
Главное, что он это делает.

Отредактировано sva-don (2011-12-23 17:15:08)

0

14

Не забывайте, массив имеет жесткий размер и значит есть четкие параметры вывода всегда.

0

15

Думаю, что при проектировании архитектуры изделия программист и электронщик должны совместно определить протоколы ввода/вывода, поэтому объем данных передаваемых/принимаемых контроллером жестко определен. Понимаю, что бывают случаи, когда эти параметры невозможно определить заранее, но для этого и подходы к проектированию будут другими. Можно сказать, что в BASCOMе процессы обмена по СОМ выполнены весьма впечатляюще. За это Марку огромное спасибо. Если кто писал на С, то должен это оценить.

0

16

Если по размышлять на эту тему, то при не лимитированной длине пакетов/протокола можно вообще не заморачиваться с массивами и просто выводить по одному байту данные через переменную тем же printbin-ом. Да, получатся задержки между посылками, но зато гибко. Но вообще когда нужно что и куда послать/принять тщательно продумываются/взвешиваются все достоинства и недостатки.

0

17

Похоже до меня начинает доходить. Итак когда декларируем переменные. Скобками () определяем что это массив, соответственно имя массива и тип переменных в массиве. В скобках определяется количество ячеек в которые будут ложитсья наши переменные Dim Chislo(2) As Word. Дальше в процессе чтения строк компилятор будет знать что Chislo(1) эта переменная с одноименного массива первой ячейки (или бита), Chislo(2) эта переменная с одноименного массива второй ячейки. Ну а Printbin Chislo(1), я так понял, отправит в UART последовательно сначала переменную
Chislo(1), а затем Chislo(2).

Config Printbin = Extended
Config Com1 = Dummy , Synchrone = 0 , Parity = None , Stopbits = 1 , Databits = 8 , Clockpol = 0
Dim Chislo(2) As Word , B1 As Word , B2 As Word
Dim Idx1 As Integer

    Do
If Chislo(1) = 0 Then
For B1 = 1 To 50
Incr Chislo(1)
Waitms 20
End If
  Next
If Chislo(1) = 50 Then
For B1 = 1 To 50
Decr Chislo(1)
Waitms 20
  End If
    Next
    If Chislo(2) = 0 Then
For B2 = 1 To 100
Incr Chislo(2)
Waitms 10
End If
  Next
If Chislo(2) = 100 Then
For B2 = 1 To 100
Decr Chislo(2)
Waitms 10
  End If
   Next

For Idx1 = 1 To 2
  Chislo(idx1) = Idx1
   Next
    Printbin Chislo(1)
   Loop
        End

Подскажите я все правильно понял или нет?

0

18

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

If Chislo(1) = 0 Then
For B1 = 1 To 50
  Incr Chislo(1)
  Waitms 20
End If
Next

Опять у тебя путаница с IF и FOR! Я выше уже поправлял. Операторы END IF и NEXT нужно поменять местами! Это первое.
Принцип передачи ты понял правильно. Т.е. если написать
PRINTBIN A(1), то будет передан весь массив до конца (255 байт мах).
PRINTBIN A(1), 5, будут переданы 5 байт массива А.
Но в твоем случае ты определил число Chislo(2) As Word, а WORD это 2 байта, поэтому перед передачей необходимо разбить WORD на 2 байта операторами HIGH и LOW например так:

DIM B(4) As Byte
Dim Chislo(2) As Word
B(1)=High(Chislo(1))
B(2)=LoW(Chislo(1))
B(3)=High(Chislo(2))
B(4)=LoW(Chislo(2))
Printbin B(1)

Будут выданы 4 байта. В приемнике их нужно вновь объединить в WORD.

Отредактировано sva-don (2011-12-26 16:01:29)

0

19

Не стал плодить новые темы, спрошу здесь . Подскажите кто в курсе , как узнать длину пакета UART т.е. сколько байт предстоит получить ? UART использую хардовый .

0

20

dimon-790 написал(а):

как узнать длину пакета UART т.е. сколько байт предстоит получить

Можно указать в начале самого пакета, если протокол неизвестен, то через буфер.

Код:
Config Serialin = Buffered , Size = 255
Dim Na As String * 1
Enable Interrupts
'Очистим буфер
CLEAR SERIALIN
Do
 'Получим символ
  If Ischarwaiting() = 1 Then                           
    Input Na     
  End If                                           
 Wait 1                                                   
Loop

Потом подсчитать сколько в буфере не нулевых байт. Недостатки Мах размер буфера 255.

0

21

Спасибо sva-don, с Input правда у меня ничего не вышло , только через waitkey или inputbin. В пакетах походу только числа. Пакеты имеют такой формат: 11 03 02 50 00 С9 или так:  11 03 01 05 53 я так понимаю что 1-й это у нас заголовок 2-й адрес а 3-й байт и указывает на число байт кот. будет идти за ним , поледний по всей видимости контр.сумма. Приём у меня сделан пока так:
Dim  Rxt_1(8) As Byte
rx:
Inputbin Rxt_1(1)
Gosub Show_disp
return
Show_disp:
lcd                                 Rxt_1(1) Rxt_1(2) и т.д
на иникатор выводится:              СВ 00 АС 11 03 04 55 00
а если посмотреть в терминалке: 11 03 04 55 00 СВ 00 6В

Не могу ни как понять как реализуется приём пакета ? и почему один байт не совпадает ?

Потом подсчитать сколько в буфере не нулевых байт.

так у меня и нули в пакетах , тоже проходят , как с ними быть ?

Отредактировано dimon-790 (2012-02-02 12:05:13)

0

22

Проблему с несовпадающим байтом решил , благодоря sva-don сделал по вашему примеру, только вместо строковой использовал байтовый массив и вместо input соотв. inputbin. Теперь если смотреть по порядку от 1 до 8-го строчка индикатора выглядит так : 00 6В 11 03 04 55 00 СВ , вопрос о порядке очереди , принимаемых байт пакета пока остаётся открытым...

Отредактировано dimon-790 (2012-02-02 12:14:42)

0

23

Поигрался с размерами буфера , вместо 50-ти поставил 8 теперь всё как должно быть по порядку  один в один с терминалкой. Но терзают смутуные сомнения , правильно ли я сделал а если надо буде принять  например 10-ть байт ?

0

24

Что это за устройство с которого ведется прием?

0

25

промышленный контроллер , управляется по rs485 принимаю на своё уст-во на меге 8535

0

26

Ооооооооо, тогда у него есть протокол. Может просто запросить у разработчика?

0

27

да, еслиб разработчик не зажимал-бы протокол , не было-бы и данной проблемы, впрочем длина буфера уже отошла на второй план. Счаз насущная проблема контр.сумма , как её расчитать ? никак не могу понять .

Отредактировано dimon-790 (2012-02-03 21:19:30)

0

28

В Basic-е есть функции CRC8 и CRC16. Попробовать принятую строку обработать ими и сравнить с тем, что получается.

0

29

ещё есть checksum, пробовал всё это , правда наскоком, пока безрезультатно...

0

30

Там разработчики часто придумывают свои КС, и прочее, для несовместимости со стандартным софтом (типа SCADA систем, или делают отдельно библиотеки протоколов).
Можете сказать конкретно, что за устройство ? Если у меня есть готовый протокол, я его Вам выложу (сам иногда реверсом занимаюсь по причине жадности разработчиков)
Нули похожи на разделители полей
А контрольная сумма у Вас точно есть ? Ее не все применяют

0


Вы здесь » Программирование ATMEL в BASCOM. » Связь проводная и бесп-ная, интерфейсы, протоколы » Как отправить через UART последовательно несколько переменных?