Hi boroko,
Code:
Getbytes:
While RCIF = 1 ' clear the buffer
HSERIN 100,error,[Serialdata] ' Get serial
led2count = led2count + 1 ' Incr heartbeat
Wend
You're throwing away perfectly good data with that.
You need to process everything that comes in, even if it's not for this chips address.
And you don't need a Timeout in the HSERIN, because it's guaranteed to have a byte in the USART if it triggers an interrupt.
Well, I wrote this last night. I thought I'd get a chance to test/debug it. But today I've got 5 people coming at me from 4 different directions.
Makes me wonder what those 2 are doing together. 
Hopefully, what I was trying to say will show through, if it doesn't work.
Basically it's, make the Handler as fast as possible. Get in, do your thing, and get out.
No PAUSES, no HSEROUTS, nothing that will keep it from leaving the interrupt as fast as possible.
Anything that needs to take time, should be done in the main loop. Where it can be interrupted again..
Flags are used to trigger those "Main Loop" processes.
Hope it gives some direction ...
If nothing else, note the changes to the Getbytes: handler.
Code:
':::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
'Based on Hserin with Darrel Taylor's Instant Interrupts
':::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
' Program to echo incoming serial data.
' RX SYNC byte, if good: ADDRESS byte, if good: COMMAND
' MPASM, LabX-1 , PBP2.47, Using PIC 16F877A @ 4mHz, 9600 Baud
' Using Hardware USART and MAX232 to MCS Serial Communicator on PC
DEFINE OSC 4
DEFINE HSER_RCSTA 90h ' enable serial port,
define HSER_TXSTA 24h ' enable transmit,
define HSER_BAUD 9600 ' set baudrate to 9600
DEFINE HSER_CLOERR 1 ' automatic clear overrun error
TRISD = $00000000 'D to outputs for the LEDs
TRISC = %10000000 ' PORTC.7 is the RX input, PORTC.6 is the TX output
ADCON1 = %00001111 'Set up ADCON1 register no matter what yr doing!!!
':::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
INCLUDE "DT_INTS-14.bas" ' Base Interrupt System
INCLUDE "ReEnterPBP.bas" ' Include if using PBP interrupts
':::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
' Variable definition
':::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
led0 var PORTD.0
led1 var PORTD.1
led2 var PORTD.2
led7 var PORTD.7
ERROR_LED VAR led7 ' rename the LED's
LATE_LED VAR led2
HEART_LED VAR led0
LEDonDELAY CON 4
CmdBuf var byte 'command for the pwm or acknowledge
SerialData var byte '
ERRORtime var byte
LATEtime var byte
HEARTtime VAR BYTE
state VAR BYTE
Sync VAR state.0 ' Sync byte rcvd
ForMe VAR state.1 ' Packet is for this device
CmdRcvd VAR state.2 ' Command has been rcvd
ERROR VAR state.3 ' Sync rcvd out of order
LATE VAR state.4 ' command rcvd before last one was processed
SyncByte CON "U"
ID CON "A"
state = 0
':::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
ASM
INT_LIST macro ; IntSource, Label, Type, ResetFlag?
INT_Handler RX_INT, _Getbytes, PBP, no
INT_Handler TMR0_INT, _TMR0handler, PBP, YES
endm
INT_CREATE ; Creates the interrupt processor
ENDASM
@ INT_ENABLE RX_INT ; enable RX_INT interrupts
@ INT_ENABLE TMR0_INT ; enable TMR0_INT interrupts 65.5ms
':::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
hserout ["start"] 'splash screen to verify comm
HSEROUT [13,10] ' CR to start new line on terminal program
Mainloop:
IF CmdRcvd THEN GOSUB ProcessCMD ' Process any incomming data
IF ERROR THEN ' if there's been an Error
HIGH ERROR_LED ' Turn ON ERROR LED
ERROR = 0 ' reset the error flag
ERRORtime = LEDonDELAY ' start countdown till LED-OFF
HSEROUT ["Error",13,10]
ENDIF
IF LATE THEN ' if command took too long
HIGH LATE_LED ' Turn ON LATE LED
LATE = 0 ' reset the LATE flag
LATEtime = LEDonDELAY ' start countdown till LED-OFF
HSEROUT ["Late",13,10]
ENDIF
GOTO Mainloop
'*********** Process received command **************************************
ProcessCMD:
hserout ["Cmd: ",CmdBuf, " [", _ ' send Command and CR/LF
DEC CmdBuf,"]",13,10]
CmdRcvd = 0 ' indicate CMD has been processed
RETURN
'*********** 'ISR for TMR0_INT interrupt ***********************************
TMR0handler:
IF ERRORtime > 0 THEN ' if the Error LED is ON
ERRORtime = ERRORtime - 1 ' decrement the count
IF ERRORtime = 0 THEN ' when it reaches 0
LOW ERROR_LED ' turn the Error LED OFF
ENDIF
ENDIF
IF LATEtime > 0 THEN ' if the LATE LED is ON
LATEtime = LATEtime - 1 ' decrement the count
IF LATEtime = 0 THEN ' when it reaches 0
LOW LATE_LED ' turn the LATE LED OFF
ENDIF
ENDIF
HEARTtime = HEARTtime + 1 ' Toggle heartbeat ~.5sec
IF HEARTtime = 7 THEN
HEARTtime = 0
TOGGLE HEART_LED
ENDIF
@ INT_RETURN
'*********** 'ISR for RX_INT interrupt *************************************
Getbytes:
HSERIN [Serialdata] ' Get the serial data
IF Serialdata = SyncByte THEN ' if it's a Sync byte,
IF Sync THEN ERROR = 1 ' last command was corrupted
Sync = 1 ' indicate Sync was rcvd
ForMe = 0 ' ID has not been rcvd
ELSE
IF Sync THEN
IF !ForME THEN ' if we haven't rcvd the ID
IF Serialdata = ID THEN ' and this byte matches the ID
ForMe = 1 ' indicate ID rcvd
ELSE
Sync = 0 ' Not my packet
ForMe = 0 ' reset receive state
ENDIF ' and wait for next Sync
ELSE
CmdBuf = serialdata ' store the command
IF CmdRcvd THEN LATE = 1 ' last command not finished
CmdRcvd = 1 ' indicate a command was rcvd
Sync = 0 ' reset receive state
ForMe = 0
ENDIF
ENDIF
ENDIF
@ INT_RETURN
Bookmarks