PDA

View Full Version : Controlling an 240x128 LCD Touchpanel Display



Vincent
- 6th June 2006, 18:30
Hello everybody

First to say i'm new here.

I've got a very complex problem,
I'm trying to controll a LCD Display with touchpanel via interrupts and RS232 interface.
I'm using an PIC18F452 Controller
and this Display: www.electronicassembly.de/eng/pdf/grafik/kit2407e.pdf
www.lcd-module.de/deu/pdf/grafik/kit240-7.pdf

All the comunication with the controler and the Display is working fine.
Also the comands from the Display are recived via RS232 interrupt.
The Problem now is: I need the controller to count seconds.
I tryed to do this via Timer1 interrupt but this is not working!
The CODE I use looks like this:
'-----Interrupt--settings---------------------------------------------------
PIE1.5 = 1 'Interrupt Enable "Empfang
PIR1.5 = 0 'Interrupt Flag bit Empfang
PIR1 = $00 'alle anstehenden Interrupts löschen
PIR2 = $00 '

INTCON = %11100000 'GIE,PEIE , testing bit5 = 1
INTCON2 = %00000000 'Interrupt Kontrollregister 2

Timer1-------------------------------------------------------------------------
T1CON = %10001001 '7=16Bit,5-4=Prescaler,0=Timer ON
PIE1.0=1 'testing 'Interrupt enable für Timer1
TMR1H =0 'Timer Hight Byte
TMR1L =0 'Timer Low Byte
IPR1.0=1 'Interrupt Priorität High

disable '------------ INTERRUPT -Handler------------------------
inter:


If ( PIR1.0 == 1) Then ' Timer1 overflow
'toggle led 'LED zustand wechseln

zeiteinheit = zeiteinheit + 1 'Variable "Zeiteinheit" hochzählen
if (zeiteinheit >= 15) Then
zeiteinheit = 0
sek = sek +1 'Variable "sek" hochzählen

if sek>999 Then
sek = 0 'Variable "sek" auf 0 setzen
endif

endif

PIR1.0 = 0 'Timer1 überlaufflag auf 0 setzen
TMR1H = $00 'testing 'Zählregister mit dem Wert vorbelegen
TMR1L = $00 'testing 'Zählregister mit dem Wert 0 vorbelegen

endif



if ( PIR1.5 == 1 ) then 'Zeichen über RS232 Schnittstelle

empf = RCREG 'Empfangsregister in empf kopieren

select case empf 'Auswahl anhand des empfangenen Zeichen treffen
CASE 22, 8, 12, 61
anzeige = 0
GOSUB main_menue_int
case 71, 40, 50
anzeige = 0
endpunkt = "D"
gosub menue_sensoren
case 72
gosub menue_Messablauf
case 73, 33
gosub menue_einstellungen
case 74
gosub menue_credits
CASE 20
anzeige = "D"
druck_aktiv_flag = 1
temp_aktiv_flag = 0
querbeschl_aktiv_flag = 0 laengsbeschl_aktiv_flag = 0
hserout [27,66, 82, 5, 2, 120, 240, 128, 0, 254, 1]
pause mx
GOSUB menue_drucksensor
CASE 21
anzeige = "T"

druck_aktiv_flag = 0
temp_aktiv_flag = 1
querbeschl_aktiv_flag = 0
laengsbeschl_aktiv_flag = 0

hserout [27,66, 82, 5, 2, 120, 240, 128, 0, 254, 1]
pause mx
GOSUB menue_temperatur
case 23
anzeige = "G"
'beschleunigung_flag = 0
hserout [27,66, 82, 5, 2, 120, 240, 128, 0, 254, 1]
pause mx
gosub menue_geschw
case 25
anzeige = "Q"
druck_aktiv_flag=0 temp_aktiv_flag = 0
querbeschl_aktiv_flag = 1
laengsbeschl_aktiv_flag = 0

hserout [27,66, 79, 3, 2]
pause mx
hserout [60, 10, 1, 0, 254, 1]
pause mx

hserout [27,66, 85, 4, 2]
pause mx
hserout [61, 10, 125, 0, 254, 1]
pause mx

gosub menue_quer
case 26
anzeige = "L"

druck_aktiv_flag = 0
temp_aktiv_flag = 0
querbeschl_aktiv_flag = 0
laengsbeschl_aktiv_flag = 1

hserout [27,66, 82, 1, 120]
pause mx
hserout [120, 240, 128, 0, 254, 1]
pause mx

hserout [27,66, 76, 2, 119]
pause mx
hserout [120, 0, 128,254,1]
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]
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
gosub main_menue_int 'gehe zurück ins Hauptmenü
end select

ENDIF


GOTO int_ende
'--------------------------------------------------------------------------

if i now enable the Timer1 interrupt every time a Timer1 interrupt is aktive also the RS232 ELSE CASE will be carried out
if i disable the Timer1 interrupt put keep the Timer1 runnig ervery time a RS232 interrupt is aktive also the Timer1 interrupt serviceroutine will be carried out.

If there is anybody here who can help me on this problem i would be very glad
and thankeful

by NVM

mister_e
- 6th June 2006, 23:21
i saw 2 things

You can't use Gosub in a interrupt handler
I don't see that you re-enable the interrupts


And it should be only a part of your program 'cause i don't see any ON Interrupt goto statement.

Vincent
- 7th June 2006, 07:28
Thanks mister_e!

I will try to reprogram the interrupthandler without using GOSUB.

The on interrupt goto statement is written in a GOSUB init: funktion which is called befor the main: loop
'--------------------------------------------------------------------------
inter_default:
on interrupt goto inter
return
'--------------------------------------------------------------------------

The reenabeling of interrupt is done in this two funktions:
'--------------------------------------------------------------------------
int_ende: 'Interrupt Ende

z1_tmp=10
z2_tmp=10
z3_tmp=10
z4_tmp=10

resume main_ende
enable

'--------------------------------------------------------------------------
main_ende:
pause 10
goto main

Vincent
- 7th June 2006, 09:40
No my interrupthandler is working without any GOSUB routine.
But the problem with having a variable counted up via a timer1 interrupt is still there.
???

by NVM

Melanie
- 7th June 2006, 09:43
> You can't use Gosub in a interrupt handler

Not true.

You just got to watch how many Interrupts & Gosubs you've got pushed on the stack and not exceed the maximum allowed. The sum total in most cases must not exceed FOUR.

mister_e
- 7th June 2006, 12:34
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.

Melanie
- 7th June 2006, 12:53
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.

Vincent
- 7th June 2006, 15:06
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

Vincent
- 7th June 2006, 15:10
how can i calculate the cycle time or the nummber of interrups I need to count exakt seconds?

by NVM

SteveB
- 7th June 2006, 18:22
http://www.picbasic.co.uk/forum/showthread.php?t=2031

Melanie
- 7th June 2006, 21:50
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.

Vincent
- 7th June 2006, 22:05
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

Vincent
- 7th June 2006, 23:36
Mots of my problems are solved...
I should have posted earlier in this Forum.
That would have saved me some sleepless nights.

Thanks to all of you.

I'll be back with better problems or better say tasks...


good night

by NVM