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

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

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

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



MODBUS

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

1

Предлагаю разживать данный протокол до мельчайших подробностей.
http://sd.uploads.ru/t/9hHDi.jpg
Наброски кода работают коряво!
Master

Код:
'**************************************************
' Servo RS485     ATMega328P
 '*************************************************
$regfile = "m328pdef.dat"
$crystal = 1000000
$hwstack = 32
$swstack = 10
$framesize = 32
$baud = 2400
'**************************************************
Config Lcd = 16 * 2
Config Lcdpin = Pin , Db4 = Portb.2 , Db5 = Portb.3 , Db6 = Portb.4 , Db7 = Portb.5 , E = Portb.1 , Rs = Portb.0
Cursor Off
'**********************************************************

'********************************************************
Config Portb.7 = Output
Led Alias Portb.7
Config Portc.0 = Input
But1 Alias Pinc.0
Config Portc.1 = Input
But2 Alias Pinc.1
'************************
Dim Mayadres As Word
Dim Adres As Byte
Dim Xadc1 As Word
Dim Xadc2 As Word
Dim A As Byte
Dim B As Bit
'**********************************************
Mayadres = 01
Ucsr0a = &H21


Cls

'****************************
'*        начинаем          *
'****************************
Do
Set Led
Waitms 100
Reset Led
Waitms 100
'-----------------------------------------------------------------------

A = Ucsr0a
Locate 1 , 1 : Lcd Bin(a)
Locate 2 , 1 : Lcd Xadc1
If But1 = 0 Then
Waitms 200
Printbin 11
Printbin 678
Cls
End If
'/////////////////////////////////////////////////////////
If But2 = 0 Then
Waitms 200
Printbin 12
Printbin 789
Cls
End If
'------------------------------------------------------------------------------
If A = &H61 Then
Reset Ucsr0a
Ucsr0a = &H21
End If
'-------------------------------------------------------------------------------
Adres = 0
Ucsr0a = &H21
'----------------------------------------------------------------------------
If A = &HA1 Then
Reset Ucsr0a
Ucsr0a = &H21
End If
'-------------------------------------------------------------------------------
If A = &HE1 Then
Reset Ucsr0a
Ucsr0a = &H21
End If
'------------------------------------------------------------------------------
Locate 2 , 10 : Lcd Xadc1
'------------------------------------------------------------------------------
If Mayadres = Adres Then
Ucsr0a = &H20
Adres = 0
Inputbin Xadc1 , 2
Waitms 50
Cls
End If
'-------------------------------------------------------------------------------
If A = &H29 Then                                            ' ошибка по переполнению
Reset Ucsr0a
Ucsr0a = &H21
End If






'-----------------------------------------------------------------------
Loop
End

Slave0

Код:
'**************************************************
' СУН отработка RS485     ATMega328P
 '*************************************************
$regfile = "m328pdef.dat"
$crystal = 1000000
$hwstack = 32
$swstack = 10
$framesize = 32
$baud = 2400
'**************************************************
'**************************************************
Config Lcd = 16 * 2
Config Lcdpin = Pin , Db4 = Portb.2 , Db5 = Portb.3 , Db6 = Portb.4 , Db7 = Portb.5 , E = Portb.1 , Rs = Portb.0
Cursor Off
'****************************************************************************************************************
Config Adc = Single , Prescaler = 2 , Reference = Avcc
Start Adc
'**********************************************************
Config Print0 = Portd.2 , Mode = Set
Config Pind.2 = Output
'*************************************************************************
Config Portb.7 = Output
Led Alias Portb.7
Config Portc.0 = Input

'************************
Dim Xadc As Word
Dim X_data As Word
Dim Adres As Byte
Dim Mayadres As Word
Dim A As Byte
Dim B As Byte
Dim C As Byte
'***************************************************
Mayadres = 11
Ucsr0a = &H21
Cls
'****************************
'*        начинаем          *
'****************************
Osnova:
Do

Set Led
Waitms 100
Reset Led
Waitms 100
'----------------------------------------------------------------------
Xadc = Getadc(0)
A = Ucsr0a
Adres = 0
If A = &HA1 Then
Inputbin Adres
Ucsr0a = &H21
End If
If Mayadres = Adres Then
Ucsr0a = &H20
Adres = 0
Ucsr0a = &H21
Inputbin X_data , 2
Cls
End If
Locate 1 , 1 : Lcd "Data_IN=" ; X_data
Locate 2 , 1 : Lcd "Data_Out=" ; Xadc
Loop
End

Slave1

Код:
'**************************************************
' СУН отработка RS485     ATMega328P
 '*************************************************
$regfile = "m328pdef.dat"
$crystal = 1000000
$hwstack = 32
$swstack = 10
$framesize = 32
$baud = 2400
'**************************************************
'**************************************************
Config Lcd = 16 * 2
Config Lcdpin = Pin , Db4 = Portb.2 , Db5 = Portb.3 , Db6 = Portb.4 , Db7 = Portb.5 , E = Portb.1 , Rs = Portb.0
Cursor Off
'****************************************************************************************************************
Config Adc = Single , Prescaler = 2 , Reference = Avcc
Start Adc
'**********************************************************
Config Print0 = Portd.2 , Mode = Set
Config Pind.2 = Output
'*************************************************************************
Config Portb.7 = Output
Led Alias Portb.7
Config Portc.0 = Input

'************************
Dim Xadc As Word
Dim X_data As Word
Dim Adres As Byte
Dim Mayadres As Word
Dim A As Byte
Dim B As Byte
Dim C As Byte
'***************************************************
Mayadres = 12
Ucsr0a = &H21
Cls
'****************************
'*        начинаем          *
'****************************
Osnova:
Do

Set Led
Waitms 100
Reset Led
Waitms 100
'----------------------------------------------------------------------
Xadc = Getadc(0)
A = Ucsr0a
Adres = 0
Ucsr0a = &H21
If A = &HA1 Then
Inputbin Adres
End If
If Mayadres = Adres Then
Ucsr0a = &H20
Adres = 0
Inputbin X_data , 2
Waitms 50
Printbin Xadc
Cls
End If
If A = &H61 Then
Reset Ucsr0a
Ucsr0a = &H21
End If
Locate 1 , 1 : Lcd "IN=" ; X_data
Locate 2 , 1 : Lcd "Out=" ; Xadc
Locate 1 , 8 : Lcd Bin(a)
Loop
End

0

2

Sega12
Сам  проект положи зипом.

0

3

Мультипроцессорный USART, 9-ти битный, адресный, может сгодится  -  скачать

http://se.uploads.ru/t/u01Sx3.jpg

Отредактировано sasha_1973 (2014-08-09 15:29:51)

+1

4

sasha_1973
не могу ни скачать не просмотреть код!
До недавнего времени всё скачивал  без проблем теперь такая ерунда:
http://sd.uploads.ru/t/XourA.jpg
кликаешь по донлоад в ответ игнор!

Отредактировано Sega12 (2014-08-09 15:34:51)

0

5

Aleks
Как это сделать?))

0

6

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

не могу ни скачать не просмотреть код!

Закинул Вам на mail

+1

7

sasha_1973
Спасибо  за оперативность,уже изучаю.

0

8

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

Спасибо  за оперативность,уже изучаю.

Большой плюс этого метода в том, что когда общаются 2 МК, остальные игнорируют посылки и не отвлекаются от своей работы.

0

9

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

Большой плюс этого метода в том, что когда общаются 2 МК, остальные игнорируют посылки и не отвлекаются от своей работы.

Сань, ну не подкладывай ты людям геморрой ))))
MODBUS четко стандартизован, и заставить работать в 9ти битном режиме промышленный контроллер , который будет опрашивать твое устройство будет ой как не просто, если вообще возможно, но время на попытку человек потеряет ))

Выдрать оттуда твои процедуры будет крайне полезно, но 9бит режим- ни в коем разе )

Отредактировано Skull (2014-08-09 18:09:04)

0

10

Skull

Сань, ну не подкладывай ты людям геморрой ))))

Не согласен на счёт геморроя. Материал полезный, если не будет желания разобраться то гемор обеспечен хоть в 8-и битной хоть в 9-и битной передачи, а опыт работы с регистрами достаточно разжёван для сочленения его к протоколу.

