Hi Encoder,
Have a look at this:
;the comms format is <;> header, single byte address, data then <CR> terminator
; the master (a PLC) is address 0
; it is RS-485 multidrop
; this is cut from an actual old application on a GP32
;init the SCI
mov #%00010010,SCBR ;9600 BAUD AT 7.3MHZ BUSS
mov #%01000000,SCC1 ;enable SCI
mov #%00101100,SCC2 ;SET SCC2 TO ENABLE SCI & REC INT
mov #%00000000,SCC3 ;set SCC3
;so it always receives, and puts the string in RECBUF and sets a bit when its got the complete string
;and when you want to send a response:
;you put it in TXBUF and do this:
BSET TXRXENA,PORTD ;enable transmitter
BSET 7,SCC2 ;enable transmit ints
************* SCI INTERRUPT SERVICE ROUTINE *********************************
SCITX_SVR LDA SCS1
BRSET 5,SERSTAT,SENTHEAD ;(INT MUST BE SCTE) CHECK IF HEADER SENT
BSET 5,SERSTAT
LDA #$3B ;SEMICOLON
STA SCDR ;SEND HEADER
BRA SCITRET
SENTHEAD BRSET 6,SERSTAT,SENDMESS ;CHECK IF ADDRESS SENT
BSET 6,SERSTAT
LDA #'0'
STA SCDR ;SEND ADDRESS
BRA SCITRET
SENDMESS LDX TXCNT ;GET TX'D CHAR COUNT
INC TXCNT
LDA TXBUF,X ;GET NEXT CHAR FROM TXBUF
STA SCDR ;SEND CHAR
CMP #CR ;CHECK IF CARRIAGE RETURN
BNE SCITRET ;KEEP GOING IF NOT CR
BCLR 7,SCC2 ;DISABLE TX INTERRUPTS
BCLR 5,SERSTAT
BCLR 6,SERSTAT
SCITC BRCLR 6,SCS1,SCITC ;WAIT FOR TRANSMISSION COMPLETE
BCLR TXRXENA,PORTD
CLR TXCNT ;RESET TX COUNTER
SCITRET RTI ;FINISHED TX
************************************************************************
SCIRX_SVR LDA SCS1 ;GET STATUS REG
AND #%00001110 ;CHECK FOR ERRORS, OR, NF, FE
BNE ERROR ;SET LED ON & EXIT
LDA SCDR ;GET RECIEVED CHAR
CMP #$3B ;CHECK FOR HEADER (SEMICOLON)
BNE NOTSEMI
BSET 1,SERSTAT ;set have header
BCLR 3,SERSTAT ;clear have address char
BCLR 4,SERSTAT ;clear my address
CLR RECCNT ;clear recieved char count
BRA SCIRET
NOTSEMI BRCLR 1,SERSTAT,SCIRET ;no header so bail
BRSET 3,SERSTAT,READMESS
BSET 3,SERSTAT
CMP ADDRESS
BNE SCIRET
BSET 4,SERSTAT ;SET MY ADDRESS BIT
BRA SCIRET
READMESS CMP #LF ;RECIEVED CHAR IS LF
BEQ SCIRET ;DON'T BUFFER IT
CMP #SPACE ;CHECK IF A SPACE
BEQ SCIRET ;BAIL IF IT IS
CMP #$08 ;Backspace?
BNE NOTBS ;bypass if not
TST RECCNT ;bypass if no chars
BEQ SCIRET
DEC RECCNT ;delete last char
BRA SCIRET ;and bailout
NOTBS LDX RECCNT ;GET CHAR COUNT IN X
STA RECBUF,X ;PUT CHAR IN BUF
CMP #CR ;CHECK IF CARRIAGE RETURN
BNE NOCR ;KEEP GOING IF NOT CR
BSET 0,SERSTAT ;SET LINE RECIEVED BIT
NOCR INCX ;INC X REG
STX RECCNT ;INC CHAR COUNT
CPX #RBUFSIZ ;CHECK ROOM LEFT IN BUF
BEQ RESETC ;ROLL OVER IF NO ROOM LEFT
BRA SCIRET ;END IF OK
ERROR BSET COMMERR,INTPORT ;TURN FAULT BIT ON
LDA SCDR ;READ RECIEVED CHAR TO CLEAR
RESETC CLR RECCNT ;RESET CHAR COUNT
SCIRET RTI ;LEAVE
Regards
Peg
Hello Encoder & Peg,
With respect to the sample code, a minor (but important) point - I notice that both ISRs are using indexed instructions to access the buffers, so CLRH instructions should be explicitly included. So the existing H-values would first need to be pushed to the stack, and restored on exit from the ISR.
For multi-drop RS485, the packet structure and handling might need to be a little more complex, for compatibility with half-duplex operation, and to ensure that only a single slave will respond to each command from the master. So, somewhere within the command packet the destination (slave) address would be required. For the master, a "receive window" timeout period would also be required so that slave polling operation could continue in the event that the slave does not respond.
Many multi-drop systems would also include error detection (checksum or CRC) within each packet, to allow for error detection and re-send of packets.
Regards,
Mac
Encoder wrote:... I need to transmitt bynary data and I have to change the format to be able to transmit any byte, including $0D, LF, SPACE etc..I think to add a leading byte which states the data length, so avoiding skipping or altering reserved characters in the middle of the message.
Another possibility would be to identify two different packet types, one containing (encoded) binary data, and the other containing ASCII string data. Here, you might use different ASCII control characters (not normally used within the string data), to delimit the packet. An example might be <SOH> for the start of the packet, and <ETX> for the end of the packet. So the packet structure might look something like: