|
ME Labs, Inc. 719-520-5323 |
|
|
|
ME Labs, Inc. | 1-719-520-5323 | Example Program - SERBUFAX.pbpPICBASIC PRO program to demonstrate an interrupt-driven input buffer for hardware USART receive using Assembly language interrupt. Pin definitions compatible with LAB-X1 and PIC16F887' Name : SERBUFAX.pbp
' Compiler : PICBASIC PRO Compiler 2.60
' Assembler : PM or MPASM
' Target PIC : 40-pin 16F887
' Hardware : LAB-X1 Experimenter Board
' Oscillator : 4MHz external crystal
' Keywords : ASSEMBLY INTERRUPTS, LCDOUT
' Description : PICBASIC PRO program to demonstrate an interrupt-driven
' input buffer for hardware USART receive using Assembly language interrupt.
' Pin definitions compatible with LAB-X1 and PIC16F887
'
' Defines for LCD
Define LCD_DREG PORTD
Define LCD_DBIT 4
Define LCD_RSREG PORTE
Define LCD_RSBIT 0
Define LCD_EREG PORTE
Define LCD_EBIT 1
' Define interrupt handler
Define INTHAND myint
' Configure internal registers
ANSEL = %00000000 ' Make AN0-AN7 digital
ANSELH= %00000000 ' Make AN8-AN13 digital
RCSTA = $90 ' Enable USART receive
TXSTA = $24 ' Set USART parameters
SPBRG = 25 ' Set baud rate to 9600
LED VAR PORTD.0 ' Alias LED to PORTD.0
CREN VAR RCSTA.4 ' Alias CREN (Serial receive enable)
'Variables for saving state in interrupt handler
wsave VAR BYTE $70 system ' Saves W
ssave VAR BYTE bank0 system ' Saves STATUS
psave VAR BYTE bank0 system ' Saves PCLATH
fsave VAR BYTE bank0 system ' Saves FSR
buffer_size CON 32 ' Sets size of ring buffer
buffer VAR BYTE[buffer_size] ' Array variable for holding received characters
index_in VAR BYTE bank0 ' Pointer - next empty location in buffer
index_out VAR BYTE bank0 ' Pointer - location of oldest character in buffer
errflag VAR BYTE bank0 ' Error flag
bufchar VAR BYTE ' Stores the character retrieved from the buffer
col VAR BYTE ' Stores location on LCD for text wrapping
i VAR BYTE ' Loop counter
GoTo start ' Skip around interrupt handler
' Assembly language INTERRUPT handler
Asm
myint
; Uncomment the following if the device has less than 2k of code space
;movwf wsave ; Save W
;swapf STATUS,W ; Swap STATUS to W (swap avoids changing STATUS)
;clrf STATUS ; Clear STATUS
;movwf ssave ; Save swapped STATUS
;movf PCLATH,W ; Move PCLATH to W
;movwf psave ; Save PCLATH
; Save the FSR value for later
movf FSR,W ; Move FSR to W
movwf fsave ; Save FSR
; Check for hardware overrun error
btfsc RCSTA,OERR ; Check for usart overrun
GoTo usart_err ; jump to assembly error routine
; Find in which bank the compiler put buffer, and set IRP
IF (_buffer > 0FFh) ; Find the bank where buffer is located
bsf STATUS,IRP ; If bank 2 or 3 set IRP
Else
bcf STATUS,IRP ; If bank 0 or 1 clear IRP
EndIF
; Test for buffer overrun
incf _index_in,W ; Increment index_in to W
subwf _index_out,W ; Subtract indexes to test for buffer overrun
btfsc STATUS,Z ; check for zero (index_in = index_out)
GoTo buffer_err ; jump to error routine if zero
; Increment the index_in pointer and reset it if it's outside the ring buffer
incf _index_in,F ; Increment index_in to index_in
movf _index_in,W ; Move new index_in to W
sublw _buffer_size-1; Subtract index_in from buffer_size-1
btfss STATUS, C ; If index_in => buffer_size
clrf _index_in ; Clear index_in
; Set FSR with the location of the next empty location in buffer
movlw Low _buffer ; Get the location of buffer[0]
addwf _index_in,W ; Add index_in to point to next empty slot
movwf FSR ; Store pointer in FSR
; Read and store the character from the USART
movf RCREG,W ; Read the received character
movwf INDF ; Put the received character in FSR location
; Restore FSR, PCLATH, STATUS and W registers
finished
movf fsave,W ; retrieve FSR value
movwf FSR ; Restore it to FSR
movf psave,W ; Retrieve PCLATH value
movwf PCLATH ; Restore it to PCLATH
swapf ssave,W ; Retrieve the swapped STATUS value (swap to avoid changing STATUS)
movwf STATUS ; Restore it to STATUS
swapf wsave,F ; Swap the stored W value
swapf wsave,W ; Restore it to W (swap to avoid changing STATUS)
retfie ; Return from the interrupt
; Error routines
buffer_err ; Jump here on buffer error
bsf _errflag,1 ; Set the buffer flag
usart_err ; Jump here on USART error
bsf _errflag,0 ; Set the USART flag
movf RCREG, W ; Trash the received character
GoTo finished ; Restore state and return to program
EndAsm
start: ' Initialize variables
index_in = 0
index_out = 0
col = 1
errflag = 0
INTCON = %11000000 ' Enable interrupts
PIE1.5 = 1 ' Enable interrupt on USART
Low PORTE.2 ' LCD R/W line low (W)
Pause 100 ' Wait for LCD to start
LCDOut $fe,1 ' Clear LCD
' Main program starts here - blink an LED at 1Hz
mainloop:
High LED ' Turn on LED connected to PORTD.0
Pause 500 ' Pause 500mS
Low LED ' Turn off LED connected to PORTD.0
Pause 500 ' Pause 500mS
display: ' dump the buffer to the LCD
IF errflag Then error ' Goto error routine if needed
IF index_in = index_out Then mainloop ' loop if nothing in buffer
GoSub getbuf ' Get a character from buffer
LCDOut bufchar ' Send the character to LCD
col = col + 1 ' Increment LCD location
IF col > 20 Then ' Check for end of line
col = 1 ' Reset LCD location
LCDOut $fe,$c0,REP " "\20 ' Clear any error on line-2 of LCD
LCDOut $FE,2 ' Tell LCD to return home
EndIF
GoTo display ' Check for more characters in buffer
' Subroutines
' Get a character from the buffer
getbuf: ' Move the next character in buffer to bufchar
intcon = 0 ' Disable interrupts while reading buffer
index_out = index_out + 1 ' Increment index_out pointer (0 to 63)
IF index_out => buffer_size Then index_out = 0 ' Reset pointer if outside buffer
bufchar = buffer[index_out] ' Read buffer location(index_out)
INTCON = %11000000 ' Enable interrupts
Return
' Display an error
error: ' Display error message
INTCON = 0 ' Disable interrupts while in the error routine
IF errflag.1 Then ' Determine the error
LCDOut $FE,$c0,"Buffer Overrun" ' Display buffer error on line-2
Else
LCDOut $FE,$c0,"USART Overrun" ' Display usart error on line_2
EndIF
LCDOut $fe,2 ' Send the LCD cursor back to line-1 home
For i = 2 TO col ' Loop for each column beyond 1
LCDOut $fe,$14 ' Put the cursor back where it was
Next i
errflag = 0 ' Reset the error flag
CREN = 0 ' Disable continuous receive to clear hardware error
CREN = 1 ' Enable continuous receive
INTCON = %11000000 ' Enable interrupts
GoTo display ' Carry on
End
Download the program file. |
|
Copyright 2022 ME Labs, Inc. PO Box 8250 Asheville NC 28814 (719) 520-5323 (719) 520-1867 fax email: support@melabs.com |
|