0

11

Skull

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

цитата с другой ветки,ну да ладно.
Вот опробованная идея для измерения уровня жидкости с помощью простого коаксиального кабеля.
http://sf.uploads.ru/t/eUKIp.jpg
со стороны МК :  var = GETRC( pin , number )

0

12

Коаксиал с цельным или сегментированно-воздушным диэлектриком ??

Ну,  и коль ты занялся столь нужной штукой как промышленные протоколы- лови русское описание стандарта
DOC

Отредактировано Skull (2014-08-10 03:24:31)

0

13

Коаксиал с цельным или сегментированно-воздушным диэлектриком ??

Целый, простой кусок кабеля от телевизионной антенны с одной стороны герметично залит с выводом центральной жилы, с другой через резюк к контролерй. Длинна по размеру резервуара .

0

14

Доброго времени суток, 
продолжу тему модбаса

нарисовал тестовую схемку общения атмеги8 по rs422 с компьютером по modbus
накидал прошивку

Код:
'modbus.lib contains the crcMB function
 $lib "modbus.lbx"


  $regfile = "m8def.dat"
  Const _crystal = 8000000                                  ' chip used
 $crystal = _crystal                                        ' xtal used
Const Baudrate = 9600
'Const Baudrate = 19200
'Const Baudrate = 38400
'Const Baudrate = 57600
'Const Baudrate = 115200
  $baud = Baudrate
$hwstack = 45
$swstack = 85
$framesize = 32


Config Com1 = Dummy , Synchrone = 0 , Parity = None , Stopbits = 2 , Databits = 8 , Clockpol = 0
  Config Scl = Portc.5                                      ' I2c Scl
  Config Sda = Portc.4                                      ' I2c Sda
  'Config I2cdelay = 1                                       ' Ñêîðîñòü ðàáîòû øèíû I2c íà ïðîãðàììíîì óðîâíå
  I2cinit

 'Config Lcdpin = Pin , Db4 = Portc.4 , Db5 = Portc.5 , Db6 = Portc.6 , Db7 = Portc.7 , E = Portd.7 , Rs = Portd.5
 Declare Sub Copy_inputs_to_table

 Dim Mbuf(255) As Byte , Modc As Byte , Modt As Byte , Modw As Word
 Dim Table_data(40) As Word                                 'òàáëèöà ñ äàííûìè (òåêóùèå çíà÷åíèÿ èçìåðåíèé, ñëîâà âõîäîâ âûõîäîâ óñòàâêè, íàñòðîéêè )
 Dim Tmp_table_data(10) As Word                             'òàáëèöà ñ äàííûìè (òåêóùèå çíà÷åíèÿ èçìåðåíèé, ñëîâà âõîäîâ âûõîäîâ óñòàâêè, íàñòðîéêè )
 Dim Tmp As Word                                            'ïðîìåæóòî÷íûå ïåðåìåííûå
 Dim Tmp_byte As Byte                                       'ïðîìåæóòî÷íûå ïåðåìåííûå
 Dim Tmp_byte2 As Byte
 Dim Tmp_byte_modbus As Byte
 Dim N_word As Byte                                         'êîëè÷åñòâî ñëîâ â ïîñûëêå
 Dim N_byte As Byte                                         'êîëè÷åñòâî áàéò â ïîñûëêå
 Dim Beg_adr As Byte                                        'íà÷àëüíûé àäðåñ äàííûõ
 Dim Beg_adr_w As Byte                                      ' àäðåñ äàííûõ  ïðè çàïèñè
 Dim I As Byte                                              'ñ÷åò÷èê öèêëîâ â for
 Dim Cnt_print As Byte
 Dim Error_mod As Integer                                   ' êîä îøèáêè
 Dim Frame_value As Byte                                    'çíà÷åíèå ïàóçû ìåæäó ôðåéìàìè çàãðóæàåìîå â ñ÷åò÷èê
 Dim Serial_numb_l As Eram Byte
 Dim Serial_numb_h As Eram Byte
                            ' ïàðàìåòðû äëÿ çàïèñè â ýíåðãîíåçàâèñèìóþ ïàìÿòü
 Dim W_to_device As Byte                                    'ïðèçíàê çàïèñè â óñòðîéñòâî
 Dim Modbus_slave As Eram Byte                              'àäðåñ óñòðîéñòâà â ñåòè Modbus
 Dim Frame_value_dev As Eram Byte                           'çíà÷åíèå ïàóçû ìåæäó ôðåéìàìè
 Dim Ust1_up As Eram Integer                                'óñòàâêà1 âåðõíÿÿ
 Dim Ust1_dwn As Eram Integer                               'óñòàâêà1 íèæíÿÿ
 Const Maximum_input_registers = 28                         ' ìàêñèìàëüíîå êîëè÷åñòâî ðåãèñòðîâ êîòîðîå ìîæíî ïðî÷åñòü 0-27 registers !
 Dim Md_t_start As Bit
' If _crystal = 8000000 Then
'   If Baudrate = 9600 Then
'      Const Load_timer = &H006C
'   End If
'   If Baudrate = 19200  Then
'      Const Load_timer = &H0031
'   End If
'   If Baudrate = 38400 Then
'      Const Load_timer = &H0018
'   End If
'   If Baudrate = 57600 Then
'      Const Load_timer = &H0011
'   End If
'   If Baudrate = 115200 Then
'      Const Load_timer = &H0008
'   End If
'End If
  Const Load_timer = &H006C


 Dim L_time(7) As Eram Byte
 Dim L_input As Eram Byte
 Dim Tmpl_input As Byte






  Const Çàïèñü_ds1307 = &HD0                                ' Àäðåñ çàïèñè â ÎÇÓ Ds1307
  Const ×òåíèå_ds1307 = &HD1                                ' Àäðåñ ÷òåíèÿ èç ÎÇÓ Ds1307

  Const Const_ãîä = 6                                       ' Ðåãèñòð ãîä Ds1307
  Const Const_÷àñû = 2                                      ' Ðåãèñòð ÷àñû Ds1307
  Const Const_ìåñÿö = 5                                     ' Ðåãèñòð ìåñÿö Ds1307
  Const Const_ìèíóòû = 1                                    ' Ðåãèñòð ìèíóòû Ds1307
  Const Const_ñåêóíäû = 0                                   ' Ðåãèñòð ñåêóíäû Ds1307
  Const Const_äåíü_íåäåëè = 3                               ' Ðåãèñòð äåíü_íåäåëè Ds1307
  Const Const_÷èñëî_ìåñÿöà = 4                              ' Ðåãèñòð ÷èñëî_ìåñÿöà Ds1307

  Const Const_íàñòðîéêà_ds1307 = 7                          ' Ðåãèñòð äëÿ íàñòðîéêè Ds1307
  Const Const_stop_÷àñû = &B10000000                        ' Çíà÷åíèå êîíñòàíòû äëÿ îñòàíîâêè ÷àñîâ
  Const Const_start_÷àñû = &B00000000                       ' Çíà÷åíèå êîíñòàíòû äëÿ çàïóñêà ÷àñîâ
  Const Const_ðàçðåøåíèå_sout_ds1307 = &H90                 ' Çíà÷åíèå êîíñòàíòû äëÿ ñòàðòà ñåêóíäíûõ èìïóëüñîâ

'===============================================================================
'            È Ñ Ï Î Ë Ü Ç Ó Å Ì Û Å     Ï Î Ä Ï Ð Î Ã Ð À Ì Ì Û
'===============================================================================

  Declare Sub Çàïèñü_i2c(byval Àäðåñ_÷èïà_çàïèñü As Byte , Byval Ðåãèñòð_÷èïà As Byte , Byval Çàïèñûâàåìàÿ_ïåðåìåííàÿ As Byte)
  Declare Sub ×òåíèå_i2c(byval Àäðåñ_÷èïà_÷òåíèå As Byte , Byval Àäðåñ_÷èïà_çàïèñü As Byte , Byval Ðåãèñòð_÷èïà As Byte , Ñ÷èòàííàÿ_ïåðåìåííàÿ As Byte)

  Declare Sub Modbus_exec
