mmm interesting... it's different from what i already heard somewhere. I should test it one day.
Usually my interrupt handler are just short and mostely set Flag and variable wich are tested in the main program, then it react depending of them.
mmm interesting... it's different from what i already heard somewhere. I should test it one day.
Usually my interrupt handler are just short and mostely set Flag and variable wich are tested in the main program, then it react depending of them.
Steve
It's not a bug, it's a random feature.
There's no problem, only learning opportunities.
Try the TIMER (Buttons.bas) example I just posted under the SINGLE BUTTON FUNCTION thread or OLYMPIC TIMER, both contain a GOSUB within an ISR.
You have to treat an ISR as if it was a SUBROUTINE except you exit with a RESUME rather than a RETURN.
The only thing you have to remember is the TOTAL number of pushes made on the stack do not exceed the maximum allowed for your PIC.
Hello Melanie ,mister_e
Yes its possible to use GOSUB in the interrupt handler.
But i do not really understand the thing with "TOTAL number of pushes made on the stack" What exactly are pushes and how do they get stored on the controller?
I posted another thread because the controller is reseting every 20 to 30 interrupst i guess it could stick on overflowing stack?
by NVM
how can i calculate the cycle time or the nummber of interrups I need to count exakt seconds?
by NVM
Every time you perform a GOSUB (or Interrupt Call), the return address is automatically pushed onto a stack within the processor core. When you perform a RETURN (or RESUME) that address is popped back out from the stack. All this happens automatically. All you must remember is that there should really be no more that FOUR actice events on the stack at any point in time. By that, the sum total of active GOSUBs and pending INTERRUPTS must not exceed FOUR, otherwise you risk losing the end stack contents as they are just pushed out into oblivion. You then have an unstable program.
I've not studied your problem, but if you think that every x interrupts you have a problem, then it seems to me you could be executing a new interrupt before you've completed handling the previous one. Make sure that Interrupts are DISABLED within your Interrupt Service Routine and that you exit your ISR with a RESUME before an new interrupt is allowed to happen.
Thanks Melanie
I reworked my code. Now any GOSUB should be ended by its own RETURN statement.
It's not working perfekt but i think i'll find out the other smal bugs soon.
What do you think about this?
The CODE:
main: '---- MAIN LOOP ---------------------------------
for warte = 0 to 10000 'Beschäftigen des Controllers
warte = warte +1
next warte
select case anzeige
case "H"
reset_flag = "H"
anzeige = 0
gosub main_menue_int
case "D"
reset_flag = "D"
gosub anzeige_drucksensor
case "T"
reset_flag = "T"
gosub anzeige_temperatur
case "G"
reset_flag = "G"
gosub anzeige_geschw
case "Q"
reset_flag = "Q"
gosub anzeige_quer
case "L"
reset_flag = "L"
gosub anzeige_laengs
case "a"
reset_flag = "a"
gosub auswahl_scrollmenue
case "Z"
reset_flag = "Z"
gosub anzeigen_zaehler
case 0
reset_flag = "E"
'toggle led
end select
main_ende:
goto main
Interrupt Haendler:
disable '------------ INTERRUPT -Handler------------------------
inter:
If ( PIR1.0 == 1) Then
timer1_flag = 1
zeiteinheit = zeiteinheit + 1
if (zeiteinheit >= 15) Then
zeiteinheit = 0
sek = sek +1
if sek>999 Then
sek = 0
endif
endif
PIR1.0 = 0
TMR1H = $00 'testing
TMR1L = $00 'testing
endif
if ( PIR1.5 == 1 ) then
'toggle led
empf = RCREG
rs232_flag = 1
select case empf
CASE 22, 8, 12, 61
anzeige = "H"
'GOSUB main_menue_int
case 71, 40, 50
'toggle led
anzeige = 0 'keine Grösse anzeigen
'endpunkt = "D"
gosub menue_sensoren 'gehe zu Menue "Sensoren"
case 72
gosub menue_Messablauf 'gehe zu Menue "Messablauf"
case 73, 33
gosub menue_einstellungen 'gehe zu Menue "Einstellungen"
case 74
gosub menue_credits 'gehe zu Menue "Credits"
CASE 20
anzeige = "D" 'Anzeigen des Drucks
druck_aktiv_flag = 1 'Temperaturanzeige ist Akti
temp_aktiv_flag = 0 'Temperaturanzeige ist Aktiv
querbeschl_aktiv_flag = 0 'Querbeschleunigungsanzeige ist Aktiv
laengsbeschl_aktiv_flag = 0 'Längsbeschleunigungsanzeige ist Aktiv
hserout [27,66, 82, 5, 2, 120, 240, 128, 0, 254, 1] 'Bargraph Nr.5 ausschlag nach rechts -->
pause mx
GOSUB menue_drucksensor
CASE 21
anzeige = "T" 'Anzeigen der Temperatur
druck_aktiv_flag = 0 'Temperaturanzeige ist Inaktiv
temp_aktiv_flag = 1 'Temperaturanzeige ist Aktiv
querbeschl_aktiv_flag = 0 'Querbeschleunigungsanzeige ist Inaktiv
laengsbeschl_aktiv_flag = 0 'Längsbeschleunigungsanzeige ist Inaktiv
hserout [27,66, 82, 5, 2, 120, 240, 128, 0, 254, 1] 'Bargraph Nr.5 ausschlag nach rechts -->
pause mx
GOSUB menue_temperatur
case 23
anzeige = "G" 'Anzeigen der Geschwindigkeit
'beschleunigung_flag = 0
hserout [27,66, 82, 5, 2, 120, 240, 128, 0, 254, 1] 'Bargraph Nr.5 ausschlag nach rechts -->
pause mx
gosub menue_geschw
case 25
anzeige = "Q" 'Anziegen der Quer Beschleunigung
druck_aktiv_flag = 0 'Temperaturanzeige ist Inaktiv temp_aktiv_flag = 0 'Temperaturanzeige ist Inaktiv 'neu
querbeschl_aktiv_flag = 1 'Querbeschleunigungsanzeige ist Aktiv
laengsbeschl_aktiv_flag = 0 'Längsbeschleunigungsanzeige ist Inaktiv
hserout [27,66, 79, 3, 2] 'Bargraph Nr.3 ausschlag nach oben
pause mx
hserout [60, 10, 1, 0, 254, 1] 'Bargraph Nr.3 ausschlag nach oben
pause mx
hserout [27,66, 85, 4, 2] 'Bargraph Nr.4 ausschlag nach unten
pause mx
hserout [61, 10, 125, 0, 254, 1] 'Bargraph Nr.4 ausschlag nach unten
pause mx
gosub menue_quer
case 26
anzeige = "L" 'Anzeigen der Längsbeschleunigung
druck_aktiv_flag = 0 'Temperaturanzeige ist Inaktiv
temp_aktiv_flag = 0 'Temperaturanzeige ist Inaktiv
querbeschl_aktiv_flag = 0 'Querbeschleunigungsanzeige ist Inaktiv
laengsbeschl_aktiv_flag = 1 'Längsbeschleunigungsanzeige ist Aktiv
hserout [27,66, 82, 1, 120] 'Bargraph Nr.1 ausschlag nach rechts-->
pause mx
hserout [120, 240, 128, 0, 254, 1] 'Bargraph Nr.1 ausschlag nach rechts-->
pause mx
hserout [27,66, 76, 2, 119] 'Bargraph Nr.2 ausschlag nach links <--
pause mx
hserout [120, 0, 128, 0, 254, 1] 'Bargraph Nr.2 ausschlag nach links <--
pause mx
gosub menue_laengs
Case 24
anzeige = "q"
beschleunigung_flag = 0
Gosub menue_besch
CASE 7
anzeige = "Z"
gosub menue_zeit
CASE 28
anzeige = 0
scroll_flag = 1
'GOSUB menue_offset
'gosub scrollmenue_offset
gosub menue_offset
CASE 11
anzeige = 0
scroll_flag = 0
GOSUB menue_Grundeinst
gosub scrollmenue_einstellungen
CASE 62
GOSUB analog_offset_1
HSerout [27,82,76,150,45,240,65] 'bereich löschen
pause mx
HSEROUT [27,70,3,1,1] 'Font 3 verwenden
pause mx '
Hserout [27,90,76,150,50,"Offset = ",#wert_offset1,0]
pause mx
case 63
gosub analog_offset_2
HSerout [27,82,76,150,65,240,85] 'bereich löschen
pause mx
HSEROUT [27,70,3,1,1] 'Font 3 verwenden
pause mx
Hserout [27,90,76,150,72,"Offset = ",#wert_offset2,0]
pause mx
case 64
gosub analog_offset_3
HSerout [27,82,76,150,85,240,105] 'bereich löschen
pause mx
HSEROUT [27,70,3,1,1] 'Font 3 verwenden
pause mx
Hserout [27,90,76,150,95,"Offset = ",#wert_offset3,0]
pause mx
case 30
hserout [27,78,80]
case 31
hserout [27,78,78]
case 32
anzeige = "a"
case 1
hserout [27,68,82]
anzeige = "H"'GOSUB main_menue_int
anzeige = 0
case 2
Toggle anzeige_einheit
gosub anzeige_einheit_aendern
gosub scrollmenue_einstellungen
anzeige = 0
case 3
toggle ton
gosub tonaendern
gosub scrollmenue_einstellungen
anzeige = 0
case 4
toggle beschl_switch
gosub beschl_einheit_aendern 'Ändern der Anzeigeeinheit für Beschleunigung
gosub scrollmenue_einstellungen
anzeige = 0
'case else
' anzeige = "H" 'gosub main_menue_int 'gehe zurück ins Hauptmenü
end select
ENDIF
z1_tmp=10 'Temporäre Ziffern immer neu löschen bei neuem Ziffernaufbau
z2_tmp=10
z3_tmp=10
z4_tmp=10
if (rs232_flag = 1) then
rs232_flag = 0
select case reset_flag
case "H"
reset_flag = 0
resume menue_main_ende
case "D"
reset_flag = 0
resume druck_ende
case "T"
reset_flag = 0
resume temp_ende
case "G"
reset_flag = 0
resume geschw_ende
case "Q"
resume quer_ende
case "L"
reset_flag = 0
resume laengs_ende
case "a"
resume scroll_ende
case "Z"
reset_flag = 0
resume zaehl_ende
case "E"
reset_flag = 0
resume
end select
endif
if (timer1_flag == 1) then
timer1_flag = 0
resume
endif
'resume main_ende
enable
toggle led
goto main_ende
by NVM
Bookmarks