EMS10
Verschillende varianten van een eenvoudige toestands- machine
In dit document vind je verschillende uitwerkingen vanopdracht 5.2.3van EMS10.
Deze opdracht luidt als volgt:
Implementeer de infiguur 1gegeven toestandsmachine.
op slot RGB= 100 start
dicht RGB= 001
open RGB= 010 SW0
SW0
SW1
SW1
Figuur 1: Eenvoudige toestandsmachine.
Het gaat hier om een toestandsmachine van een deur. De deur kan zich in drie toestanden bevinden:
• op slot, dit wordt aangegeven door de RGB led rood te laten branden;
• dicht, dit wordt aangegeven door de RGB led blauw te laten branden;
• open, dit wordt aangegeven door de RGB led groen te laten branden.
De deur kan alleen geopend worden en/of op slot gedaan worden vanuit de toestand dicht. Door één maal op drukknop SW 0 te drukken kan de deur van het slot worden gehaald respectievelijk op slot worden gedaan. Door één maal op drukknop SW 1 te drukken kan de deur geopend respectievelijk gesloten worden.
De knoppen moeten dus ontdenderd worden en er moet flankdetectie worden toegepast. Als het programma start, moet de deur zich in de toestand op slot bevinden.
EMS10 Hardware
Hardware
In dit document wordt er van uitgegaan dat je de MSP430G2553 op je breadboard hebt geplaatst samen met twee drukknoppen en een common-cathode RGB-led met drie weerstanden om de stroom door de leds te begrenzen. Deze moeten als volgt aangesloten worden:
• knop SW 0 moet geplaatst worden tussen VCC en P1.0;
• knop SW 1 moet geplaatst worden tussen VSS (GND) en P1.1;
• de common-cathode moet verbonden worden met VSS (GND);
• de rode led moet via een weerstand verbonden worden met P2.0;
• de groene led moet via een weerstand verbonden worden met P2.1;
• de blauwe led moet via een weerstand verbonden worden met P2.2.
Ik ga ervan uit dat je weet hoe je een knop moet inlezen en hoe je een led moet aansturen met behulp van de MSP430G2553.
Stap voor stap
De methode die we gebruiken om tot een werkend programma te komen dat aan de opdracht voldoet is stapsgewijze verfijning (Engels: stepwise refinement).
We beginnen met een eenvoudig programma en breiden het programma stap voor stap uit tot we uiteindelijk het gewenste programma hebben. We testen het programma na elke stap.
Flankdetectie
SW0
Om te beginnen is het handig om eerst de flankdetectie van de knoppen te imple- menteren en te testen. We beginnen met een programma dat de rode led inverteert tekens als knop SW 0 wordt ingedrukt. Als knop SW 0 is ingedrukt, dan is P1.0 verbonden met VCC. Als knop SW 0 niet is ingedrukt, moeten we er voor zorgen dat P1.0 laag is. Dit doen we door een pull-down weerstand aan te sluiten op pin P1.0. Dat kan met behulp van een externe weerstand, maar het is veel eenvoudiger
EMS10 FlankdetectieSW0
om de intern in de MSP430G2553 aanwezige pull-down weerstand te gebruiken.
Dit kunnen we, zoals je weet, instellen met behulp van registersP1RENenP1OUT. Als we willen detecteren of knop SW 0 ingedrukt is, dan kunnen we eenvoudig het registerPIN1uitlezen en bit 0 bekijken. Als we willen detecteren of knop SW 0 ingedrukt wordt, dan moeten we ook de vorige toestand van de knop onthouden.
Op die manier kunnen we een verandering in de toestand van de knop waarnemen.
Inlisting 1is een programma gegeven dat het signaal op de rode led inverteert (toggled) als knop SW 0 wordt ingedrukt.
1 # i n c l u d e < m s p 4 3 0 . h >
2 # i n c l u d e < s t d b o o l . h >
3
4 int main (void)
5 {
6 W D T C T L = WDT PW | W D T H O L D ; // stop de w a t c h d o g ti mer
7
8 P2 DIR |= 1 << 0; // zet pin P2.0 op o u t p u t
9 P2 OUT &= ~(1 << 0) ; // P2.0 = 0
10
11 P1 DIR &= ~(1 << 0) ; // zet pin P1.0 op i npu t
12 P1 REN |= 1 << 0; // zet i n t e r n e w e e r s t a n d aan bij pin ←- ,→ P1.0
13 P1 OUT &= ~(1 << 0) ; // s e l e c t e e r pull down w e e r s t a n d ←- ,→ op pin P1.0
14
15 bool k n o p 0 _ w a s _ i n g e d r u k t = false;
16 while (1)
17 {
18 bool k n o p 0 _ i s _ i n g e d r u k t = ( P1IN & (1 << 0) ) != 0;
19 if ( k n o p 0 _ w a s _ i n g e d r u k t == false && ←- ,→ knop0_is_ingedrukt == true)
20 {
21 P2 OUT ^= 1 << 0; // t o g g l e P2.0
22 }
23 k n o p 0 _ w a s _ i n g e d r u k t = k n o p 0 _ i s _ i n g e d r u k t ;
EMS10 FlankdetectieSW0
24 }
25 r et u r n 0;
26 }
Listing 1:De rode led gaat aan/uit alsSW0wordt ingedrukt:
knop_pull_down_wordt_ingedrukt.c.
In dit programma wordt de booleaanse variabeleknop0_is_ingedruktgebruikt om bij te houden of knop SW 0 ingedrukt is en wordt de booleaanse variabele knop0_was_ingedruktgebruikt om bij te houden of knop SW 0 ingedrukt was. Met behulp van deze twee booleaanse variabelen kan bepaald worden of knop SW 0 ingedrukt wordt. De knop wordt namelijk ingedrukt als de knop niet ingedrukt wasen wel ingedrukt is. Op regel 19 vanlisting 1is dit in C gecodeerd. Let op het verschil tussen de logische ‘and’-bewerking (&&) en de bitwise ‘and’-bewerking (&)1.
Regel 19 kan korter gecodeerd worden. De variabeleknop0_is_ingedruktis een booleaanse variabele en heeft dus de waardetrueoffalse. De expressie:
k n o p 0 _ i s _ i n g e d r u k t == true
levert dus hetzelfde resultaat als de expressie:
k n o p 0 _ i s _ i n g e d r u k t
De variabeleknop0_was_ingedruktis een booleaanse variabele en heeft dus de waardetrueoffalse. De expressie:
k n o p 0 _ w a s _ i n g e d r u k t == false
levert dus hetzelfde resultaat als de expressie:
! k n o p 0 _ w a s _ i n g e d r u k t
Waarbij de operator!de booleaanse ‘not’ operator is. Let op het verschil tussen de logische ‘not’-bewerking (!) en de bitwise ‘not’-bewerking (~)1.
1 Zie: https://bitbucket.org/HR_ELEKTRO/cprog/wiki/Dictaat-C_ebook.pdf#subsection.
9.1.2
EMS10 OntdenderenSW0
Regel 19:
if ( k n o p 0 _ w a s _ i n g e d r u k t == false && k n o p 0 _ i s _ i n g e d r u k t ←- ,→ == true)
kan dus ook als volgt gecodeerd worden:
if (! k n o p 0 _ w a s _ i n g e d r u k t && k n o p 0 _ i s _ i n g e d r u k t )
Ontdenderen
SW 0
Het programma gegeven inlisting 1werkt niet correct als de knop SW 0 dendert.
Er komen dan namelijk meerder opgaande flanken op pin P1.0 als knop wordt ingedrukt (of losgelaten). Dit probleem kunnen we oplossen met behulp van hardware door een laagdoorlaatfilter tussen de knop en de pin te plaatsen. Het is echter ook eenvoudig mogelijk om de knop te ontdenderen met behulp van software. Het enige dat we moeten doen is een vertraging invoegen zodat de dender verdwenen is als de knop opnieuw wordt ingelezen. Een vertraging van 10 ms is over het algemeen voldoende. Inlisting 2is deze vertraging toegevoegd op regel 24.
1 # i n c l u d e < m s p 4 3 0 . h >
2 # i n c l u d e < s t d b o o l . h >
3
4 int main (void)
5 {
6 W D T C T L = WDT PW | W D T H O L D ; // stop de w a t c h d o g ti mer
7
8 P2 DIR |= 1 << 0; // zet pin P2.0 op o u t p u t
9 P2 OUT &= ~(1 << 0) ; // P2.0 = 0
10
11 P1 DIR &= ~(1 << 0) ; // zet pin P1.0 op i npu t
12 P1 REN |= 1 << 0; // zet i n t e r n e w e e r s t a n d aan bij pin ←- ,→ P1.0
13 P1 OUT &= ~(1 << 0) ; // s e l e c t e e r pull down w e e r s t a n d ←- ,→ op pin P1.0
EMS10 Flankdetectie en ontdenderenSW1
14
15 bool k n o p 0 _ w a s _ i n g e d r u k t = false;
16 while (1)
17 {
18 bool k n o p 0 _ i s _ i n g e d r u k t = ( P1IN & (1 << 0) ) != 0;
19 if (! k n o p 0 _ w a s _ i n g e d r u k t && k n o p 0 _ i s _ i n g e d r u k t )
20 {
21 P2 OUT ^= 1 << 0; // t o g g l e P2.0
22 }
23 k n o p 0 _ w a s _ i n g e d r u k t = k n o p 0 _ i s _ i n g e d r u k t ;
24 _ _ d e l a y _ c y c l e s ( 1 1 0 0 0 ) ; // 10 ms w a c h t e n @ 1 .1 MHz ←- ,→ ( z org t voor s o f t w a r e m a t i g o n t d e n d e r e n van de knop )
25 }
26 r et u r n 0;
27 }
Listing 2:De rode led gaat aan/uit alsSW0wordt ingedrukt:
knop_pull_down_wordt_ingedrukt_ontdenderd.c.
Flankdetectie en ontdenderen
SW 1
We schrijven vervolgens een programma dat de rode led inverteert tekens als knop SW1 wordt ingedrukt. Als knop SW 1 is ingedrukt, dan is P1.0 verbonden met VSS. Als knop SW 1 niet is ingedrukt, moeten we er voor zorgen dat P1.1 hoog is. Dit doen we door een pull-up weerstand aan te sluiten op pin P1.1. Dat kan met behulp van een externe weerstand, maar het is veel eenvoudiger om de intern in de MSP430G2553 aanwezige pull-up weerstand te gebruiken. Dit kunnen we, zoals je weet, instellen met behulp van registersP1RENenP1OUT.
Inlisting 2is een programma gegeven dat detecteert dat SW 1 wordt ingedrukt. Er is een vertraging toegevoegd, zodat je geen last hebt van dender.
1 # i n c l u d e < m s p 4 3 0 . h >
2 # i n c l u d e < s t d b o o l . h >
3
4 int main (void)
EMS10 Eenvoudige toestandsmachine
5 {
6 W D T C T L = WDT PW | W D T H O L D ; // stop de w a t c h d o g ti mer
7
8 P2 DIR |= 1 << 0; // zet pin P2.0 op o u t p u t
9 P2 OUT &= ~(1 << 0) ; // P2.0 = 0
10
11 P1 DIR &= ~(1 << 1) ; // zet pin P1.1 op i npu t
12 P1 REN |= 1 << 1; // zet i n t e r n e w e e r s t a n d aan bij pin ←- ,→ P1.1
13 P1 OUT |= 1 << 1; // s e l e c t e e r pull up w e e r s t a n d op pin ←- ,→ P1.1
14
15 bool k n o p 1 _ w a s _ i n g e d r u k t = false;
16 while (1)
17 {
18 bool k n o p 1 _ i s _ i n g e d r u k t = ( P1IN & (1 << 1) ) == 0;
19 if (! k n o p 1 _ w a s _ i n g e d r u k t && k n o p 1 _ i s _ i n g e d r u k t )
20 {
21 P2 OUT ^= 1 << 0; // t o g g l e P2.0
22 }
23 k n o p 1 _ w a s _ i n g e d r u k t = k n o p 1 _ i s _ i n g e d r u k t ;
24 _ _ d e l a y _ c y c l e s ( 1 1 0 0 0 ) ; // 10 ms w a c h t e n @ 1 .1 MHz ←- ,→ ( z org t voor s o f t w a r e m a t i g o n t d e n d e r e n van de knop )
25 }
26 r et u r n 0;
27 }
Listing 3:De rode led gaat aan/uit alsSW1wordt ingedrukt:
knop_pull_up_wordt_ingedrukt_ontdenderd.c.
Eenvoudige toestandsmachine
In listing 4 vind je een eenvoudige implementatie van de in figuur 1gegeven toestandsmachine. De flankdetectie en het ontdenderen van de knoppen SW 0 en SW1 is overgenomen uitlistings 2en3.
EMS10 Eenvoudige toestandsmachine
1 # i n c l u d e < m s p 4 3 0 . h >
2 # i n c l u d e < s t d b o o l . h >
3
4 int main (void)
5 {
6 W D T C T L = WDT PW | W D T H O L D ; // stop de w a t c h d o g ti mer
7
8 P2 DIR |= 1 << 2 | 1 << 1 | 1 << 0; // zet pins P2.2 , ←- ,→ P2.1 en P2.0 op o u t p u t
9 P2 OUT &= ~(1 << 2 | 1 << 1) ; // P2.2 en P2.1 laag ←- ,→ Bl auw uit en Gr oen uit
10 P2 OUT |= 1 << 0; // P2.0 = 1 Rood aan
11
12 P1 DIR &= ~(1 << 1 | 1 << 0) ; // zet pin P1.1 en P1.0 ←- ,→ op inp ut
13 P1 REN |= 1 << 1 | 1 << 0; // zet i n t e r n e w e e r s t a n d aan ←- ,→ bij pin P1.1 en P1.0
14 P1 OUT &= ~(1 << 0) ; // s e l e c t e e r pull down w e e r s t a n d ←- ,→ op pin P1.0
15 P1 OUT |= 1 << 1; // s e l e c t e e r pull up w e e r s t a n d op pin ←- ,→ P1.1
16
17 int t o e s t a n d = 0; // beg in in t o e s t a n d op slot
18
19 bool k n o p 0 _ w a s _ i n g e d r u k t = false;
20 bool k n o p 1 _ w a s _ i n g e d r u k t = false;
21
22 while (1)
23 {
24 bool k n o p 0 _ i s _ i n g e d r u k t = ( P1IN & (1 << 0) ) != 0;
25 bool k n o p 1 _ i s _ i n g e d r u k t = ( P1IN & (1 << 1) ) == 0;
26
27 s wi t c h ( t o e s t a n d )
28 {
29 case 0: // op slot
30 if (! k n o p 0 _ w a s _ i n g e d r u k t && k n o p 0 _ i s _ i n g e d r u k t )
31 {
EMS10 Eenvoudige toestandsmachine
32 P2 OUT &= ~(1 << 0) ; // P2.0 = 0 Rood uit
33 P2 OUT |= 1 << 2; // P2.2 = 1 B lau w aan
34 t o e s t a n d = 1; // dic ht
35 }
36 break;
37 case 1: // dic ht
38 if (! k n o p 0 _ w a s _ i n g e d r u k t && k n o p 0 _ i s _ i n g e d r u k t )
39 {
40 P2 OUT &= ~(1 << 2) ; // P2.2 = 0 B lau w uit
41 P2 OUT |= 1 << 0; // P2.0 = 1 Rood aan
42 t o e s t a n d = 0; // op slot
43 }
44 if (! k n o p 1 _ w a s _ i n g e d r u k t && k n o p 1 _ i s _ i n g e d r u k t )
45 {
46 P2 OUT &= ~(1 << 2) ; // P2.2 = 0 B lau w uit
47 P2 OUT |= 1 << 1; // P2.1 = 1 G roe n aan
48 t o e s t a n d = 2; // open
49 }
50 break;
51 case 2: // open
52 if (! k n o p 1 _ w a s _ i n g e d r u k t && ! k n o p 1 _ i s _ i n g e d r u k t )
53 {
54 P2 OUT &= ~(1 <<1 ) ; // P2.1 = 0 G roe n uit
55 P2 OUT |= 1 << 2; // P2.2 = 1 B lau w aan
56 t o e s t a n d = 1; // dic ht
57 }
58 break;
59 }
60 k n o p 0 _ w a s _ i n g e d r u k t = k n o p 0 _ i s _ i n g e d r u k t ;
61 k n o p 1 _ w a s _ i n g e d r u k t = k n o p 1 _ i s _ i n g e d r u k t ;
62 _ _ d e l a y _ c y c l e s ( 1 1 0 0 0 ) ; // 10 ms w a c h t e n @ 1 .1 MHz ←- ,→ ( z org t voor s o f t w a r e m a t i g o n t d e n d e r e n van de knop )
63 }
64 r et u r n 0;
65 }
Listing 4: Een eenvoudige toestandsmachine:opdr5.2.3_a.c.
EMS10 Toestand coderen met eenenum
De toestand waarin de toestandsmachine zich bevindt wordt bijgehouden in de integer variabeletoestand. Met behulp van een switch-statement2 wordt, op regel 27 tot en met 57, per toestand de bijbehorende actie gecodeerd.
Hoewel deze code exact doet wat er gevraagd wordt, kan de leesbaarheid, aanpas- baarheid, uitbreidbaarheid en herbruikbaarheid van dit programma nog (sterk) verbeterd worden.
Toestand coderen met een
enum
Inlisting 4wordt de toestand waarin de toestandsmachine zich bevindt bijgehou- den in de integer variabeletoestand. De programmeur moet dus zelf onthouden welk nummer bij welke toestand hoort. Hij/zij heeft commentaar toegevoegd om aan te geven over welke toestand het gaat. In het algemeen is het beter om dit soort informatie te coderen in de C-taal en niet in het commentaar (indien mogelijk). In dit geval kan dat gedaan worden door een zogenoemdeenumte gebruiken3, zielisting 5.
17 t y p e d e f enum { opslot , dicht , open } T o e s t a n d ;
18 T o e s t a n d t o e s t a n d = o p s l o t ;
19
20 bool k n o p 0 _ w a s _ i n g e d r u k t = false;
21 bool k n o p 1 _ w a s _ i n g e d r u k t = false;
22
23 while (1)
24 {
25 bool k n o p 0 _ i s _ i n g e d r u k t = ( P1IN & (1 << 0) ) != 0;
26 bool k n o p 1 _ i s _ i n g e d r u k t = ( P1IN & (1 << 1) ) == 0;
27
28 s wi t c h ( t o e s t a n d )
29 {
30 case o p s l o t :
2 Zie:https://bitbucket.org/HR_ELEKTRO/cprog/wiki/Dictaat-C_ebook.pdf#section.5.3
3 Zie: https://bitbucket.org/HR_ELEKTRO/ems10/wiki/Handboek/EMS10_handboek_ebook.
pdf#chapter.8.
EMS10 Maskers coderen
31 if (! k n o p 0 _ w a s _ i n g e d r u k t && k n o p 0 _ i s _ i n g e d r u k t )
Listing 5:Een toestandsmachine waarbij de toestanden zijn gecodeerd met eenenum: opdr5.2.3_b.c.
Maskers coderen
De programmeur moet bij alle tot nu toe gepresenteerde programma’s zelf ont- houden welk masker (of pinnummer) bij welke led of drukknop hoort. Hij/zij heeft commentaar toegevoegd om aan te geven over welke led of knop het gaat.
In het algemeen is het beter om dit soort informatie te coderen in de C-taal en niet in het commentaar (indien mogelijk). In dit geval kan dat maar liefst op drie verschillende manieren gedaan worden:
• met behulp van#define, zieopdr5.2.3_c.c;
• met behulp vanconst, zieopdr5.2.3_d.c;
• met behulp vanenum, zieopdr5.2.3_e.c;
Met behulp van #define kunnen we woorden definiëren die voordat het pro- gramma gecompileerd wordt, door de zogenoemde preprocessor, vervangen wor- den door een stukje code.
Bijvoorbeeld als we definiëren:
# de f i ne BL AUW (1 << 2)
Dan kunnen we de code om de blauwe led uit te zetten:
P2 OUT &= ~(1 << 2) ; // P2.2 = 0 B lau w uit
coderen als:
P2 OUT &= ~ BL AUW ; // B lau w uit
De preprocessor zal het woordBLAUWvervangen door(1 << 2). Let erop dat in dit geval de haken bij de#definenoodzakelijk zijn!
EMS10 Abstractie verhogen met behulp van functies
We kunnen ook een constante definiëren met de naamBLAUWen de waarde van het betreffende masker:
const i n t 8 _ t BLA UW = 1 << 2;
We kunnen de blauwe led nu als volgt uitzetten:
P2 OUT &= ~ BL AUW ; // B lau w uit
We kunnen ook een enumeratietype definiëren waarin we de maskerwaarden van de verschillende leds definiëren:
t y p e d e f enum { ROOD = 1 << 0 , G ROE N = 1 << 1 , BLA UW = 1 << ←- ,→ 2} leds ;
We kunnen de blauwe led nu als volgt uitzetten:
P2 OUT &= ~ BL AUW ; // B lau w uit
Welke van deze drie methoden je kiest is afhankelijk van je persoonlijke smaak.
Als de optimizer aangezet wordt bij het compileren van de C-code leveren alle drie de methoden exact dezelfde machinecode op. De methode met behulp van
#defineis het minst aan te raden omdat bij het gebruik van deze methode soms onverwachte effecten op kunnen treden (bijvoorbeeld als je de haakjes vergeet). In het vervolg van dit document wordt de methode met behulp vanconstgebruikt.
Abstractie verhogen met behulp van functies
Door gebruik te maken van functies, kunnen we bepaalde details verbergen en kunnen we de toestandsmachine op een hoger abstractieniveau beschrijven.
Als we bijvoorbeeld de volgende functie definiëren:
void l e d _ u i t ( i n t 8 _ t m a s k e r ) {
P2 OUT &= ~ m a s k e r ; }
Dan kunnen we de blauwe led met de volgende code uitzetten:
EMS10 Abstractie verhogen met behulp van functies
l e d _ u i t ( BL AUW ) ;
Deze code heeft geen commentaar meer nodig, maar spreekt voor zichzelf.
Inopdr5.2.3_f1.czijn functies gebruikt om de implementatie van de toestands- machine in het hoofdprogramma leesbaarder te maken. Inopdr5.2.3_f2.cis de functieknop_is_ingedruktmet behulp van booleaanse operatoren heel compact gecodeerd.
Inopdr5.2.3_f3.czijn de functiesknop_0_wordt_ingedruktenknop_1_wordt_- ingedruktgedefinieerd waardoor de toestandsmachine op een hoog abstractieni- veau kan worden weergegeven, zielisting 6.
50 t y p e d e f enum { opslot , dicht , open } T o e s t a n d ;
51 T o e s t a n d t o e s t a n d = o p s l o t ;
52
53 while (1)
54 {
55 s wi t c h ( t o e s t a n d )
56 {
57 case o p s l o t :
58 if ( k n o p _ 0 _ w o r d t _ i n g e d r u k t () )
59 {
60 l e d _ u i t ( ROOD ) ;
61 l e d _ a a n ( BL AUW ) ;
62 t o e s t a n d = dic ht ;
63 }
64 break;
65 case di cht :
66 if ( k n o p _ 0 _ w o r d t _ i n g e d r u k t () )
67 {
68 l e d _ u i t ( BL AUW ) ;
69 l e d _ a a n ( ROOD ) ;
70 t o e s t a n d = o p s l o t ;
71 }
72 if ( k n o p _ 1 _ w o r d t _ i n g e d r u k t () )
73 {
EMS10 Abstractie verhogen met behulp van functies
74 l e d _ u i t ( BL AUW ) ;
75 l e d _ a a n ( GR OEN ) ;
76 t o e s t a n d = open ;
77 }
78 break;
79 case open :
80 if ( k n o p _ 1 _ w o r d t _ i n g e d r u k t () )
81 {
82 l e d _ u i t ( GR OEN ) ;
83 l e d _ a a n ( BL AUW ) ;
84 t o e s t a n d = dic ht ;
85 }
86 break;
87 }
88 _ _ d e l a y _ c y c l e s ( 1 1 0 0 0 ) ; // 10 ms w a c h t e n @ 1 .1 MHz ←- ,→ ( z org t voor s o f t w a r e m a t i g o n t d e n d e r e n van de knop )
89 }
Listing 6:Met behulp van functies kan de toestandsmachine op een hoog abstractieniveau gecodeerd worden:opdr5.2.3_f3.c.
De functie knop_0_wordt_ingedrukt moet dus zelf onthouden wat de vorige toestand van de knop was, zielisting 7.
11 bool k n o p _ 0 _ w o r d t _ i n g e d r u k t (void) {
12 s ta t i c bool w a s _ i n g e d r u k t = false;
13 bool i s _ i n g e d r u k t = ( P1IN & SW0 ) != 0;
14 bool w o r d t _ i n g e d r u k t = ! w a s _ i n g e d r u k t && i s _ i n g e d r u k t ;
15 w a s _ i n g e d r u k t = i s _ i n g e d r u k t ;
16 r et u r n w o r d t _ i n g e d r u k t ;
17 }
Listing 7: De functieknop_0_wordt_ingedrukt:opdr5.2.3_f3.c.
De variabele was_ingedrukt moet dus static gedefinieerd worden zodat de waarde van deze variabele behouden blijft ook als de functie beëindigd is.