'===============================================================================
'             È Ñ Ï Î Ë Ü Ç Ó Å Ì Û Å     Ï Å Ð Å Ì Å Í Í Û Å
'===============================================================================

  Dim Ãîä As Byte
  Dim ×àñû As Byte
  Dim Ìåñÿö As Byte
  Dim Ìèíóòû As Byte
  Dim Ñåêóíäû As Byte
  Dim Äåíü_íåäåëè As Byte
  Dim ×èñëî_ìåñÿöà As Byte

  Dim Ôëàã_îïðîñèòü_ds1307 As Byte

   Config Pind.2 = Input                                    ' Íàñòðàèâàåì âûâîä íà âõîä
  Config Int0 = Rising                                      ' Ïðåðûâàíèå ñðàáàòûâàåò ïî ñïàäó óðîâíÿ   Rising (ïî ïåðåäíåìó ôðîíòó) ; Falling (ïî çàäíåìó ôðîíòó) ; Low Level (ïî íèçêîìó óðîâíþ)
  On Int0 Ïðåðûâàíèå_ds1307 Nosave                          ' Ïîñëå ïðåðûâàíèÿ èäåì â ïîäïðîãðàììó îáðàáîòêè
 '  Call Çàïèñü_i2c(çàïèñü_ds1307 , Const_íàñòðîéêà_ds1307 , Const_ðàçðåøåíèå_sout_ds1307)

I2cstart
I2cwbyte &HD0
I2cwbyte Const_íàñòðîéêà_ds1307
I2cwbyte Const_ðàçðåøåíèå_sout_ds1307
I2cstop


 Config Timer1 = Timer , Prescale = 256                     'îðãàíèçàöèÿ çàäåðæêè îòêëþ÷åíèÿ ðàçðåøåíèÿ ïåðåäà÷è, ïðè ïåðåäà÷å íà ïîðò 485             '4000000 0,065536 ñåê (15,25878906 â 1 ñåêóíäó)          8000000  0,032768 30,51757813


 ' **************** âûõîäû*************
 'Config Portc.0 = Output
 Config Portd.4 = Output
  Config Portd.5 = Output
   Config Portd.6 = Output
   Config Portd.7 = Output
   'Test_light Alias Portc.0
   Enable_tx Alias Portd.4                                  'ðàçðåøåíèå íà ïåðåäà÷ó ïî 485

   T1 Alias Portd.5
     T2 Alias Portd.6
       T3 Alias Portd.7
' ****************      0
If Modbus_slave > 254 Then Modbus_slave = 1
If Modbus_slave = 0 Then Modbus_slave = 1

   T3 = 1
  'Exception response codes
Illegal_function Alias 1
Illegal_data_address Alias 2
Illegal_data_value Alias 3

'***************************************************************
' I/O configuration
' This is user configurable.
' Config PORT'S pin's to match modbus client hardware
' Inputs must start with Input_
' Outputs must start with Coil_
Input_1 Alias Pinb.0                                        ' Input 1
Input_2 Alias Pinb.1                                        ' Input 2
Input_3 Alias Pinb.2                                        ' Input 3
Input_4 Alias Pinb.3                                        ' Input 4
Input_5 Alias Pinb.4                                        ' Input 5
'Input_6 Alias Pina.5                                        ' Input 6
'Input_7 Alias Pina.6                                        ' Input 7
'input_8 Alias Pina.7                                       ' Input 8


   '---------------------- Íàñòðàèâàåì ÀÖÏ --------------------------------------------------
Config Adc = Single , Prescaler = Auto , Reference = Avcc
Start Adc


 Declare Sub Send_to_master                                 'ïîäïðîãðàììà ïåðåäà÷è îòâåòà ìàñòåðó
 Declare Sub Error_modbus                                   'ïîäïðîãðàììà ôîðìèðîâàíèÿ îøèáêè ìîäáàñ

 ' Config Portc = Output                                     'íàñòðîèì ïîðò ñ êàê âûõîäû
  Modc = 0                                                  'èíèöèàëèçàöèÿ
  W_to_device = 0
  Error_mod = 0
  Cnt_print = 0
  Frame_value = Frame_value_dev

  If Frame_value = 255 Then Frame_value = 253
  '************************************************************
' Program initialisation
'************************************************************
                 'ÂÀÆÍÎ! - Ïîñëå Ïåðîïðîøèâêè Çíà÷åíèå Modbus_slave = 255 !!!!!!!
  Tmp_byte = Modbus_slave                                   ' íåëüçÿ ïèñàòü åðàì áàéò â èíò. ìîæíî ÷åðåç ïðîìåæóòî÷íóþ ïåðåìåííóþ
  Table_data(12) = Tmp_byte                                 ' àäðåñ 4010 - íîìåð óñòðîéñòâà â ñåòè ìîäáàñ (÷èòàòü ïèñàòü)
  Table_data(13) = Ust1_up                                  ' àäðåñ 4011 - óñòàâêà âåðõ  (÷èòàòü ïèñàòü)
  Table_data(14) = Ust1_dwn                                 ' àäðåñ 4012 - óñòàâêà íèç (÷èòàòü ïèñàòü)
  Table_data(15) = Frame_value                              ' àäðåñ 4015 - çíà÷åíèå TIMER0 çàãðóæàåìîå ïðè ñòàðòå òàéìåðà TIMER0 (÷èòàòü)
  Table_data(1) = &H4D49                                    'óñòðîéñòâî MI-01.01
  Table_data(2) = &H0101
  Tmp_byte = Serial_numb_h
  Tmp_byte2 = Serial_numb_l                                 'âåðñèÿ   ïëàòû. âåñèÿ Ïðîøèâêè ( 01 01)
            'ñåðèéíûé íîìåð
  Table_data(4) = 660                                       'íàïïðÿæåíèå ñóõîé (660 èëè 1140)
  Table_data(5) = &HFFFF                                    'ðåçåðâ
  Table_data(7) = &HFFFF                                    'òîê (íåòó - êîä FFFF)
  Table_data(8) = &HFFFF                                    'íàïðÿæåíèå  (íåòó - êîä FFFF)
  Table_data(9) = &HFFFF                                    'óòå÷êà  (íåòó - êîä FFFF)
  Table_data(10) = &HFFFF                                   'ðåçåðâ
  Table_data(11) = &HFFFF

   Table_data(6).0 = Input_1
   Table_data(6).1 = Input_2
   Table_data(6).2 = Input_3
   Table_data(6).3 = Input_4
   Table_data(6).4 = Input_5
   Table_data(6).5 = 1
   Table_data(6).6 = 1
   Table_data(6).7 = 1


   '   Tmpl_input = Table_data(6)
  Tmp_byte = L_input
    Table_data(28) = Tmp_byte
    Tmp_byte = L_time(1)
    Table_data(26) = Tmp_byte                               ' = Ñåêóíäû
    Tmp_byte = L_time(2)
   Table_data(27) = Tmp_byte                                ' = Ìèíóòû
   Tmp_byte = L_time(3)
   Table_data(24) = Tmp_byte                                ' = ×àñû
   Tmp_byte = L_time(4)
   Table_data(25) = Tmp_byte                                ' = ×èñëî_ìåñÿöà
   Tmp_byte = L_time(5)
   Table_data(22) = Tmp_byte                                ' = Ìåñÿö
   Tmp_byte = L_time(6)
   Table_data(23) = Tmp_byte                                ' = Ãîä

  ' L_time(1)                                                '                                 ' = Ñåêóíäû
  ' L_time(2) = Ìèíóòû
  ' L_time(3) = ×àñû
  ' L_time(4) = ×èñëî_ìåñÿöà
  ' L_time(5) = Ìåñÿö
  ' L_time(6) = Ãîä



