Thank you all for your input on my post. As was said by fanie- you have to think like the pic when working with interrupts, which is what I have always done with my assembler but now its more difficult without digging into the generated code to see exactly how the compiler handles things. Making the jump to Proton kind of got me thinking about some of the issues with interrupts and how I may need to deal with them with Proton. That got me to going “hmmm” and digging around the forum on the issue of interrupts. I saw a lot of posts on the subject and realized that these little issues I had to deal with in the assembler world might be things that weren’t so obvious. So I made the post hoping that some may find the information useful.
I am posting my snippet of code for the serial buffer here. It’s the Protonized version of how I’ve always done it in assembler. I apologize if this is not the proper way to do this or I mess up the posting of the code. This is the first and only forum I am on so I still have lots to learn about the correct way to do things. Hope folks find it useful. Many of you will probably notice my lack of efficient Proton coding which comes from my thinking in assembler all these years and this was (is) my first Proton project. That will improve with time as I get more comfortable with how the compiler handles things (learning what I can get away with).
Code:
;Example of handeling interrupts in basic and a serial port receive buffer.
On_Hardware_Interrupt intstrt ;goto intstrt if interrupt
;inpterupt routine variables
Dim itmp As Byte ;temp use
Dim icnt As Byte
;rs232 rec buffer variables
Symbol blmt=10 ;set buffer size to 10 (0-9)
Dim rbuf[blmt] As Byte ;set up receive buffer
Dim ipnt As Byte ;chr input pointer
Dim opnt As Byte ;chr output pointer
;system controls
Symbol gie=INTCON.7 ;interupt enable
Symbol tmr1if=PIR1.0 ;timer 1 rollover flag
Symbol rcif=PIR1.5 ;receive buffer full flag
Symbol txif=PIR1.4 ;transmit buffer empty flag
Symbol rcie=PIE1.5 ;rs232 rec int enable
Symbol spen=RCSTA.7 ;serial port enable
Symbol cren=RCSTA.4 ;async rec enable
Symbol ferr=RCSTA.2 ;framing error flag
Symbol oerr=RCSTA.1 ;overrun error flag
;*******************************************************************************
; interupt routines
;*******************************************************************************
GoTo init ;get around the interrupr handler
High_Int_Sub_Start
intstrt:
Context Save ;this is a small price to pay for being
;sure that Proton system variables aren't
;messed up by Proton funtions in the
;interrupt loop. This example doesn't
;really use higher level commands but
;there are other higher level things in
;the actual program that do.
intchk: If rcif=1 Then recin ;serial input interrupt
If tmr1if=1 Then tmrcnt ;timer1 rollover interrupt
GoTo intend
;Test interrupt timer/counter- sets updf for main to see new data in icnt.
;I used this as an initial test of how Proton would handle interrupts (keep in
;mind the program this is from is my very first project with proton).
tmrcnt: Inc icnt
updf=1
tmr1if=0
GoTo intchk
;recin- gets characters from async port and saves it in ring buffer so they can
;be processed in the main program loop when time allows. If the buffer overflows
;the last character is discarded. If there is an internal overrun error the port
;is reset and the character is discarded. If there is a framing error the
;chr is also discarded.
recin: itmp=RCREG ;get chr
If oerr=1 Then ;if overrun error
cren=0 ;reset port
cren=1
GoTo rcend ;discard chr
End If
If ferr=1 Then rcend ;if framing error discard chr
Inc ipnt ;select next pos in buffer
If ipnt=blmt Then Clear ipnt ;if rollover reset to start
If ipnt=opnt Then ;if buffer is full
Dec ipnt ;reduce ipnt by 1
If ipnt=255 Then ipnt=blmt-1
GoTo rcend ;discard chr
End If
rbuf[ipnt]= itmp ;put chr in buffer
rcend: GoTo intchk ;make sure no more interrupts
;to process
intend: Context Restore
High_Int_Sub_End
init: ;basic initialization here
;******************************************************************************
; Main program loop
;******************************************************************************
timdly: If tmr1if=1 Then GoTo process ;this is how I actually have my time reference
;now and don't use the interrupt timer function (its commented out in the code).
;I left it in the above routine to show how I process multiple interrupts.
;dataio- gets data from the rs232 buffur and processes it.
;commands
;O- turns unit on (takes out of standby)
;F- turns unit off (puts into standby)
;R- reset current alarms (does not affect maint alarms)
;D- send units data
dataio: If ipnt=opnt Then timdly ;exit if no chr in buffer
Inc opnt ;select next chr
If opnt=blmt Then Clear opnt ;rollover adjust
dta=rbuf[opnt] ;get chr
If dta="O" Then swtm.0=1 ;set run switch if on rec
If dta="F" Then swtm.1=1 ;set stop switch if off rec
If dta="R" Then swtm.2=1 ;set reset switch if reset rec
If dta="D" Then GoSub sndsys ;send system data
;!!! for testing
;GoSub chrout ;echo character
;If dta=13 Then
; dta=10
; GoSub chrout ;I have since found that hserout works
;EndIf ;well and I didn't need my chrout sub.
GoTo timdly
process: ;timed (.25sec) system data processing, controls, displays, etc.
tmr1if=0
;
;
;
GoTo timdly