>>
You just learn a little slower after 50.
Oh No! I better hurry up and learn more, I've only got 3 years left.
>>
... with only 4 months of experience at this ...
Well, for only 4 months, you're doing pretty good.
>>
... how long have you been doing this? anyway
PicBasic Pro - about 5 years
Programming - Umm, one month after the first TRS-80 hit the market, I guess that makes it about oh 28 years.
I know DT_INTS looks intimidating at the begining, but it's really not that bad, and you don't need to learn assembly language to use it. But I can understand why you might not want to try it out. The biggest obstacle is that you have to be using MPASM.
So whenever you get around to DT_INTS, you can come back to this thread and try out this program.
It's your backpack program modified for Instant Interrupts.
I've highlighted most of the changes (red is added, blue is removed).
Tested it on a 16F877A
Code:
;---- Config settings for MPASM ----------------------------------------------
@ __config _HS_OSC & _WDT_OFF & _PWRTE_ON & _MCLRE_ON & _LVP_OFF & _CP_OFF
trisb = %00000010
trisA = %11110011
;include "modedefs.bas"
;----Added by DT--------------------------------------------------------------
INCLUDE "DT_INTS-14.bas"
INCLUDE "ReEnterPBP.bas" ; Include if using PBP interrupts
ASM
INT_LIST macro ; IntSource, Label, Type, ResetFlag?
INT_Handler RX_INT, _serialin, PBP, no
endm
INT_CREATE ; Creates the interrupt processor
ENDASM
@ INT_ENABLE RX_INT ; enable external (INT) interrupts
;-----------------------------------------------------------------------------
' Define LCD registers and bits
Define LCD_DREG PORTB
Define LCD_DBIT 4
Define LCD_RSREG PORTA
Define LCD_RSBIT 0
Define LCD_EREG PORTA
Define LCD_EBIT 1
DEFINE LCD_LINES 4 'Define using a 2 line LCD
DEFINE LCD_COMMANDUS 2000 'Define delay time between sending LCD commands
DEFINE LCD_DATAUS 50 'Define delay time between data sent.
DEFINE OSC 20
DEFINE HSER_RCSTA 90h ' Enable serial port & continuous receive
DEFINE HSER_TXSTA 20h ' Enable transmit, BRGH = 0
DEFINE HSER_SPBRG 32 ' FOR 20MHZ 129 = 2400, 32=9600,25 @ 4 for 2400
DEFINE HSER_CLROERR 1 ' Clear overflow automatically
RCIF VAR PIR1.5 ' Receive interrupt flag (1=full , 0=empty)
TXIF VAR PIR1.4 ' Transmit interrupt flag (1=empty, 0=full)
LED VAR PORTA.4
OERR VAR RCSTA.1 ' Alias OERR (USART Overrun Error Flag)
CREN VAR RCSTA.4 ' Alias CREN (USART Continuous Receive Enable)
buffer_size CON 64 ' Sets the size of the ring buffer, set up from 32
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
index_in = 0
index_out = 0
i = 0
col = 1
'RxData var byte
CMCON = 7 ' PORTA is digital
Pause 100 ' Wait for LCD to startup
high PortA.2 ' power for backlight
low PortA.3 ' backlight ground
;INTCON = %11000000 ' Enable interrupts
;ON INTERRUPT GoTo serialin ' Declare interrupt handler routine
;PIE1.5 = 1 ' Enable interrupt on USART
pause 1500
lcdout $FE,1
lcdout $FE,2
LCDOUT "Your Text Goes Here"
PAUSE 2000
' * * * * * * * * * * * * * Main program starts here - blink an LED at 1Hz
' I removed some code here, it seems to require what's left
loop:
For i = 0 to 10 ' Delay for .02 seconds (10*2mS)
Pause 2 ' Use a short pause within a loop
Next i ' instead of one long pause
For i = 0 to 10 ' Delay for .02 seconds (10*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 loop ' loop if nothing in buffer
GoSub getbuf ' Get a character from buffer
LCDOut bufchar ' Send the character to LCD
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
@ INT_DISABLE RX_INT
index_out = (index_out + 1) ' Increment index_out pointer (0 to 63)
' Reset pointer if outside of buffer
IF index_out > (buffer_size-1) Then index_out = 0
bufchar = buffer[index_out] ' Read buffer location
@ INT_ENABLE RX_INT
Return
error: ' Display error message if buffer has overrun
IF errflag.1 Then ' Determine the error
LCDOut $FE,$c0,"Clearing Display Buffer" ' Display buffer error on
' line-2 and 3 Buff overrun
Else
LCDOut $FE,$D4,"USART Overrun" ' Display usart error on line-4
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 ' $14 = 20 DEC.
errflag = 0 ' Reset the error flag
CREN = 0 ' Disable continuous receive to clear overrun flag
CREN = 1 ' Enable continuous receive
GoTo display ' Errors cleared, time to work.
' * * * * * * * * * * * * * * * 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
@ INT_RETURN ; 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
@ INT_RETURN ; Return to program
End
Hope you can use it some day,
Bookmarks