Call Copy_inputs_to_table

 Tmpl_input = Table_data(6)

 Load Timer1 , Load_timer
 On Timer1 Modbus_timers


 On Urxc Urxc_isr                                           'ïðåðûâàíèå ïî ïðèåìó UART
 Enable Urxc
 On Utxc Utxc_isr                                           'ïðåðûâàíèå ïî ïåðåäà÷å UART

 Enable Timer1
 Enable Interrupts

                                  'ðåçåðâ


 '\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\
'    Ç À Ï Ó Ñ Ê    È    Ï Ð Å Ä Â À Ð È Ò Å Ë Ü Í Û Å    Í À Ñ Ò Ð Î É Ê È
'\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\



  Ñåêóíäû = 20
  Ìèíóòû = 20
  ×àñû = 20
  Äåíü_íåäåëè = 7
  ×èñëî_ìåñÿöà = 12
  Ìåñÿö = 4
  Ãîä = 14

  Table_data(16) = Ñåêóíäû
   Table_data(17) = Ìèíóòû
   Table_data(18) = ×àñû
   Table_data(19) = ×èñëî_ìåñÿöà
   Table_data(20) = Ìåñÿö
   Table_data(21) = Ãîä


  Ãîä = Makebcd(ãîä)                                        ' Ãîä
  ×àñû = Makebcd(÷àñû)                                      ' ×àñû
  Ìåñÿö = Makebcd(ìåñÿö)                                    ' Ìåñÿö
  Ìèíóòû = Makebcd(ìèíóòû)                                  ' Ìèíóòû
  Ñåêóíäû = Makebcd(ñåêóíäû)                                ' Ñåêóíäû
  Äåíü_íåäåëè = Makebcd(äåíü_íåäåëè)                        ' Äåíü íåäåëè
  ×èñëî_ìåñÿöà = Makebcd(÷èñëî_ìåñÿöà)                      ' ×èñëî

 '   I2cstart                                                ' Ïîäãîòîâêà ê ðàáîòà øèíû I2c
 '   I2cwbyte Çàïèñü_ds1307                                  ' Àäðåñíîå îáðàùåíèå ê èñïîëüçóåìîìó ÷èïó i2c, äëÿ çàïèñè
 '   I2cwbyte 0                                              ' Àäðåñ ðåãèñòðà, â êîòîðûé áóäåò ïðîèçâîäèòüñÿ çàïèñü
 '   I2cwbyte Ñåêóíäû                                        ' Çàïèñûâàåìàÿ ïåðåìåííàÿ
 '  I2cwbyte Ìèíóòû                                          ' Çàïèñûâàåìàÿ ïåðåìåííàÿ
 '  I2cwbyte ×àñû                                            ' Çàïèñûâàåìàÿ ïåðåìåííàÿ
 '  I2cwbyte Äåíü_íåäåëè                                     ' Çàïèñûâàåìàÿ ïåðåìåííàÿ
 '  I2cwbyte ×èñëî_ìåñÿöà                                    ' Çàïèñûâàåìàÿ ïåðåìåííàÿ
 '  I2cwbyte Ìåñÿö                                           ' Çàïèñûâàåìàÿ ïåðåìåííàÿ
 '  I2cwbyte Ãîä                                             ' Çàïèñûâàåìàÿ ïåðåìåííàÿ
 '  I2cstop

  Call Çàïèñü_i2c(çàïèñü_ds1307 , Const_ãîä , Ãîä)
  Call Çàïèñü_i2c(çàïèñü_ds1307 , Const_÷àñû , ×àñû)
  Call Çàïèñü_i2c(çàïèñü_ds1307 , Const_ìåñÿö , Ìåñÿö)
  Call Çàïèñü_i2c(çàïèñü_ds1307 , Const_ìèíóòû , Ìèíóòû)
  Call Çàïèñü_i2c(çàïèñü_ds1307 , Const_ñåêóíäû , Ñåêóíäû)
  Call Çàïèñü_i2c(çàïèñü_ds1307 , Const_äåíü_íåäåëè , Äåíü_íåäåëè)
 Call Çàïèñü_i2c(çàïèñü_ds1307 , Const_÷èñëî_ìåñÿöà , ×èñëî_ìåñÿöà)

  Do                                                        'íà÷àëî îñíîâíîãî öèêëà
 If Md_t_start = 1 Then                                     '  åñëè âðåìÿ ìåæäó ïðèíÿòûìè áàéòàìè áîëüøå 3.5 ñèìâîëà, â áóôåðå ïðèíÿò ôðåéì

      Md_t_start = 0                                        ' îáíóëÿåì âñå ïðèçíàêè
      Error_mod = 0                                         ' îáíóëÿåì îøèáêó è íà÷èíàåì ðàçáèðàòü ïðèíÿòûé ôðåéì èç áóôåðà.
   T2 = 1
    If Mbuf(1) = Modbus_slave Or Mbuf(1) = 0 And Modc > 0 Then       'ïåðâûé áàéò ýòî àäðåñ óñòðîéñòâà

      Tmp_byte = Modc - 1                                   ' âû÷èñëÿåì àäðåñà äëÿ ðàñ÷åòà CRC
      Tmp_byte2 = Modc                                      ' âû÷èñëÿåì àäðåñà äëÿ ðàñ÷åòà CRC
      Modw = Makeint(mbuf(tmp_byte) , Mbuf(tmp_byte2))      ' ñ÷èòûâàåì èç ïðèíÿòîãî ôðåéìà  CRC
      Tmp_byte = Modc - 2                                   ' âû÷èñëÿåì àäðåñà äëÿ ðàñ÷åòà CRC
      Tmp = Crcmb(mbuf(1) , Tmp_byte)                       ' âû÷èñëÿåì  CRC èç ôðåéìà ïðèíÿòûõ äàííûõ

      If Modw = Tmp Then                                    ' ñðàâíèâàåì ðàñ÷èòàííûé CRC è ïðèíÿòûé CRC
                                                  'ñïðàâåäëèâî äëÿ ôóíêöèé 3,4 è 5,6.Åñëè áóäóò äðóãèå ôóíêöèè êðîìå 3,4 èëè 5,6 òî  äîáàâèòü ñðàâíåíèå ñ ôóíêöèÿìè
         Beg_adr = Makeint(mbuf(4) , Mbuf(3))
         Incr Beg_adr                                       'àäðåñ ðåãèñòà ÷òåíèÿ  (óâåëè÷èâàåì íà 1 òàê êàê èíäåêñ ìàññèâà íà÷èíàåòñÿ îò 1, à àäðåñàöèÿ èäåò ñ 0 - 4000 àäðåñ)


                                                             'âòîðîé áàéò ýòî íîìåð ôóíêöèè
         Select Case Mbuf(2)
                Case 3:                                     'ôóíêöèÿ 3- ÷òåíèå ðåãèñòðîâ
                 N_word = Makeint(mbuf(6) , Mbuf(5))        'êîëè÷åñòâî ñëîâ ÷òåíèÿ
                 If N_word > Maximum_input_registers Then   'ÿ îãðàíè÷èë êîëè÷åñòâî 27 ñëîâàìè
                    N_word = 1                              ' ôîðìèðóåì îøèáêó åñëè â çàïðîñå íà ÷òåíèå áîëüøå 27 ñëîâ
                    Error_mod = Illegal_data_address        'åñëè ïðåâûøåíèå ðàçìåðà áóôåðà òî ôîðìèðóåì îøèáêó 2 - íåïðàâèëüíûé àäðåñ
                 End If
                 N_byte = N_word + N_word                   'êîëè÷åñòâî ñëîâ ïåðåâîäèì â êîë. áàéò
                 Mbuf(3) = N_byte                           'êîë ñ÷èòûâàåìûõ áàéò byte count wieviele Bytes sollen gesendet werden
                 Tmp_byte = 4                               'íà÷èíàåì ñ÷èòàòü ñ 4-ãî áàéòà(1-ûé áàéò äàííûõ)
                 Copy_inputs_to_table
                  '************************ çäåñü áûë êîñÿê For I = Beg_adr To N_word
                  Tmp_byte2 = Beg_adr + N_word              'ôîðìèðóåì èíäåêñ êîëè÷åñòâà ñëîâ ñ ó÷åòîì ñìåùåíèÿ îò íà÷àëüíîãî àäðåñàà
                 For I = Beg_adr To Tmp_byte2               'öèêë çàïèñè â áóôåð îáìåíà çàïðàøèâàåìîãî êîëè÷åñòâà ñëîâ
                     Tmp_byte_modbus = High(table_data(i))  'ðàçáèðàåì ïî áàéòàì íà ñòàðøèé áàéò
                     Mbuf(tmp_byte) = Tmp_byte_modbus       ' çàïèñü â áóôåð îáìåíà  ñ ðàçáèâêîé íà áàéòû (òàáëèöà äàííûõ)
                     Incr Tmp_byte                          '
                     Tmp_byte_modbus = Low(table_data(i))   'ðàçáèðàåì ïî áàéòàì íà ìëàäøèé áàéò
                     Mbuf(tmp_byte) = Tmp_byte_modbus       'çàïèñü â áóôåð îáìåíà  ñ ðàçáèâêîé íà áàéòû (òàáëèöà äàííûõ)
                     Incr Tmp_byte                          '
                 Next I

              N_byte = N_byte + 3                           'íîìåð ïîñëåäíåãî áàéòà ïåðåäàâàåìûõ â ïîñûëêå ñëîâ ñ äàííûìè (òàáëèöà äàííûõ) 3-êîëè÷åñòâî áàéò ïåðåä äàííûìè (íîìåð óñòðîéñòâà, ôóíêöèÿ, êîëè÷åñòâî ïåðåäàâàåìûõ ñëîâ )
              Modw = Crcmb(mbuf(1) , N_byte)                ' create checksum
              Incr N_byte                                   'íîìåð ïðåäïîñëåäíåãî áàéòà âî âñåé ïîñûëêå   ()  (CRC LOW)
              Mbuf(n_byte) = Low(modw)                      'Checksumme LOWer Byte
              Incr N_byte                                   'íîìåð ïîñëåäíåãî áàéòà  âî âñåé ïîñûëêå (CRC High)
              Mbuf(n_byte) = High(modw)                     'Checksumme HIGHer Byte

                  Table_data(8) = Getadc(0) * 100
                  Table_data(8) = Table_data(8) / 205

   Table_data(8) = Table_data(8) * 10

                Case 6:                                     'ôóíêöèÿ 6- çàïèñü îäíîãî ðåãèñòðà
                      Tmp_table_data(beg_adr) = Makeint(mbuf(6) , Mbuf(5))       'çàïèñûâàåì ïîëó÷åííîå çíà÷åíèå
                      W_to_device = 1                       'ôîðìèðóåì ïðèçíàê çàïèñè â óñòðîéñòâî
                      Beg_adr_w = Beg_adr                   'íîìåð ñëîâà äëÿ çàïèñè â ïàìÿòü
                      N_byte = 8
                                               'äëèíà ïîñûëêè äëÿ ôóíêöèè 6 âñåãäà =8 áàéò
                  If Beg_adr_w > 8 Then Error_mod = Illegal_data_address       'íåïðàâèëüíûé àäðåñ ðåãèñòðà ( íåëüçÿ ïèñàòü)
             '  Select Case Beg_adr_w
             '              Case 3 : Nop
             '              Case 12 : Nop
             '              Case 16 : Nop
             '              'Tmp_byte2 = Low(tmp_table_data(beg_adr))
             '              'If Tmp_byte2 > 59 Then  Error_mod = Illegal_data_value
             '              Case 17 : Nop
             '              'Tmp_byte2 = Low(tmp_table_data(beg_adr))
             '              'If Tmp_byte2 > 59 Then  Error_mod = Illegal_data_value
             '              Case 18 : Nop
             '              'Tmp_byte2 = Low(tmp_table_data(Beg_adr_w))
             '              'If Tmp_byte2 > 23 Then Error_mod = Illegal_data_value
             '              Case 19 : Nop
             '              Case 20 : Nop
             '              'Tmp_byte2 = Low(tmp_table_data(beg_adr))
             '              'If Tmp_byte2 > 12 Then Error_mod = Illegal_data_value
             '              Case 21 : Nop
             '              Case Else :
             '              Error_mod = Illegal_data_address 'íåïðàâèëüíûé àäðåñ ðåãèñòðà ( íåëüçÿ ïèñàòü)
             '  End Select
               Case Else:
                      Error_mod = Illegal_function          'íåïîääåðæèâàåìàÿ ôóíêöèÿ

         End Select


         If Error_mod > 0 Then
              Call Error_modbus                             'êîä îøèáêè íåïðàâèëüíûé ôóíêöèîíàëüíûé êîä
         End If

         Call Send_to_master                                'îòâåò ìàñòåðó

      Else                                                  'åñëè íåïðàâèëüíàÿ êîíòðîëüíàÿ ñóììà
                Error_mod = 3                               'êîä îøèáêè Checksumme
                Call Error_modbus
                Call Send_to_master
                T1 = 1                                      'îòâåò ìàñòåðó
               Waitms 3000
               T1 = 0
              ' T2 = 0
      End If
    End If

  Modc = 0
 End If
   NOP
  ' Tmp_byte = Getadc(0)

   NOP

      If W_to_device = 1 Then                               'ïðè íàëè÷èè ïðèçíàêà çàïèñè â óñòðîéñòâî (óñòàâêè, íàñòðîéêè, âûõîäûè ò.ä.)
         Select Case Beg_adr_w                              'ïðè çàïèñè (ôóíêöèÿ 6) Beg_adr = èíäåêñó â ìàññèâå  Table_data

            Case 1 :
                                                     ' àäðåñ 4010 - íîìåð óñòðîéñòâà â ñåòè ìîäáàñ (÷èòàòü ïèñàòü)
                       Modbus_slave = Tmp_table_data(beg_adr_w)       'çàïèñü â ýíåðãîíåçàâèñèìóþ ïàìÿòü
                     Tmp_byte = Modbus_slave
                       Table_data(12) = Tmp_byte
            Case 2 :
                  Tmp_byte = Low(tmp_table_data(beg_adr_w)) ' àäðåñ 4003 - ñåðèéíûé íîìåð (÷èòàòü ïèñàòü)
                  Serial_numb_l = Tmp_byte                  'çàïèñü â ýíåðãîíåçàâèñèìóþ ïàìÿòü
                  Tmp_byte = High(tmp_table_data(beg_adr_w))
                  Serial_numb_h = Tmp_byte
                  Table_data(3) = Tmp_table_data(beg_adr_w) 'çàïèñü â òàáëèöó
         '   Case 13 :                                       ' àäðåñ 4011 - óñòàâêà âåðõ  (÷èòàòü ïèñàòü)
         '            '  Ust1_up = Table_data(beg_adr_w)      'çàïèñü â ýíåðãîíåçàâèñèìóþ ïàìÿòü
         '   Case 14:                                        ' Frame_value=äåëèòåëü -(âðåìÿ â ìñ / çàäàííîå çíà÷åíèå âðåìåíè ïðåðûâàíèÿ çà îäèí òàêò)    256-(âðåìÿ â ìñ/0.0032)
         '              Tmp = Table_data(beg_adr_w) * 100
         '              Tmp = Tmp \ 32
         '                       Table_data(14) = Tmp
         '                       Frame_value = 256 - Tmp
         '                       Table_data(15) = Frame_value       'îò 1 äî 82ìñåê
         '
         '            Frame_value = Frame_value_dev
              Case 3
              Ñåêóíäû = Low(tmp_table_data(beg_adr_w))
              Ñåêóíäû = Makebcd(ñåêóíäû)
               Call Çàïèñü_i2c(çàïèñü_ds1307 , Const_ñåêóíäû , Ñåêóíäû)
              Case 4
              Ìèíóòû = Low(tmp_table_data(beg_adr_w))
              Ìèíóòû = Makebcd(ìèíóòû)
               Call Çàïèñü_i2c(çàïèñü_ds1307 , Const_ìèíóòû , Ìèíóòû)
              Case 5
              ×àñû = Low(tmp_table_data(beg_adr_w))
              ×àñû = Makebcd(÷àñû)
               Call Çàïèñü_i2c(çàïèñü_ds1307 , Const_÷àñû , ×àñû)
              Case 6
              ×èñëî_ìåñÿöà = Low(tmp_table_data(beg_adr_w))
              ×èñëî_ìåñÿöà = Makebcd(÷èñëî_ìåñÿöà)
               Call Çàïèñü_i2c(çàïèñü_ds1307 , Const_÷èñëî_ìåñÿöà , ×èñëî_ìåñÿöà)
              Case 7
              Ìåñÿö = Low(tmp_table_data(beg_adr_w))
              Ìåñÿö = Makebcd(ìåñÿö)
               Call Çàïèñü_i2c(çàïèñü_ds1307 , Const_ìåñÿö , Ìåñÿö)
              Case 8
              Ãîä = Low(tmp_table_data(beg_adr_w))
              Ãîä = Makebcd(ãîä)
               Call Çàïèñü_i2c(çàïèñü_ds1307 , Const_ãîä , Ãîä)

         End Select
         W_to_device = 0
      End If


 '===============================================================

    Call Copy_inputs_to_table

   ' âðåìÿ ïîñëåäíåé ñðàáîòàâøåé çàùèòû
  If Tmpl_input <> Table_data(6) Then
    Tmpl_input = Table_data(6)
    L_input = Table_data(6)
    Table_data(28) = Tmpl_input
    Table_data(26) = Ñåêóíäû
   Table_data(27) = Ìèíóòû
   Table_data(24) = ×àñû
   Table_data(25) = ×èñëî_ìåñÿöà
   Table_data(22) = Ìåñÿö
   Table_data(23) = Ãîä
   L_time(1) = Ñåêóíäû
   L_time(2) = Ìèíóòû
   L_time(3) = ×àñû
   L_time(4) = ×èñëî_ìåñÿöà
   L_time(5) = Ìåñÿö
   L_time(6) = Ãîä
  End If
  '=========================================================

       If Ôëàã_îïðîñèòü_ds1307 <> 0 Then
        T2 = Not T2
        I2cstart
