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