Hallo,
hab einen Source für das SNAP-Protokoll geschrieben. Inzwischen sehr komlex geworden. Hab bisher alles mit Gosub und goto aufgerufen. Aber jetzt will ich das alles Sauber mit Sub-Funktionen lösen. Aber irgendwas mach ich falsch.
Code:
' This Code suspend:
'
' from 1 to 512 Databytes
' crc16-ccitt, 8Bit-Checksumm or non Error detection Method
' ACK/NACK or non ACK/NACK- Mode for Recieve
' 8Bit Addresses for max.255 user
'
'
'
' the variables are:
'
' hdb1  = hederbyte1
' hdb2  = headrbyte2
' db(x) = Databyte x
' dab1  = destination adressbyte1 (only one Byte)
' sab1  = source adressbyte1 (only one Byte)
' rx    = recievebit
' tx    = sendbit
' wts   = wait-to-send bit
' rtr   = ready-to-recieve bit
' myadress= adress of this unit
'
' to controll are the Bits:
'
' crcen   = crc-16 ccitt function enable
' hdben   = hake_hdb - function enable
' cmdmode = rx, tx, wts, rtr enable
' are this Bits set of 1 then the functions are enable
'
' Standart definition is two databytes and crc-ccitt error detection
'
' The packet structure is defined in the received packets first two
' bytes (HDB2 and HDB1). The following packet structure is used.
'
' DD=01     - 1 Byte destination address (one Byte lengh)
' SS=01     - 1 Byte source address (one Byte lengh)
' PP=00     - No protocol specific flags
' AA=01     - Acknowledge is required
' D=0       - No Command Mode
' EEE=100   - 16-bit CRC-CCITT
' NNNN=1111 - max. 512 Byte data (0000 and 1111 -> 0Bytes)
'
' Overview of header definition bytes (HDB2 and HDB1)
'
'         HDB2             HDB1               DAB1              SAB1
' +-----------------+-----------------+-----------------+-----------------+
' | D D S S P P A A | D E E E N N N N | X X X X X X X X | X X X X X X X X |
' +-----------------+-----------------+-----------------+-----------------+
'
' -----[ Declairs ]---------------------------------------------------
'
Declare Sub Sendsnap(byval Dab1 As Byte , Db(1) As Byte)
Declare Sub Sendsnapback(byval Db(1) As Byte)
Declare Function Recievesnap(db(16) As Byte) As Byte
'
' -----[ Constants ]--------------------------------------------------
'
Const Sync_ = &B01010100                                    ' Synchronisation byte
Const Crcpoly = &H1021                                      ' CRC-CCITT
Const Hdb2_ = &B01010001                                    ' HDB2
Const Hdb1_ = &B01001111                                    ' HDB1
Const Myaddress = 123                                       ' Address for this node (1-255)
Const Cmdmode = 0
Const Crcen = 1
Const Hdben = 1
'
' -----[ Variables ]--------------------------------------------------
'
'Myaddress                                                     address
'Cmdmode                                                       Command mode give the Status of SNAP
'dim Rx as bit                                                 Recieve Active Bit
'dim Tx as bit                                                 Send Active Bit
'dim Rtr as bit                                               "Ready to recieve" Bit
'dim Wts as bit                                               "Wait to send" Bit (can used at interrupt-output to send)
'dim crcen as bit
Dim Sb As Bit                                               ' Send Back Bit
Dim Crc As Word                                             ' CRC Word
Dim Hdb1 As Byte                                            ' Header Definition Byte 1
Dim Hdb2 As Byte                                            ' Header Definition Byte 2
Dim Dab1 As Byte                                            ' Empfängeradresse
Dim Sab1 As Byte                                            ' Senderadresse
                                                             ' lengh of databytes as word
Dim Db(16) As Byte                                          ' Packet Data Bytes (max.16 for smaler uCs)
Dim Databytes As Byte                                       ' lengh of  databytes as byte
Dim Crc2 As Byte                                            ' Packet CRC Hi_Byte
Dim Crc1 As Byte                                            ' Packet CRC Lo_Byte
Dim Temp1 As Byte                                           ' Temporary Variable Byte
Dim Temp2 As Byte                                           ' Temporary Variable Byte
Dim Tmp3 As Byte                                            ' Temporary Variable Byte
Dim Tmpw1 As Word                                           ' Temponary Variable Word
Dim Tmpw2 As Word                                           ' Temponary Variable Word
'
' -----[ Initialization ]---------------------------------------------
'
Baud = 19200
'
' -----[ Program ]----------------------------------------------------
'


Sub Recievesnap(db(16) As Byte)
Snap:
    #if Cmdmode = 1
    Reset Rx
    Set Rtr
    #endif

    Temp1 = Waitkey()                                       ' Wait for data on serialport
    ' If received data is a SYNC byte read next eight bytes
    ' from master, if not return to snap
    If Temp1 <> Sync_ Then Goto Snap

    #if Cmdmode = 1
    Reset Rtr
    Set Rx
    #endif

        ' Get packet in binary mode
        Inputbin Hdb2 , Hdb1 , Dab1 , Sab1 ,

        Gosub Databytes
        If Databytes = 0 Then Goto Snp
        For Tmp3 = Databytes To 1 Step -1
        Inputbin Db(tmp3),
        Next Tmp3