I2cwbyte &HD0
I2cwbyte &H00
I2cstart
I2cwbyte &HD1
I2crbyte Ñåêóíäû , Ack
I2crbyte Ìèíóòû , Ack
I2crbyte ×àñû , Ack
I2crbyte Äåíü_íåäåëè , Ack
I2crbyte ×èñëî_ìåñÿöà , Ack
I2crbyte Ìåñÿö , Ack
I2crbyte Ãîä , Nack
I2cstop
         Ãîä = Makedec(ãîä)                                 ' Ãîä
         ×àñû = Makedec(÷àñû)                               ' ×àñû
         Ìåñÿö = Makedec(ìåñÿö)                             ' Ìåñÿö
         Ìèíóòû = Makedec(ìèíóòû)                           ' Ìèíóòû
         Ñåêóíäû = Makedec(ñåêóíäû)                         ' Ñåêóíäû
         Äåíü_íåäåëè = Makedec(äåíü_íåäåëè)                 ' Äåíü íåäåëè
         ×èñëî_ìåñÿöà = Makedec(÷èñëî_ìåñÿöà)               ' ×èñëî

         Ôëàã_îïðîñèòü_ds1307 = 0

  Table_data(16) = Ñåêóíäû
   Table_data(17) = Ìèíóòû
   Table_data(18) = ×àñû
   Table_data(19) = ×èñëî_ìåñÿöà
   Table_data(20) = Ìåñÿö
   Table_data(21) = Ãîä


     End If

 '     Waitms 100




 Loop

  Urxc_isr:                                                 '  ïðåðûâàíèå ïî ïðèåìó äàííûõ
   sbis usr, 7                                              ' Wait for character
   rjmp urxc_isr                                            ' wait until we can read the byte
  Modt = Udr                                                ' get the byte
  Load Timer1 Load_timer                                    'Frame_value                                   'óñòàíàâëèâàåì çíà÷åíèå òàéìåðà òèøèíû ìåæäó ôðåéìàìè
  Start Timer1                                              'ñòàðòóåì òàéìåð ôðåéìà
  Incr Modc                                                 'óâåëè÷èâàåì ñ÷åò÷èê ïðèíÿòîãî áàéòà
  Mbuf(modc) = Modt                                         ' ïèøåì â áóôåð çíà÷åíèå ïðèíÿòîãî áàéòà

 Return

 Utxc_isr:
                                                    'Ïîäïðîãðàììà ïåðåäà÷è äàííûõ
 If Cnt_print = 1 Then                                      ' åñëè ïîñëåäíèé áàéò ïåðåäàí
   Enable_tx = 0                                            ' ðàçðåøàåì ïðèåì (çàïðåùàåì ïåðåäà÷ó )
   Cnt_print = 0                                            ' îáíóëÿåì ïðèçíàê ïîñëåäíåãî áàéòà ïåðåäà÷è
   Disable Utxc                                             ' çàïðåàåì ïðåðûâàíèå.
  End If

 Return


 Sub Send_to_master
    Enable Utxc                                             'ðàçðåøàåì ïðåðûâàíèå ïî
    If Enable_tx = 0 Then
     Enable_tx = 1
     For I = 1 To N_byte                                    'îòâåò ìàñòåðó.  öèêë äëÿ ïåðåäà÷è áóôåðà îáìåíà ñ çàäàííûì êîë. áàéò c çàäàííîãî àäðåñà
     Print Chr(mbuf(i));                                    'îòïðàâêà áóôåðà îáìåíà â Íåõ
     Next
    ' Print N_byte ;
     Cnt_print = 1
   End If
 End Sub
 Sub Error_modbus
 'N_byte = Modc
  '      Mbuf(1) = Modbus_slave                              'ôóíêöèÿ ôîðìèðîâàíèÿ ïàêåòà èñêëþ÷èòåëüíîãî îòâåòà ìàñòåðó ïî îøèáêå.
  '    Mbuf(2) = Modc                                        ' 1äðåñ,2ôóíêö.êîä ñ 1(åäèíèöåé),3êîä îøèáêè,4,5CRC âñåãî 5 áàéò
  '   Mbuf(3) = Error_mod                                    'êîä îøèáêè (1- íåïðàâèëüíûé ôóíöèîíàëüíûé êîä(íåïîääåðæèâàåìàÿ ôóíêöèÿ); 2- íåïðàâèëüíûé àäðåñ; 3- íåïðàâèëüíûå äàííûå (CRC). )
  '   Modw = Crcmb(mbuf(1) , 3)                              ' create checksum
  '    Mbuf(4) = Low(modw)                                   'Checksumme LOWer Byte
  '    Mbuf(5) = High(modw)                                  'Checksumme HIGHer Byte
      N_byte = 7

 End Sub

 Modbus_timers:                                             'ïðåðûâàíèå ïî òàéìåðó.  íåì îðãàíèçîâàíî äâà ñ÷åò÷èêà. Ïî îäíîìó ñ÷åò÷èêó îáðàáîòêà ïàêåòà ïðèíÿòûõ ñîîáùåíèé ìîäáàñ, ïî äðóãîìó çàäåðæêà íà îòêëþ÷åíèå ïåðåäàò÷èêà TX â 485.

   Stop Timer1
