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

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

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

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


Вы здесь » Программирование ATMEL в BASCOM. » Вопросы - ответы » Помогите разобратся с приемом по RS-232


Помогите разобратся с приемом по RS-232

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

1

Всем доброго времени суток! Задача у меня стоит в следуюшем , нужно принять НЕХ  по СОМ порту, которые передаются с программы.
Есть программа , которая передает НЕХ данные (но в нем только цифры) по СОМ , ну и соответственно  контроллер который их должен принять.
Не получается следующие:
данные вроде бы и принимаются , но - если в таймере стоит ( Prescale = 256) то при этом ужасно мерцают индикаторы , если поставить (Prescale = 64) данные тоже передаются но уже не правильные , с провалами - выпадают некоторые цифры , когда ставишь (Prescale = 8) индикаторы показывают идеально , но зато очень трудно передать данные по СОМ.
Перечитал почти весь интернет но все примеры сводятся к работе в терминале и передачи через INPUT. Может данные нужно не в НЕХ передовать в байтах
(программу для компа сам писал могу исправить на передачу по байтам), но как настроить прием для этого.
Если нужно вот архив с программами и протеус
вот код программы

Код:
$regfile = "m8def.dat"
$crystal = 4000000

$baud = 9600

Ddrb = &B11111111


Dim A(16) As Byte
Dim A1 As String * 1
Dim A2 As String * 1
Dim A3 As String * 1
Dim A4 As String * 1
Dim A5 As String * 1
Dim A6 As String * 1
Dim A7 As String * 1
Dim A8 As String * 1
Dim A9 As String * 1
Dim A10 As String * 1
Dim A11 As String * 1
Dim A12 As String * 1
Dim A13 As String * 1
Dim A14 As String * 1
Dim A15 As String * 1
Dim A16 As String * 1
Dim Rs As String * 16                                       'переменная для приема через RS-232
Dim L As Byte
Dim Ledout As Byte


Config Timer0 = Timer , Prescale = 8
On Timer0 Indication
Enable Timer0
Enable Interrupts



Do

Rs = "1234567890123456"
'Input Rs
Stop Timer0
A1 = Mid(rs , 1 , 1)                                        'извлекаем данные из массива и переводим из НЕХ
A(1) = Val(a1)
A2 = Mid(rs , 2 , 1)
A(2) = Val(a2)
A3 = Mid(rs , 3 , 1)
A(3) = Val(a3)
A4 = Mid(rs , 4 , 1)
A(4) = Val(a4)
A5 = Mid(rs , 5 , 1)
A(5) = Val(a5)
A6 = Mid(rs , 6 , 1)
A(6) = Val(a6)
A7 = Mid(rs , 7 , 1)
A(7) = Val(a7)
A8 = Mid(rs , 8 , 1)
A(8) = Val(a8)
A9 = Mid(rs , 9 , 1)
A(9) = Val(a9)
A10 = Mid(rs , 10 , 1)
A(10) = Val(a10)
A11 = Mid(rs , 11 , 1)
A(11) = Val(a11)
A12 = Mid(rs , 12 , 1)
A(12) = Val(a12)
A13 = Mid(rs , 13 , 1)
A(13) = Val(a13)
A14 = Mid(rs , 14 , 1)
A(14) = Val(a14)
A15 = Mid(rs , 15 , 1)
A(15) = Val(a15)
A16 = Mid(rs , 16 , 1)
A(16) = Val(a16)
Start Timer0




Loop

Indication:
  If L > 15 Then L = 0
   Ledout = Lookup(l , Effect3)
   Shiftout Portb.2 , Portb.3 , Ledout , 1

   Ledout = Lookup(l , Effect2)
   Shiftout Portb.2 , Portb.3 , Ledout , 1

   Incr L
   Ledout = Lookup(a(l) , Effect1)
   Shiftout Portb.2 , Portb.3 , Ledout , 1

   Pulseout Portb , 1 , 5

 Return


