Well I just learned a few things about PBP USART defines.
1. If you use PBP USART defines like DEFINE HSER_TXSTA 24h, but do "not" use HSEROUT or HSERIN somewhere in the program, these defines don't configure the USART like one might assume.
In this case you need to write directly to USART registers to setup everything.
TXSTA = $24 ' Enable TXEN and BRGH=1
RCSTA = $90 ' SPEN & CREN = 1
SPBRG = 129 ' SPBRG val for 19,200bps
2. This also goes for DEFINE HSER_CLOERR 1. If you don't also use HSERIN or HSEROUT, then OERR never gets "automatically" cleared on over-run, and of course, it goes like splat when you shoot more than 2 characters at the USART before emptying RCREG.
This program below has been tested, and it definitely does generate a USART interrupt even with a baud rate missmatch.
Notes:
If you send 1 character, it displays that character.
If you send 2 characters, it displays the 2nd received.
If you send 3 or > characters, it still dispays only the 2nd character received because anything over 2 bytes shot at the USART before RCREG is cleared isn't transferred into RCREG from RSR.
This was tested with a PC sending serial data, but it should work the same with anything sending asynchronous serial data.
Code:
DEFINE OSC 40 ' _HSPLL_OSC_1H & _HS_OSC_1H
' // Setup for dev board LCD pinout
DEFINE LCD_DREG PORTB ' LCD I/O port
DEFINE LCD_DBIT 4 ' 4-bit data from RB4 to RB7
DEFINE LCD_RSREG PORTB ' Register select port
DEFINE LCD_RSBIT 2 ' Register select pin
DEFINE LCD_EREG PORTB ' Enable port
DEFINE LCD_EBIT 3 ' Enable pin
DEFINE LCD_BITS 4 ' 4-bit data bus
DEFINE LCD_LINES 2 ' 2-line LCD
DEFINE LCD_COMANDUS 2000 ' LCD command delay
DEFINE LCD_DATAUS 50 ' LCD data delay
' // Set USART parameters
TXSTA = $24 ' Enable TXEN and BRGH=1
RCSTA = $90 ' SPEN & CREN = 1
SPBRG = 129 ' SPBRG val for 19,200bps @40MHz
' // Set USART bit aliases
SYMBOL RCIF = PIR1.5 ' Received character int flag
SYMBOL OERR = RCSTA.1 ' Over-run error bit
SYMBOL CREN = RCSTA.4 ' Continuous receive enable/disable bit
' // Setup A/D, variables, etc,,
ADCON1 = %00000111 ' A/D off, all digital
X VAR BYTE ' Loop var
Teller VAR BYTE ' Holds char for display
Teller = "0" ' Start with ASCII 0
' // LCD init time / clear, home cursor
PAUSE 1000 ' LCD power-up / init time
lcdout $FE,1 ' Clear LCD
' // Setup interrupts
INTCON = %11000000 ' Enable global / peripheral interrupt
PIE1.5 = 1 ' USART receive interrupt enabled
on interrupt GoTo handle ' Point to int handler
Main:
lcdout $FE,1,Teller ' Clear LCD / diaplay last char
FOR X = 1 TO 50 ' Loop for 1 second in 20mS
PAUSE 20 ' intervals
NEXT X
goto Main
Disable ' Disable interrupts while in interrupt handler
Handle:
IF OERR THEN ' Clear over-runs if OERR set
CREN = 0 ' Disable USART receive
CREN = 1 ' Re-enable USART receive
ENDIF
Teller = RCREG ' Read RCREG buffer twice to
Teller = RCREG ' clear RCIF interrupt flag bit
Resume
Enable
end
Bookmarks