'    Call Modbus_exec                                              'îñòàíàâëèâàåì ïðåðûâàíèå ïî òàéìåðó òèøèíû ìåæäó ôðåéìàìè
   Md_t_start = 1                                           'âûñòàâëÿåì ïðèçíàê òîãî, ÷òî â áóôåðå ïðèíÿò ôðåéì

 Return


 Sub Copy_inputs_to_table
   Table_data(6).0 = Input_1
   Table_data(6).1 = Input_2
   Table_data(6).2 = Input_3
   Table_data(6).3 = Input_4
   Table_data(6).4 = Input_5
   Table_data(6).5 = 1
   Table_data(6).6 = 1
   Table_data(6).7 = 1

End Sub



'===============================================================================
  Sub Çàïèñü_i2c(byval Àäðåñ_÷èïà_çàïèñü As Byte , Byval Ðåãèñòð_÷èïà As Byte , Byval Çàïèñûâàåìàÿ_ïåðåìåííàÿ As Byte)
'-------------------------------------------------------------------------------
    I2cstart                                                ' Ïîäãîòîâêà ê ðàáîòà øèíû I2c
    I2cwbyte Àäðåñ_÷èïà_çàïèñü                              ' Àäðåñíîå îáðàùåíèå ê èñïîëüçóåìîìó ÷èïó i2c, äëÿ çàïèñè
    I2cwbyte Ðåãèñòð_÷èïà                                   ' Àäðåñ ðåãèñòðà, â êîòîðûé áóäåò ïðîèçâîäèòüñÿ çàïèñü
    I2cwbyte Çàïèñûâàåìàÿ_ïåðåìåííàÿ                        ' Çàïèñûâàåìàÿ ïåðåìåííàÿ
    I2cstop                                                 ' Îñâîáîæäàåì øèíó I2c
