How about something like this?
Code:
' ** // PIC16F877, 20MHz crystal, MCS+ loader
' ** // Interrupt driven serial receive
' ** // Buffers up to 80 characters using the hardware
' ** // USART. Buffering ends when the EOM "~" character
' ** // is received.
' ** // Includes auto over-run reset + RCIF bit polling
' ** // for new serial characters
define LOADER_USED 1
define OSC 20
define HSER_BAUD 19200 ' Set data rate
DEFINE HSER_CLROERR 1 ' Automatically clear over-run errors
DEFINE HSER_RCSTA 90h ' Enable USART receive
DEFINE HSER_TXSTA 24h ' TXSTA=%00100100. TX enable, BRGH=1 for high-speed
' TXSTA=%00100000. TX enable, BRGH=0 for low-speed
GP VAR BYTE ' GP variable
BytesIn var byte[80] ' Up to 80 bytes
ByteCnt var byte ' Indicates number of bytes in buffer
X VAR BYTE ' GP var
EOM CON "~" ' "End Of Message" marker
OERR VAR RCSTA.1 ' Alias USART over-run bit
CREN VAR RCSTA.4 ' Alias USART continuous receive enable bit
RCIF VAR PIR1.5 ' Alias USART received character interrupr flag bit
' ** // Zero vars & A/D off
ByteCnt = 0 ' Zero counter
ADCON1 = 7 ' A/D off, all digital
' ** // Setup serial interrupts
INTCON = %11000000 ' Enable interrupts
PIE1.5 = 1 ' Enable interrupt on USART
On Interrupt Goto Main
GOTO Doodle
Disable
Main:
WHILE RCIF ' If RCIF=1 there's a new character in RCREG
BytesIn[ByteCnt]=RCREG ' Yes. Then store it in array
If BytesIn[ByteCnt]=EOM then OutMsg ' Display on receipt of terminating char
ByteCnt=ByteCnt+1 ' Increment array index pointer
WEND ' Exit only when RCREG is clear
RESUME ' Return to normal operation prior to interrupt
ENABLE
OutMsg: ' Note: Interrupts are still disabled here
HSEROUT [13,10,dec ByteCnt," Bytes Rcvd",13,10]
HSEROUT [str BytesIn\ByteCnt,13,10]
FOR GP=0 to ByteCnt ' Clear array bytes 0 to ByteCnt
BytesIn[GP]=0 '
NEXT '
ByteCnt=0 ' Reset index pointer back to first element
WHILE RCIF ' Trash any left over characters in RCREG buffer
GP=RCREG ' after EOM has been received
WEND
GOTO Main ' RCIF is clear, so return
Doodle: ' Waste time here waiting for serial interrupt
HIGH PORTB.0
FOR X = 0 TO 250
PAUSEUS 20 ' Do not use long pauses. It slows down interrupt
NEXT X ' processing, and requires a slower data rate to work
LOW PORTB.0 ' with on interrupt
FOR X = 0 TO 250
PAUSEUS 20
NEXT X
GOTO Doodle
end
If you have a terminator on the end of your data packets, this makes the whole process pretty simple.
If you just need to PIC to tell the PC to stop sending data, connect the PIC flow control pin to the PC CTS pin.
Bookmarks