Snp:
        If Hdb1.6 = 1 Then Inputbin Crc2 , Crc1

        ' Check HDB1 to see if MCu are capable to use the packet
        ' structure, if not goto Snap

        Temp2 = Hdb1 Or &B01001111
        If Temp2 <> Hdb1_ Then Goto Snap

        ' Packet header check routine
        '
        ' Check HDB2 to see if MCU are capable to use the packet
        ' structure, if not goto Snap

        Temp2 = Hdb2 Or &B00000001
        If Temp2 <> Hdb2_ Then Goto Snap

        ' Address check routine
        '
        ' Check if this is the node addressed, if not goto Snap
        If Dab1 <> Myaddress Then Goto Snap

        If Hdb1.6 = 1 Then Goto Nocrc

        ' Check CRC for all the received bytes
        Gosub Check_crc
        Gosub Checkcrc

        #if Cmdmode = 1
        Reset Rx
        #endif

        ' Check if there was any CRC errors, if so send NAK
        If Crc <> 0 And Hdb2.0 = 1 Then Goto Nak

        ' No CRC errors in packet so check what to do.
Nocrc:

        If Hdb2.0 = 1 Then Goto Ack_ Else End Sub


Ack_:
        ' Send ACK (i.e tell master that packet was OK)
        ' Set ACKs bit in HDB2 (xxxxxx10)
        Hdb2 = Hdb2 Or &B00000010
        Hdb2 = Hdb2 And &B11111110
        Hdb1 = &H0
        Call Sendsnapback(0)
        End Sub
Nak:
        ' Send NAK (i.e tell master that packet was bad)
        ' Set ACK bits in HDB2 (xxxxxx11)
        Hdb2 = Hdb2 Or &B00000011
        Hdb1 = &H0
        Call Sendsnapback(0)
        End Sub


Sub Sendsnapback(db(1) As Byte)
Sendback:

        Set Sb
        Goto Send

Sub Sendsnap(dab1 As Byte , Db(16)as Byte)
Send:
        If Hdb1 = 0 Or Hdb2 = 0 Then Gosub Make_hdb
        ' if send no ACK or NACK then send without ACK-Command
        If Hdb2.1 = 0 Then Hdb2 = Hdb2 And &B11111100
        ' if CRC is not requied then dont calc crc
        If Hdb1.6 = 1 Then Goto _send

        ' Clear CRC variable
        Crc = 0
        Gosub Check_crc

        ' Move calculated Hi_CRC value to outgoing packet
        Crc2 = High(crc)
        ' Move calculated Lo_CRC value to outgoing packet
        Crc1 = Low(crc)

        ' Send packet to master, including the preamble and SYNC byte

_send:
        Temp1 = &B00001111 And Hdb1
        If Temp1 < 1 Then
                     Hdb1 = Hdb1 And &B11110001
                     Temp1 = 1
                   End If
        If Temp1 = 1 Then Databytes = 1 Else Databytes = 0

        'check the Databus at three times, when its this times free then send

        #if Cmdmode = 1
        Set Wts
        #endif

        For Temp2 = 1 To 3
Chcksnd:
        Temp1 = Inkey()                                     'look for character
        If Temp1 > 0 Then                                   'is variable > 0?
        Temp2 = 1
        Waitms 1
        Goto Chcksnd
        End If
        Next Temp2

        #if Cmdmode = 1
        Reset Wts
        Set Rx
        Waitus 100
        #endif

        Print &H0 ; Sync_ ;
        Print Chr(hdb2) ; Chr(hdb1) ;
        ' is the command sendback, then swap print dab1 and sab1
        If Sb = 1 Then Print Chr(sab1) ; Chr(dab1) ; Else Print Chr(dab1) ; Chr(sab1) ;
        Temp1 = &B00001111 And Hdb1
        If Temp1 = 0 Then Goto Snd:
        Print Chr(db(1));
Snd:
        If Hdb1.6 = 1 Then Print Chr(crc2) ; Chr(crc1) ;

        ' Give AVR time to shift out all bits before setting to Rx
        Waitms 5

        Reset Sb

        #if Cmdmode = 1
        Reset Rx
        #endif

        ' Done, go back to Start and wait for a new packet
        End Sub


' -----[ Subroutines ]------------------------------------------------
'
' created Header- Bytes
Make_hdb:

Hdb1 = &B00000001
Hdb2 = &B01010000
Return



' Soubroutine for checking all received bytes in packet
Check_crc:

        Crc = 0
        Gosub Databytes

        Temp1 = Hdb2
        Gosub Calc_crc
        Temp1 = Hdb1
        Gosub Calc_crc
        Temp1 = Dab1
        Gosub Calc_crc
        Temp1 = Sab1
        Gosub Calc_crc
        If Databytes = 0 Then Return
        For Tmp3 = Databytes To 1 Step -1
        Temp1 = Db(tmp3)
        Gosub Calc_crc
        Next Tmp3
        Return

Checkcrc:

        Temp1 = Crc2
        Gosub Calc_crc
        Temp1 = Crc1
        Gosub Calc_crc
        Return

' Subroutine for calculating CRC value in variable Tmp_Byte1
Calc_crc:

        Tmpw1 = Temp1 * 256
        Crc = Tmpw1 Xor Crc
        For Temp2 = 0 To 7
            If Crc.15 = 0 Then Goto Shift_only
            Tmpw2 = Crc * 2
            Crc = Tmpw2 Xor Crcpoly
            Goto Nxt
Shift_only:
            Crc = Crc * 2
Nxt:
        Next
        Return

' Subroutine to scan the lengh of Databytes
Databytes:

   Temp1 = Hdb1 And &B00001111
   Databytes = Lookup(temp1 , Anzdb)
   Return

Anzdb:
   Data 0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 16 , 0 , 0 , 0 , 0 , 0 , 0

' -----[ End of S.N.A.P. ]------------------------------------------------

Command:
Kann mir jemand sagen, wie ich das mit den Subs richtig hinbekomme?