'-------------------------------------------------------------------------------
Waitms 10
  End Sub
'===============================================================================


'===============================================================================
'  Ïîäïðîãðàììà äëÿ îáðàáîòêè ïðåðûâàíèÿ èíèöèèðóåìîãî ñåêóíäíûìè èìïóëüñàìè ñ âûâîäà "SQW/OUT" Ds1307
'=================<===<=<=<=<===<===<=<=<=<=====================================
  Ïðåðûâàíèå_ds1307:                                        ' ñ ïîìîùüþ ASM AVR
'-------------------------------------------------------------------------------
    $asm
      push R16                                              ' Âðåìÿ âûïîëíåíèÿ èíñòðóêöèè, 2 òàêòà
      ldi R16 , 1                                           ' Çàãðóçèòü êîíñòàíòó, âðåìÿ âûïîëíåíèÿ èíñòðóêöèè, 1 òàêò
      sts {Ôëàã_îïðîñèòü_ds1307} , R16                      ' Çàãðóçèòü çíà÷åíèå ðåãèñòðà â ïåðåìåííóþ, âðåìÿ âûïîëíåíèÿ èíñòðóêöèè, 2 òàêòà
      Pop R16                                               ' Âðåìÿ âûïîëíåíèÿ èíñòðóêöèè, 2 òàêòà
      reti                                                  ' Âðåìÿ âûïîëíåíèÿ èíñòðóêöèè, 4 òàêòà
    $end Asm
'-------------------------------------------------------------------------------
  Return
'===============================================================================

и тут проблемка, если я эмулирую это в протеусе, и опрашиваю программой Modbus Tester через виртуальный порт то все работает
собрал схемку в железе, все...., не работает,
устройство показывает  ошибку CRC в принятом пакете
, сделал  так чтобы устройство при ошибке ЦРЦ отправляло обратно принятый пакет ( ну чтоб модно было посмотреть что оно там получило) в ответ приходят первые 2 байта правильные а дальше какаято муйня

Отредактировано Penumbra (2015-11-11 23:19:51)

0

15

лог ответа от железа:

Код:
12.11.15 10:28:55.679 TRANSPORT         : SERIAL line
12.11.15 10:28:55.679 SETTINGS          : COM4,9600,8,None,2,None
12.11.15 10:28:55.679 REPLY TIMEOUT     : 3000ms
12.11.15 10:28:55.679 DELAY BEFORE SEND : 100ms
12.11.15 10:28:55.679 PACKET TIMEOUT    : 300ms
12.11.15 10:28:55.749 Line/socket open succefull
12.11.15 10:28:55.749 
12.11.15 10:28:55.759     Dev:01h Func:03h R.HReg Addr:0001h Qu/Val:001Bh 8bytes
12.11.15 10:28:55.759 TX: 01 03 00 01 00 1B 54 01 
12.11.15 10:28:56.179 RX: 01 03 54 00 00 00 00 
12.11.15 10:28:56.179     ERROR: CRC error
12.11.15 10:28:56.279     Dev:01h Func:03h R.HReg Addr:0001h Qu/Val:001Bh 8bytes
12.11.15 10:28:56.279 TX: 01 03 00 01 00 1B 54 01 
12.11.15 10:28:59.299     ERROR: Timeout
12.11.15 10:28:59.299     Dev:01h Func:03h R.HReg Addr:0001h Qu/Val:001Bh 8bytes
12.11.15 10:28:59.299 TX: 01 03 00 01 00 1B 54 01 
12.11.15 10:28:59.649 RX: 01 03 54 00 00 00 00 
12.11.15 10:28:59.649     ERROR: CRC error
12.11.15 10:28:59.759     Dev:01h Func:03h R.HReg Addr:0001h Qu/Val:001Bh 8bytes
12.11.15 10:28:59.759 TX: 01 03 00 01 00 1B 54 01 
12.11.15 10:29:02.769     ERROR: Timeout
12.11.15 10:29:02.769     Dev:01h Func:03h R.HReg Addr:0001h Qu/Val:001Bh 8bytes
12.11.15 10:29:02.769 TX: 01 03 00 01 00 1B 54 01 
12.11.15 10:29:03.159 RX: 01 03 54 00 00 00 00

лог ПРАВИЛЬНОГО ответа от протеуса

Код:
11.11.15 22:13:11.026 SETTINGS          : COM2,9600,8,None,2,None
11.11.15 22:13:11.026 REPLY TIMEOUT     : 3000ms
11.11.15 22:13:11.026 DELAY BEFORE SEND : 100ms
11.11.15 22:13:11.026 PACKET TIMEOUT    : 300ms
11.11.15 22:13:11.026 Line/socket open succefull
11.11.15 22:13:11.026 
11.11.15 22:13:11.036     Dev:0Ah Func:03h R.HReg Addr:0001h Qu/Val:001Bh 8bytes
11.11.15 22:13:11.036 TX: 0A 03 00 01 00 1B 55 7A 
11.11.15 22:13:14.096 RX: 0A 03 36 01 01 00 00 02 94 FF FF 00 E0 FF FF 03 E8 FF FF FF FF FF FF 00 0A FF FF FF FF 00 FD 00 19 00 05 00 15 00 0C 00 04 00 0E 00 04 00 0E 00 14 00 0C 00 30 00 15 00 E0 8A B5 
11.11.15 22:13:14.206     Dev:0Ah Func:03h R.HReg Addr:0001h Qu/Val:001Bh 8bytes

сейчас попытаюсь проект протеуса прикрутить

Отредактировано Penumbra (2015-11-12 11:31:46)

0

16

он почемуто теряет байты  00 01 00 1B в запросе

0

17

все, заработало,  надо было рукой за корпус блока питания держаться)))

0

18

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

Мультипроцессорный USART, 9-ти битный, адресный...

В документации не понял, как определить 9й бит, он просто в регистре появляется или может вызвать прерывание или с помощью его как-то можно аппаратно залазить в регистры?

0

19

в даташите на АВР всё это расписано, используется бит другого регистра

Код:
   While Ucsr0a.udre = 0 : Wend       ' Ждём освобождения буфера передатчика
   Ucsr0b.txb8 = 1            '  0 разряд - TXB8 = 9й бит передаваемых данных
   Udr = Massiv(1)            ' загрузка байта в буфер передатчика
Код:
      temp = Ucsr0b   ' читаем 9й бит (8й разряд) ответа
      data_my = Udr

0

20

Настало время модбусить!
Есть устройство и известные характеристики:
Протокол Modbus RTU
Интерфейс EIA-485
Кол-во преобразователей от 1 до 32
Скорость 9600 8 бит, 2 стоповых без контроля чётности
Проверка на ошибки CRC16

Дан пример чтения состояния регистра управления:

Запрос:

Адрес

Функция

нач.адрес

кол-во байт

Проверка CRC

0x01

0x03

0x00   |  0x01

0x00   |  0x01

0xD5   |  0xCA

Ответ:

Адрес

Функция

Счётчик байтов

Данные

Проверка CRC

0x01

0x03

0x02

0x11   |   0x40

0xB5   |   0xE4

Забегаю в Bascom, конфигурирую всё на приём и отправку, но ничего не происходит, точней по осциллографу отправка по RS485 с модуля идёт, ответов нет. Скорости совпадают и походу чего-то не получается у меня правильно отправить всё.
Упрощенна делаю для эксперимента так:

Код:
Rsout(1) = &H01
Rsout(2) = &H03
Rsout(3) = &H00
Rsout(4) = &H01
Rsout(5) = &H00
Rsout(6) = &H01
Rsout(7) = &HD5
Rsout(8) = &HCA

