'------------------------------------------------------------------------------
'                       (c) 2002-2003 MCS Electronics
'                            MODBUS RTU SLAVE Sample
'        see   http://www.modicon.com/techpubs/dcon7.html  for more details
'------------------------------------------------------------------------------
'modbus.lib contains the crcMB function
$lib "modbus.lbx"


$regfile = "2313def.dat"                                    ' chip used
$crystal = 8000000                                          ' xtal used
$baud = 19200                                               ' baudrate N,8,1

'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


'dimension a buffer for the modbus data
Dim Mbuf(8) As Byte , Modc As Byte , Modt As Byte , Modw As Word

'the sample used an lcd to display the data
'
Config Lcd = 24 * 2
Config Lcdpin = Pin , Db4 = Portb.4 , Db5 = Portb.5 , Db6 = Portb.6 , Db7 = Portb.7 , Rs = Portb.2 , E = Portb.3
Cls
Dim Xx As Byte

Config Portd = Input                                        'so we can return the value of portD
Portd = 255

'we use the receive interrupt to receive the data
On Urxc Urxc_isr
Enable Urxc
Enable Interrupts



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
       Cls                                                  'clear display
       For Xx = 1 To 8
         Lcd Hex(mbuf(xx)) ; " "                            ' show the data
       Next
       Modw = Makeint(mbuf(7) , Mbuf(8))                    ' create word of reeived crc
       If Modw = Crcmb(mbuf(1) , 6) Then                    ' does the crc match?
          Lowerline : Lcd "match"                           'show it
          ' write the response here
          If Mbuf(2) = 6 Then                               ' function 6 to write data
             '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) = Pind                                 ' 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


