ME Labs, Inc.
719-520-5323
 
Home:
  Developer Resources:

Programming Clues
    Sample Programs
   
    PICBASIC PRO™
Compiler Manual
    PICBASIC™ Compiler
Manual
    Serin2/Serout2 Modes
    ASCII Character Set
    Number Conversion
    Floating Point
Routines
    PBP Debug Monitor
    Articles and Tutorials

Hardware Clues
    Parts / Vendor List
    PICPROTO™ Boards
    LAB-X1 Docs
    LAB-X2 Docs
    LAB-X20 Docs
    LAB-X3 Docs
    LAB-X4 Docs
    LAB-XUSB Docs
    LAB-XT Docs
     
 

ME Labs, Inc. | 1-719-520-5323 | Example Program - SERBUFX.pbp

PICBASIC PRO program to demonstrate an interrupt-driven input buffer for Hserin using On Interrupt. Pin definitions compatible with LAB-X1 and PIC16F877.
' Name        : SERBUFX.pbp
' Compiler    : PICBASIC PRO Compiler 2.6
' Assembler   : PM or MPASM
' Target PIC  : 40-pin 16F877, 877A or similar
' Hardware    : LAB-X1 Experimenter Board
' Oscillator  : 4MHz external crystal
' Keywords    : HSERIN, ON INTERRUPT, LCDOUT
' Description : PICBASIC PRO program to demonstrate an interrupt-driven
' input buffer for Hserin using On Interrupt. Pin definitions compatible
' with LAB-X1 and PIC16F877.
'

' Defines for LCD and USART
Define HSER_RCSTA 90h
Define HSER_TXSTA 24h
Define HSER_BAUD 9600

Define LCD_DREG  PORTD
Define LCD_DBIT  4
Define LCD_RSREG PORTE
Define LCD_RSBIT 0
Define LCD_EREG  PORTE
Define LCD_EBIT  1

RCIF  VAR  PIR1.5       ' Alias RCIF (USART Receive Interrupt Flag)
OERR  VAR  RCSTA.1      ' Alias OERR (USART Overrun Error Flag)
CREN  VAR  RCSTA.4      ' Alias CREN (USART Continuous Receive Enable)
LED   VAR  PORTD.0      ' Alias LED to PORTD.0

buffer_size  CON  32    ' Sets the size of the ring buffer
buffer       VAR  BYTE[buffer_size] ' Array variable for holding received characters
index_in     VAR  BYTE  ' Pointer - next empty location in buffer
index_out    VAR  BYTE  ' Pointer - location of oldest character in buffer
bufchar      VAR  BYTE  ' Stores the character retrieved from the buffer
i            VAR  BYTE  ' loop counter 
col          VAR  BYTE  ' Stores location on LCD for text wrapping
errflag      VAR  BYTE  ' Holds error flags

   ADCON1 = 7           ' Set PortA and E to digital operation

   ' Initialize variables
   index_in = 0
   index_out = 0
   i = 0
   col = 1

   Low PORTE.2     ' LCD R/W line low (W)
   Pause 100       ' Wait for LCD to start

   LCDOut $fe,1    ' Clear LCD

   INTCON = %11000000         ' Enable interrupts
   ON INTERRUPT GoTo serialin ' Declare interrupt handler routine
   PIE1.5 = 1                 ' Enable interrupt on USART

' Main program starts here - blink an LED at 1Hz
mainloop:
   High LED          ' Turn on LED connected to PORTD.0
   For i = 0 to 250  ' Delay for .5 seconds (250*2mS)
     Pause 2         ' Use a short pause within a loop
   Next i            ' instead of one long pause

   Low LED           ' Turn off LED connected to PORTD.0
   For i = 0 to 250  ' Delay for .5 seconds (250*2mS)
     Pause 2         ' Use a short pause within a loop
   Next i            ' instead of one long pause

display:             ' dump the buffer to the LCD
   IF errflag Then error ' Handle error 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 line-2 of LCD
      LCDOut $FE,2   ' Tell LCD to return home
   EndIF
   GoTo display      ' Check for more characters in buffer

' Subroutines
Disable              ' Don't check for interrupts in this section

getbuf:              ' move the next character in buffer to bufchar
   index_out = (index_out + 1) ' Increment index_out pointer (0 to 63)
   IF index_out > (buffer_size-1) Then index_out = 0 ' Reset pointer if outside of buffer
   bufchar = buffer[index_out] ' Read buffer location
   Return

error:               ' Display error message if buffer has overrun
   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  ' Move the cursor right to the right column
   Next i
        
   errflag = 0       ' Reset the error flag
   CREN = 0          ' Disable continuous receive to clear overrun flag
   CREN = 1          ' Enable continuous receive
   GoTo display      ' Carry on      
        
' Interrupt handler
serialin:            ' Buffer the character received
   IF OERR Then usart_error    ' Check for USART errors
   index_in = (index_in + 1)   ' Increment index_in pointer (0 to 63)
   IF index_in > (buffer_size-1) Then index_in = 0 ' Reset pointer if outside of buffer
   IF index_in = index_out Then buffer_error       ' Check for buffer overrun
   HSerin [buffer[index_in]]   ' Read USART and store character to next empty location
   IF RCIF Then serialin       ' Check for another character while we're here   
   Resume                      ' Return to program

buffer_error:
   errflag.1 = 1           ' Set the error flag for software

' Move pointer back to avoid corrupting the buffer. MIN insures that it ends up within the buffer.      
   index_in = (index_in - 1) MIN (buffer_size - 1) 
   HSerin [buffer[index_in]] ' Overwrite the last character stored (resets the interrupt flag)

usart_error:
   errflag.0 = 1           ' Set the error flag for hardware
   Resume                  ' Return to program

   End

           

Download the program file.