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

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

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

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



Mega32A и USART

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

1

Всем привет!
Может кто подскажет? А то уже мозг закипает.
Есть сеть из 3 МК, один Master и 2 Slave.
Один Slave собран на М16, другой на М32А, всё было нормально.
Подключил ещё один Slave на М16, на приём всё нормально, на
выходе только один байт 00. Прошивки у всех Slave одинаковые(адрес
выставляется перемычками). Дальше ещё интереснее, через несколько
дней "отвалился" Slave на М32А, приём есть, на выходе один байт 00.
Простая тестовая программа

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

Config Com1 = 9600 , Synchrone = 0 , Parity = None , Stopbits = 1 , Databits = 8 , Clockpol = 0
Config Print0 = Portd.6 , Mode = Set
Config Pind.6 = Output
Open "com1:" For Binary As #1

Config Portd.6 = Output
Portd.6 = 0

Dim Mbuf(11) As Byte
Dim My_adress As Byte
My_adress = &H02

   Mbuf(1) = My_adress
   Mbuf(2) = &H03
   Mbuf(2) = &H01

Do
   Printbin #1 , Mbuf(1) ; 3
   Wait 1
   Print #1 , "Slave adr " ; My_adress
   Wait 1
   Put #1 , $61
   Wait 1
Loop

End

в симуляторе всё нормально, в железе на Mega32A - 00.
Может кто подскажет или пошлёт в нужном направлении?

0

2

как это выглядит аппаратно? выходы Slave соединены напрямую? Если да, то это неправильно. Нужно делать открытые коллекторы и монтажное "И" с подтягивающим резистором.

0

3

Я смотрю прямо на TX. А интерфейс RS485.

0

4

вопрос о чем: нет ли конфликта шины?
тем более, что при работе с rs485 драйвер нужно переключать на передачу только на время выдачи сообщений, всем контроллерам
в программе этого нет!

0

5

Один глюк нашёл, это из за кипящего мозга.
С другим сложнее.
Конфликта нет, так как Slave только отвечают на запросы ведущего.
И всё разведено во времени. За приём-передачу отвечает ножка МК,
которая указывается при конфигурировании.

Код:
Config Com1 = 9600 , Synchrone = 0 , Parity = None , Stopbits = 1 , Databits = 8 , Clockpol = 0
Config Print0 = Portd.6 , Mode = Set
Config Pind.6 = Output
Open "com1:" For Binary As #1

И вот здесь "засада", как показывает лог. анализатор, на линии RX возникает короткий импуульс
и сигнал передачи срывается, отключение приёмника не помогает.....

0

6

Странно, у меня работает без нареканий... Что за трансивер ?
Вот рабочий код блока реле , написано криво, комменты не исправлял, но надо было быстро, потом некогда ))

Код:
$lib "modbus.lbx"
$regfile = "m16def.dat"                                     ' specify the used micro
$crystal = 11059200                                         ' used crystal frequency
$baud = 9600                                                ' use baud rate
$hwstack = 32                                               ' default use 32 for the hardware stack
$swstack = 10                                               ' default use 10 for the SW stack
$framesize = 40                                             ' default use 40 for the frame space


'for writing a register Modbus_slave number 3 was used
'Const Modbus_slave = 3 ' for a write test
Const Modbus_slave = 2                                      ' for a read test

On Urxc Urxc_isr
Enable Urxc
Enable Interrupts
'dimension a buffer for the modbus data
Dim Mbuf(8) As Byte , Modc As Byte , Modt As Byte , Modw As Word
Dim Xx As Byte
Config Print0 = Portb.4 , Mode = Set
Config Pinb.4 = Output                                      'set the direction yourself
Config Portc = Output
Config Porta = Output




Do
  nop
  'add you main code here
Loop



'-------- interrupt handler for the URXC interrupt ----------------------------
Urxc_isr:
  sbis usr,7
  rjmp urxc_isr                                             ' wait until we can read the byte
  Modt = Udr                                                ' get the byte

  If Modc = 0 Then                                          'if we do not have any data yet

    If Modt = Modbus_slave Then                             'is this the slave adress?
        Modc = Modc + 1                                     'increase the buffer counter
        Mbuf(1) = Modt                                      'store address in location 1
    End If
  Elseif Modc = 1 Then                                      'we received the address already
    If Modt = 6 Or Modt = 3 Then                            'this demo works with function 6 and 3 only
       Mbuf(2) = Modt                                       'store the function
       Modc = Modc + 1                                      'increase buffer counter
    Elseif Modt = Modbus_slave Then                         'test if it is the slave number
       Mbuf(1) = Modt                                       'store it in that case
    Else
       Modc = 0                                             'reset it
    End If
  Else                                                      'we received the address and the function
    Modc = Modc + 1 : Mbuf(modc) = Modt                     ' store the data
    If Modc = 8 Then                                        'we need 8 bytes

       Modw = Makeint(mbuf(7) , Mbuf(8))                    ' create word of reeived crc
       If Modw = Crcmb(mbuf(1) , 6) Then                    ' does the crc match?

          If Mbuf(2) = 6 Then                               ' function 6 to write data
              Gosub 1
             'do something here like setting a port
             'portD = mbuf(6) ' lsb of received data
             Printbin Mbuf(1) ; 8                           'just reply the received buffer
          Elseif Mbuf(2) = 3 Then                           ' function 3 to read data
             Mbuf(3) = 2                                    ' byte count
             Mbuf(4) = 0                                    'MSB
             Mbuf(5) = Pinc                                 ' LSB return input of port D
             Modw = Crcmb(mbuf(1) , 5)                      ' create checksum
             Mbuf(6) = Low(modw)                            'add to buffer
             Mbuf(7) = High(modw)
             Printbin Mbuf(1) ; 7                           ' write response
          End If
       End If
       Modc = 0
    End If
  End If
Return

1:
  Portc = Mbuf(6)
 Porta.0 = Portc.7
 Porta.1 = Portc.6
 Porta.2 = Portc.5
 Porta.3 = Portc.4
 Porta.4 = Portc.3
 Porta.5 = Portc.2
 Porta.6 = Portc.1
 Porta.7 = Portc.0
Return

Отредактировано Skull (2012-04-27 02:16:28)

0

7

Да всё приблизительно так.
Пока проблему решил в лоб.
Вместо PRINTBIN использовал PUT.

Код:
Portd.6 = 1
   For B = 1 To 8
     Put #1 , Mbuf(b)
   Next
   Waitms 2
   Portd.6 = 0

И самое интересное импульс с RX исчез.
Трансивер ADM485/

0

8

Обрати внимание на конфигурирование порта- просто $Baud. может так как у тебя конфигурится программный порт и прерывание наступает по перепаду первого же импульса а не приходу байта??
А, да, еще printbin иногда глючит с автоматическим RX\TX ,лучше по необходимости дергать порт...
Я пользую MAX485... убивается трудно.

Отредактировано Skull (2012-04-27 02:37:19)

0

9

Порт у меня аппаратный, и на приём всё работает
отлично. Причём плата на banned6 работает нормально.
Значит буду использовать PUT и дёргать ножкой.
Спасибо!

0