Rage_Empire
08.10.2005, 17:24
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.
' 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?
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.
' 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?