>> 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 16F877AHope you can use it some day,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






Bookmarks