Effect1:
Data &B00000011 , &B10011111 , &B00100101 , &B00001101 , &B10011001       '0 1 2 3 4
Data &B01001001 , &B01000001 , &B00011111 , &B00000001 , &B00001001       '5 6 7 8 9

                                                                    'данные включения портов
Effect2:
Data &B00000000 , &B00000000 , &B00000000 , &B00000000
Data &B00000000 , &B00000000 , &B00000000 , &B00000000
Data &B10000000 , &B01000000 , &B00100000 , &B00010000
Data &B00001000 , &B00000100 , &B00000010 , &B00000001

Effect3:                                                    'данные включения портов
Data &B10000000 , &B01000000 , &B00100000 , &B00010000
Data &B00001000 , &B00000100 , &B00000010 , &B00000001
Data &B00000000 , &B00000000 , &B00000000 , &B00000000
Data &B00000000 , &B00000000 , &B00000000 , &B00000000

ну уже вообще не чего не могу придумать перепробовал все что мог , надежда только на вас :)
Если не трудно помогите пожалуйста.

0

2

Щас перечитал вопрос и извеняюсь, я не правильно написал, данные у меня передаются не НЕХ а строковые , передается строка вида "1234567890123456" .

0

3

Ты сделал наоборот, потому и теряешь данные. Нужно:
- принимать побайтно в прерывании приемника;
- а индицировать в главной программе по флагу таймера
И никаких INPUTов не применять. Принял символ - добавил в строку,
принял 0Dh (конец строки) - переписал строку в другой буфер для обработки.

+1

4

Это обычная проблема накопление ошибки портового стека, причем чем шустрее ядро - тем больший буфер можно организовать для приёма (следовательно и на оборот: слабое ядро, маленькими пакетами организуем обмен) и эта проблема не накопления ошибки при кратных кварцах и скоростях (это другая ситуация).
Я ещё удивлялся в своё время, почему у меня на XMega параметр бигстринг приводил к глюкам приёма, грешил на Баском, потом, когда начал работать с Тиньками (да ещё с отсутствующими аппаратными портами) - это всё и открылось.
Т.ч. грамотная реализация алгоритма спасёт от многих проблем...

Отредактировано RDW (2013-02-01 17:44:02)

0

5

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

Как-то не комильфо разруливать здесь коммерческий проект...

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

а еще я щитаю что я не дорос для продажи своих программ , я только учусь , может быть когда нибудь и будет возможность продать что то , но это не скоро , мое самообучение  идет то не больше месяца , да и времени на это не так много работаю, а в свободное время занимаю МК

Отредактировано ptihka (2013-02-01 21:48:11)

0

6

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

Ты сделал наоборот, потому и теряешь данные. Нужно:
- принимать побайтно в прерывании приемника;
- а индицировать в главной программе по флагу таймера
И никаких INPUTов не применять. Принял символ - добавил в строку,
принял 0Dh (конец строки) - переписал строку в другой буфер для обработки.

Если я вас правельно понял , то программа с компьютера должно отправлять данные не :
такого типа "123456789"
а такого "1"
             "2"
             "3"
             "3"
и в прирывании таймера написать следующие ?

Код:
Indication:
If L > 16 Then L = 1
  X = Inkey()               читаем данные из буфера
 A(l) = X                      заносим их в массив
 Return

я правельно понял?

0

7

1 передавать как строку
2 Если это прерывание приемника (URXC), то буфер уже не пуст, поэтому

On  URXC  INT_URXC

ENABLE URXC

INT_URXC:
     X=UDR  'просто считать приемный регистр
     If X=10 Then        '&H0D (конец строки)?
        B = A                'переписать строку для обработки (A,B - строковые переменные)
        C = 255            'поставить флаг (C - байт)
        A = ""               'очистить приемный буфер
     Else
        A = A + Chr(X) 'добавить к буферу
     End if
Return

0

8

Посмотри реализацию вот тут : http://bascom-forum.de/showthread.php?3 … Modbus-RTU

0

9