Set Txout 'Включаю передачу на модуле
Waitms 1
For P = 1 To 8
  Brs = Rsout(p)
  Printbin #2 , Brs
Next P 
Reset Txout

Но ответа не наны  :dontknow: .

Но ещё больше удивило то, что оператор CRC16 выдаёт другой результат.

Код:
Dim Crc As Word 

Crc = Crc16(rsout() , 6)
Rsout(8) = High(crc)
Rsout(7) = Low(crc)

Кто сталкивался, много экзорцизма в передаче данных по RS485 с MODUS?

0

21

Ты постоянно ответ слушаешь? А то "Waitms 1" задержка как-то большая, за это время может и ответ прилететь (даже не заметишь).
С CRC вечная проблема с полиномой, может не совпадать, надо вначале убедится, что на обоих концах/устройствах оно совпадает, кстати говоря, без совпадения можно даже и ответ не получить.

0

22

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

Ты постоянно ответ слушаешь? А то "Waitms 1" задержка как-то большая, за это время может и ответ прилететь (даже не заметишь).
С CRC вечная проблема с полиномой, может не совпадать, надо вначале убедится, что на обоих концах/устройствах оно совпадает, кстати говоря, без совпадения можно даже и ответ не получить.

Ответ если прилетит - то тут сразу увижу любой прилетевший байт.
CRC пока отставил, использовал данные из таблицы примера.
Воспользовался OnLine калькулятором CRC-16, там есть совпадение но байты наоборот:
http://sh.uploads.ru/t/QyKxq.png
Какой-то CRC-16 специально для MODBUS имеется, чего-то странное тут.

0

23

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

полиномой

Заразная эта полинома!!!!
В Bascom расчёт CRC16 не Modbus, а CRC-CCITT (Xmodem).
Чтоб получить CRC-16 для Modbus RTU, нужно воспользоваться Crc16uni
Примерно вот так:
Crc = Crc16uni(rsout(1) , 6 , &HFFFF , &H8005 , 1 , 1) 
Источник - https://www.mcselec.com/index2.php?opti … ight=crc16

Это злодейство какое-то! Неужели нельзя было проще сделать контрольную сумму, такой же алгоритм сложно сделать на аппаратном уровне.

0

24

Я уже давно с этой полиномой сталкивался, ещё когда надо было с МК на сервак (ПыСы) удаленно данные отправлять/принимать.

0

25

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

.....надо было с МК на сервак (ПыСы) удаленно данные отправлять/принимать.....

Если на комп вообще проблем нет, это же обычный Uart, только в момент отправки надо передачу включать.
Проблема начинается как раз с CRC всякими )))).
Сейчас чувствую проблема в длинном проводе и скрученным как-то не очень, выдернул две жилы из толстого телефонного кабелища.

0

26

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

Если на комп вообще проблем нет

Ты не понял, через инет на сервер с своим протоколом (там свой CRC был, надо было писюшный синхронизировать с баскомовским).

0

27

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

Ты не понял, через инет на сервер с своим протоколом ....

Ну не, я ещё недостиг этого.

Понял почему глюков словил.

Оказывается PrintBin не совсем простой оператор, он массивы может целиком закидывать, к примеру если вот так:

Config Base = 1
Dim Rsout(8) As Byte
Dim Crc As Word

Rsout(1) = 1
Rsout(2) = 3
Rsout(3) = 0
Rsout(4) = 1
Rsout(5) = 0
Rsout(6) = 1
Crc = Crc16uni(rsout(1) , 6 , &HFFFF , &H8005 , 1 , 1) 
Rsout(8) = High(crc)
Rsout(7) = Low(crc)

Set Txout
Waitms 2

Printbin #4 , Rsout()
Waitms 8
Reset Txout

Правда не знаю как он чего там делает, может и за границы уйдёт, странный оператор.

Предполагаю, когда байты отсылаются через UART, оператор отправляет каждый байт по опустошению буфера, бит готовности отправки буфера появляется не после полной отправки, а примерно после 4го отправленного бита + ещё стоповые и т.п., то-есть после отправки последнего байта в массиве нужно ждать паузе прежде чем отключить сигнал отправке на модуле RS485, иначе он не отправит.

0

28

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

Оказывается PrintBin не совсем простой оператор, он массивы может целиком закидывать, к примеру если вот так

На самом деле, почитай внимательнее как им пользоваться, да он может весь массив отправлять, но лучше как в хелпе, после запятой количество байт из массива (а то мало ли куда дальше пойдёт отправлять).

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

Предполагаю, когда байты отсылаются через UART...

Ага, только лучше ограничивать, а так оно само всё делается. Если включишь буфера, то вообще шоколад, всё само течет, правда получится асинхронка и тут надо ещё дергать дирекшен, контроллировать через (возможно) флаги (у xmega они там свои, в хелпе найти не могу (web).

0

29

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

... флаги (у xmega они там свои, в хелпе найти не могу (web).

Да это не проблема (выход из Do Loop по "Usartd0_status.5 = 1"), проблема в том, что флаги устанавливаются не в конце завершение передачи байта, а на его середине, что означает надо как-то учесть задержку отключения сигнала передачи в модуле RS485:

Свернутый текст

http://gloimg.gbtcdn.com/gb/2015/201507/goods-img/1487062740233732625.jpg

Отредактировано Ev3658 (2018-01-25 10:00:12)

0

30

Вот к примеру:
Скорость 9600бод., контроллер работает на 29491200 Гц.

Отправляем 8 байт. Перед отправкой подаём сигнал на модуль RS485 для переключения в режим передачи, после отправки отключаем.
Чтоб послать следующий байт после предыдущего, делаю выход из бесконечного цикла по завершению передачи (TXCIF)
Участок когда:

Свернутый текст
Код:
Set Txout

Usartd1_data = Rsout(1)
Do
Loop Until Usartd1_status.6 = 1

Usartd1_data = Rsout(2)
Do
Loop Until Usartd1_status.6 = 1

Usartd1_data = Rsout(3)
Do
Loop Until Usartd1_status.6 = 1

Usartd1_data = Rsout(4)
Do
Loop Until Usartd1_status.6 = 1

Usartd1_data = Rsout(5)
Do
Loop Until Usartd1_status.6 = 1

Usartd1_data = Rsout(6)
Do
Loop Until Usartd1_status.6 = 1

Usartd1_data = Rsout(7)
Do
Loop Until Usartd1_status.6 = 1

Usartd1_data = Rsout(8)
Do
Loop Until Usartd1_status.6 = 1

Reset Txout

Осциллограмма:
http://s9.uploads.ru/t/4RSCe.png
Цифра два - это переключатель модуля в режим передачи.

А вот это по флагу прерывания опустошения буфера данных (DREIF):

Свернутый текст
Код:
Set Txout

Usartd1_data = Rsout(1)
Do
Loop Until Usartd1_status.5 = 1

Usartd1_data = Rsout(2)
Do
Loop Until Usartd1_status.5 = 1

Usartd1_data = Rsout(3)
Do
Loop Until Usartd1_status.5 = 1

Usartd1_data = Rsout(4)
Do
Loop Until Usartd1_status.5 = 1

Usartd1_data = Rsout(5)
Do
Loop Until Usartd1_status.5 = 1

Usartd1_data = Rsout(6)
Do
Loop Until Usartd1_status.5 = 1

Usartd1_data = Rsout(7)
Do
Loop Until Usartd1_status.5 = 1

Usartd1_data = Rsout(8)
Do
Loop Until Usartd1_status.5 = 1

Reset Txout

http://sf.uploads.ru/t/5dnYl.png

Во втором случае работает как надо, но надо учесть задержку отключения режима передачи модуля.

Вот так вот работает PRINTBIN:

Код:
Set Txout
Printbin #4 , Rsout()
Reset Txout 


http://s3.uploads.ru/t/gMvyY.png

Но заводской блок ЧПУ ответ даст при такой осциллограмме:

Код:
Set Txout
Waitms 2
Printbin #4 , Rsout()
Waitms 5
Reset Txout

http://s7.uploads.ru/t/edRZt.png

Отредактировано Ev3658 (2018-01-25 10:13:36)

0