Charles is right. You are not looking at the serial port while your code is sending MessageA thrice and then pausing for 1000 ms. During that time, whatever comes in is bound to overflow the receive register. Cloerr will mitigate the problem to an extent, but imagine, you just received your "d" and are waiting for the decimal values for B0, B1 or B2. During that time if the input packet has already finished, you're in trouble. That's because the DEC modifier parses numbers only. If it doesn't find a number, either your number read is wrong or it will end up waiting indefinitely on the "d".
Ideal solution, put in an interrupt routine to capture the incoming serial characters. Catch them to a circular buffer and read that buffer often. How to do it? This is how I would do it....
This is just a framework and is incomplete. Use it at your own risk.Code:' These variables are used to save the machine state on interrupt wsave var byte $20 SYSTEM ' location for W if in bank0 wsave1 var byte $A0 SYSTEM ' location for W if in bank1 wsave2 var byte $120 SYSTEM ' location for W if in bank2 wsave3 var byte $1A0 SYSTEM ' location for W if in bank3 ssave var byte BANK0 SYSTEM ' location for STATUS register psave var byte BANK0 SYSTEM ' location for PCLATH register fsave var byte BANK0 SYSTEM ' location for FSR register intR0 var byte BANK0 SYSTEM ' interrupt temporary variables intR1 var byte BANK0 SYSTEM ' Receive buffer RxBuf var byte[16] ' buffer holding received chars WrPtr var byte ' write index RdPtr var byte ' write index ' define the interrupt handler define INTHAND _IntHandler goto OverInterrupt IntHandler: '******************************************************************************* ' Interrupts can be from a number of sources. See INTCON p25 ' We use the following ' RBIF - interrupt on RB change ' T0IF - Timer0 overflow interrupt IntHandler: asm ; identify the interrupt source movf FSR,w movwf fsave ; save the fsr btfss PIE1,RCIE ; if enabled and goto EndInt btfss PIR1, RCIF ; receive interrupt? goto EndInt RxISR movlw 6 andwf RCSTA,w ;FERR(4) + OERR(2) btfss STATUS,Z ;not set bcf RCSTA,CREN ;clear errors bsf RCSTA,CREN ;by putting CREN=0,1 ; movf _WrPtr, W addlw low (_RxBuf) movwf FSR movf RCREG,w movwf INDF ;RxBuf[WrPtr]=RCREG ; incf _WrPtr movlw 0fh andwf _WrPtr EndInt movf fsave,w ;restore the FSR movwf FSR movf psave,w ;restore PCH movwf PCLATH swapf ssave, W ;restore STATUS movwf STATUS swapf wsave, F swapf wsave, W ;restore W retfie ENDASM ' initialize the serial buffer Ser_Init: RCSTA=$90 ' Enable serial port & continuous receive TXSTA=$20 ' Enable transmit, BRGH = 0 SPBRG=25 ' 2400 Baud @ 4MHz, 0.0% RdPtr=0 WrPtr=0 return ' read a serial character Ser_Getc: while RdPtr=WrPtr:wend gr[0]=RxBuf[RdPtr] RdPtr=RdPtr+1 RdPtr=RdPtr & $0f return ' read the value of a hex digit to gr[0] Ser_GetHex: gosub Ser_Getc if gr[0]>"9"then gr[0]=gr[0]-7 gr[0]=gr[0]-"0" return ' read the value of 2 hex digits to gr[0] Ser_GetHex2: gosub Ser_GetHex gr[1]=gr[0]<<4 gosub Ser_GetHex gr[0]=gr[1]+gr[0] return ProcessRX: while RdPtr <> WrPtr gosub Ser_GetC if gr[0]="d" then ProcRX10 ' Proceed only after we get the "d" wend return ProcRX10: ' process the data here
Jerson




Bookmarks