Извеняюсь , что так долго не отвечал , ждал микросхемы, сворганил себе отладочную платку и проверил, работу СОМ прорта. Всем огромное спасибо за помошь особенно dmm , ваш код заработал практически сразу , единстенное что только без этой строк (C = 255            'поставить флаг (C - байт)) почемуто когда я ее ставлю у меня не работает прием по СОМ , если убарть все идеально работает , ddm немогли бы вы пояснить что за строка такая и нужна ли она там? вот переделал код , уменьшил значительно.

Код:
$regfile = "m8def.dat"
$crystal = 4000000

$baud = 9600

Ddrb = &B11111111

On Urxc Getchar

Dim G As String * 16
Dim H As String * 1
Dim Rs As String * 16
Dim L As Byte
Dim Ledout As Byte
'Dim C As Byte
Dim K As Integer
Dim A(16) As Byte
Dim X As Word

Enable Interrupts
Enable Urxc


Do
Incr K
If K > 16 Then K = 1
H = Mid(rs , K , 1)
A(k) = Val(h)

  If L > 15 Then L = 0
   Ledout = Lookup(l , Effect3)
   Shiftout Portb.0 , Portb.2 , Ledout , 1

   Ledout = Lookup(l , Effect2)
   Shiftout Portb.0 , Portb.2 , Ledout , 1

   Incr L
   Ledout = Lookup(a(l) , Effect1)
   Shiftout Portb.0 , Portb.2 , Ledout , 1

   Pulseout Portb , 1 , 5
Loop



Getchar:
     X = Udr
     If X = 10 Then
  Rs = G
 ' C = 255          ' ????????
 G = ""
Else
 G = G + Chr(x)
         End If
 Return



Effect1:
Data &B00000011 , &B10011111 , &B00100101 , &B00001101 , &B10011001
Data &B01001001 , &B01000001 , &B00011111 , &B00000001 , &B00001001


Effect2:
Data &B00000000 , &B00000000 , &B00000000 , &B00000000
Data &B00000000 , &B00000000 , &B00000000 , &B00000000
Data &B10000000 , &B01000000 , &B00100000 , &B00010000
Data &B00001000 , &B00000100 , &B00000010 , &B00000001

Effect3:
Data &B10000000 , &B01000000 , &B00100000 , &B00010000
Data &B00001000 , &B00000100 , &B00000010 , &B00000001
Data &B00000000 , &B00000000 , &B00000000 , &B00000000
Data &B00000000 , &B00000000 , &B00000000 , &B00000000

кстати если это не будет рекламой могу выложить сайт где закупался , остался доволен работой магазина на 500% , очень хорошие цены (а главное сколько написано столько и стоит), работают быстро  и  качественно , все грамотно упаковано , каждая деталь подписана , вобщем все на высоком уровне.

0

10

С - флаг, по которому в главном цикле узнаешь, что принял новую строку (новые данные) и их можно выводить. А ты в программе бесконечно "ездишь" по текущим данным. Значит C тебе и не нужен. Но мешать не должно

+1

11

Еще раз здравствуйте! Всех с прошедшим праздником! Не стал создавать новую тему ради одного вопроса. Блин ребят помогите пожалуйста, никак не могу придумать как сделать следующие:
делаю часы-термометр .Кнопками я задаю время показа часов и температуры (в секундах до 99) мне нужно чтобы цыкл с чтением данных часов повторялся столько секунд сколько ввел, соответственно и температура так же. Тоесть если я ввел показывать часы 10 секунд то через 10 секунд программа дожна выйти из цикла с часами и перейти в  цикл термометра и повторять его столько секунд сколько я введуи так по кругу.
программа выглядит так

Код:
do
.......
чтение данных датчика температуры
.......
loop

do
.......
чтение данных часов
.......
loop
работа таймера:
вывод данных на семисигментный индекатор

0


Вы здесь » Программирование ATMEL в BASCOM. » Вопросы - ответы » Помогите разобратся с приемом по RS-232