15.8 De generieke IO als ingang gebruiken

Vergelijkbare documenten
212 Generieke IO De generieke IO als ingang gebruiken

ES1 Project 1: Microcontrollers

ES1 Project 1: Microcontrollers

Technology, Innovation & Society Delft

Workshop Arduino - deel 2

Inhoud. 1 De Microcontroller 1. 2 De taal C C in het kort Functies 31

Inhoud. 1 De Microcontroller 1. 2 De taal C C in het kort Functies 31

Inhoud. 1 De Microcontroller 1. 2 De taal C Declaraties Functies In- en uitvoer Voorwaardelijke opdrachten 41

RCL Arduino Workshop 1

Werkbladen voor Arduino workshop 1

Arduino Workshop 1 Zuid-Limburg

Tweede workshop Arduino

Hoofdstuk5. 1 Hoofdstuk5: Praktische realisatie van logische schakelingen. Peter Slaets () Digitale en analoge technieken October 6, / 19

Applicatiesoftware Tebis

Oefening 1 - Seriële communicatie via USB

Installeren van de Forest Shuttle. Home Automation by

Microcontrollers. Bart Kardinaal E Verslag microcontrollers Rev 1.0 Status definitief.

1. Sluit de LED aan zoals afgebeeld 2. Sluit de USB-kabel aan op de Arduino 3. Klik op de knop uploaden 4. De LED begint te knipperen

Tinyserir-RC5. Datasheet. Tinyserir-RC5 Page: 1 of 8

Microcontrollers Week 4 Introductie microcontroller Jesse op den Brouw (met dank aan Ben Kuiper) INLMIC/

Installeren van de Forest Shuttle. Home Automation by

Inschakelautomaten op 3V

Handleiding ALFANET 70-Clock

De FOR lus: // terug naar waar je vandaan kwam Serial.begin(115200); // communicatie snelheid met de PC

Gebruiksaanwijzing TTA /+150 C (1) VDH doc Versie: V1.1 Datum:

De Arduino-microcontroller in de motorvoertuigentechniek (4)

Handleiding HCS VB5118

Integratie van Net2 met een inbraakalarmsysteem

MAKERKLAS WORKSHOP ARDUINO. Maandag 7 december 2015

LocoIO Handleiding HDM08

c o n t r o l Computerbesturing voor basisscholen Laurence Rogers en Doug Dickinson, School of Education, University of Leicester

Beschrijving bedieningsunit, Serie AK30.

Ontvanger met GSM-transmissie GSM 700

LocoServo Handleiding

Inhoud vandaag. Interrupts. Algemeen ARM7 AIC

Gebruikershandleiding. Bedienpaneel MINI-REP

GEÏNTEGREERDE PROEF. VTI Sint-Laurentius. Pakketweegschaal. Industriële informatie & communicatietechnologie SCHOOLJAAR

CTCSS Encoder Super Flexibel Ontwerpen met een Arduino Nano

Gebruikershandleiding. Brandmeldcentrale JUNO-NET EN54

EmSE presentatie. Starten met de ATtiny2313: Een RGB powerled driver Kees Moerman, 13 juli 2010

Montagevoorschriften

KIT OVO. De automatisering moet worden onderworpen aan onderhoud op een regelmatige basis om een goede werking te garanderen.

Applicatiesoftware Tebis

Technisch ontwerp positiebepaling Smart Blocks

Deel 1: Arduino kennismaking. Wat is een microcontroller, structuur van een programma, syntax,

Arduino. Arduino UNO. Sam Decoster. CoderDojo Roeselare. Sam Decoster

Labo digitale technieken

FAQ en HANDLEIDINGEN. MEER HANDLEIDINGEN: kijk op faq.koba-groep.com

SafeLine VV3. Bedieningsinstructies. Toont de verdiepingen, richtingspijlen en afwisselende tekstberichten.

GEBRUIKS AANWIJZING ZONWERINGS AUTOMAAT

FAQ en HANDLEIDINGEN. MEER HANDLEIDINGEN: kijk op faq.koba-groep.com

Repetitie Elektronica (versie A)

B3C 70cm converter besturing. v PE5PVB bar.net bar.net

Fysische Informatica met FLEC

Het Keypad (met segmenten)

Handleiding HCS VB5238

BDS-001, besturing voor handbediende schuifdeuren

Gebruiksaanwijzing TTA DEUR. Typenummer (meting per 0,1C)

Bouwbeschrijving UniSAI

Workshop Arduino Uno. Touw dag 6 juni 2015 Harold Pootjes en Simon Pauw

Antwoorden Systeembord Fysische informatica voor de onderbouw havo/vwo

1. WAT STAAT ER OP DE BORD HET LEERBORD TESTEN DE PC-VERBINDING TESTEN... 6

ONSCREENKEYS 5. Windows XP / Windows Vista / Windows 7 / Windows 8

SHINELINK Stappen installeren ShineLink Growatt HANDLEIDING. Installeren ShineLink

Hand-out Introductieworkshop LED programmeren

SHINELAN Stappen installeren ShineWiFi Growatt HANDLEIDING. Installeren ShineWiFi

2-KANAALS RF AFSTANDSBEDIENINGSSET

LocoServo Handleiding

1. PRODUCTAFBEELDING MET UITLEG: 3

Beschrijving JUBI-game. Inleiding

2.1 Deurbel krijgt spanning via batterijen Deurbel krijgt spanning via 12V 1A DC Montage van de deurbel aan de muur 6

Handleiding HCS VB5224

Handleiding HCS VB5248

1. PRODUCTAFBEELDING MET UITLEG: 3

IT&T tsc B.V. Programmeer Voorschrift IT&T Kwaliteitscentrale (VERSIE 2V) (VIALIS VARIANT)

OEFENINGEN. in de cursus 'PLC'

Positie-aflezing. - LED of LCD-aflezing - met geïntegreerde microprocessor. Walda Impuls b.v. Delta MS Arnhem Tel Fax

INSTALLATIE INSTRUCTIES 11/2017

fischertechnik is een geregistreerd handelsmerk van fischertechnik Gmbh. Weinhalde 14-18, D-72178, Waldachtal.

Besturingspaneel v Raam E-systeem functie omschrijving v109

Syncro AS. Analoge Brandmeldcentrale. Gebruikershandleiding. Man V1.0NL

Oefeningen Digitale Elektronica (I), deel 4

HOOFDSTUK 3. Imperatief programmeren. 3.1 Stapsgewijs programmeren. 3.2 If Then Else. Module 4 Programmeren

Seriële bluetooth verbinding ATmega128

7,6. Samenvatting door A woorden 12 april keer beoordeeld. Natuurkunde. Natuurkunde Systemen. Systemen

GEINTEGREERDE PROEF DE COMPUTER ALS TV AFSTANDSBEDIENING

Colofon. Trea Winter Joost van den Brink

Di-Control HANDLEIDING Di-Control versie: 2.6

Toets In2305-ii Embedded Programming Dinsdag 28 November 2006, 15:45-16:30

Basisoefeningen en uitwerkingen Systeembord. Opgaven en antwoorden op It s learning en agtijmensen.nl

Handleiding Alma Rally & Alma Rally Off-road

10 Meer over functies

Software beschrijving Epoluthon 2.0

Arduino Programmeer handleiding

Programmeerhandleiding Nelson Turf EZ Pro Jr. voor de types 8304, 8306, 8309, 8312, 8374, 8376, 8379, 8382

Turbo 240 gaat bewegingsonscherpte tegen

Accelerometer project 2010 Microcontroller printje op basis van de NXP-LPC2368

Wat is Arduino? Arduino = microprocessor (Atmel)

Debietdetector/ -melder. bij pneumatisch transport. Bedrijfsinstructies. Neue Technik. und Vertrieb

Transcriptie:

1.8 De generieke IO als ingang gebruiken 13 1.8 De generieke IO als ingang gebruiken De generieke IO kan ook gebruikt worden als ingang om signalen te lezen. Een basaal voorbeeld is een schakeling met een drukknop en een led. Als de drukknop ingedrukt wordt is de led aan en anders is de led uit. 3V3 10k Xmega6A3U RESET/PDI PA0 PDI PA7 PR0/XTAL PB0 PB7 3V3 0. µh PR1/XTAL1 PC0 PC1 PC PC3 PC4 PC PC6 PC7 1k De waarde van de condensator hangt af van de mate van contactdender. Iedere type drukknop heeft een ander gedrag. Er bestaan ook drukknoppen, die nauwelijks last van contactdender hebben. Figuur 1.1 : 3V3 1u AVCC VCC VCC VCC GND GND GND PD0 PD1 PD PD3 PD4 PD PD6 PD7 PE0 PE7 PF0 PF7 De schakeling voor het aan- en uitzetten van een led met een drukknop. De schakeling van figuur 1.1 is de schakeling uit figuur 1.1 met daaraan toegevoegd een drukknop aan pin 3 van poort D. De weerstand en de condensator zijn optioneel. De condensator is toegevoegd om contactdender te voorkomen. Dit kan hard- of softwarematig ook op andere manieren worden voorkomen. In paragraaf 1.10 wordt contactdender besproken. De weerstand zorgt er voor dat als de knop niet ingedrukt is, de ingang van de microcontroller hoog is. Als de knop ingedrukt wordt, wordt de ingang laag. De datastructuur voor de generieke IO, de struct PORT_t, bevat het ingangsregister IN. Iedere klokslag wordt de inhoud van de ingangsregisters ververst met de waarden die er op dat moment op de aansluitpinnen staan. In code 1.8 wordt op regel 4 aansluiting 3 van poort D expliciet gedefinieerd als ingang door bit 3 van het DIR-register van poort D laag te maken. Standaard zijn bij een reset alle bits van de registers laag. Zonder de toewijzing op regel 4 is deze aansluiting ook een ingang. 10k

14 Generieke IO Code 1.8 : Een led die de status van een drukknop weergeeft. 1 #include <avr/io.h> 3 int main(void) { 4 PORTD.DIRCLR = PIN3_bm; // input pin for button PORTC.DIRSET = PIN0_bm; // output pin for led 6 PORTC.OUTSET = PIN0_bm; // led on 7 8 while (1) { 9 if ( PORTD.IN & PIN3_bm ) { 10 PORTC.OUTCLR = PIN0_bm; // button not pressed, led off 11 } else { 1 PORTC.OUTSET = PIN0_bm; // button pressed, led on 13 } 14 } 1 } In de oneindige while-lus wordt op regel 9 getest of de ingang hoog is. Voor deze test wordt de bitsgewijze EN-functie en het bitmasker voor pin 3 gebruikt. 7 6 4 3 1 0 7 6 4 3 1 0 1 PORTD.IN 0 PORTD.IN 0 0 0 0 1 0 0 0 PIN3_bm 0 0 0 0 1 0 0 0 PIN3_bm 0 0 0 0 1 0 0 0 PORTD.IN & PIN3_bm 0 0 0 0 0 0 0 0 PORTD.IN & PIN3_bm is ongelijk aan 0, is dus waar is gelijk aan 0, is dus niet waar Figuur 1.13 : De test om te bepalen of bit 3 uit poort D hoog of laag is. Alle bits, die in het masker 0 zijn, worden bij de bewerking PORTD.IN & PIN3_bm eveneens 0. Afhankelijk van de waarde van bit 3 in PORTD.IN is de uitkomst gelijk of ongelijk aan 0. Figuur 1.13 laat zien dat de uitdrukking PORTD.IN & PIN3_bm waar is als de ingang hoog is en niet waar is als de ingang laag is. In het eerste geval is de drukknop niet ingedrukt. De uitgang is dan laag en de led is uit. De ingang is laag, zolang de drukknop ingedrukt wordt. De test is dan niet waar, zodat de toewijzing op regel 1 de uitgang hoog maakt en de led laat branden. 1.9 Het aan- en uitzetten van een led met een drukknop In code 1.8 gaat de led aan als de knop ingedrukt wordt en weer uit als de knop losgelaten wordt. Code 1.9 geeft een eerste aanzet van een programma dat de led laat aangaan als de knop wordt ingedrukt en weer laat uitgaat als er nogmaals op de knop wordt gedrukt. Als de knop ingedrukt wordt, is de ingang laag. Op regel 1 staat bij de testconditie een!, waardoor de conditie waar is als de knop ingedrukt wordt. Op regel 13 wordt het register OUTTGL gebruikt om de uitgangswaarde te laten omklappen of toggelen. De tijdvertraging op regel 14 zorgt ervoor dat de led na één keer indrukken niet blijft toggelen. Alleen als de knop langer dan 00 ms wordt vastgehouden blijft de led aan- en uitgaan.

1.10 Contactdender 1 Code 1.9 : Een eerste aanzet om een led aan en uit te zetten met een drukknop. 1 #define F_CPU 000000UL 3 #include <avr/io.h> 4 #include <util/delay.h> 6 int main(void) { 7 PORTD.DIRCLR = PIN3_bm; // input pin for button 8 PORTC.DIRSET = PIN0_bm; // output pin for led 9 PORTC.OUTCLR = PIN0_bm; // led off 10 11 while (1) { 1 if (! (PORTD.IN & PIN3_bm) ) { 13 PORTC.OUTTGL = PIN0_bm; // toggles led 14 _delay_ms(00); 1 } 16 } 17 } De oplossing uit code 1.9 is niet robuust. Als de schakelaar contactdender vertoont en er geen goede hardwarematige ontdenderschakeling wordt gebruikt, kan het gedrag van de schakelaar onvoorspelbaar worden. (V) 1 3 4 6 8 10 1 7 9 11 13 14 U 0 Figuur 1.14 : 0.0 0. 0.4 0.6 0.8 t (ms) De dender bij het indrukken van de drukknop. Het signaal gaat veertien keer van hoog naar laag voordat het definitief laag is geworden. 1.10 Contactdender De meeste schakelaars en drukknoppen produceren contactdender. Het contact wordt niet in één keer gemaakt of in één keer verbroken. Figuur 1.14 toont de dender (bouncing) bij een maakcontact. In dit voorbeeld gaat het signaal niet één keer maar veertien keer van hoog naar laag. Dender heeft een mechanische oorzaak. Het is niet te voorspellen of het optreedt en in welke mate. Elke schakelaar heeft een ander gedrag. Dender hangt af van allerlei externe factoren, zoals vuil en slijtage. Soms is de duur van de dender een paar tiende milliseconde en soms duurt het enige milliseconden.

16 Generieke IO Als het signaal een oneven aantal keer van hoog naar laag gaat, is dat hetzelfde als dat het één keer van hoog naar laag gaat. Het signaal van figuur 1.14 gaat een even aantal keer, namelijk veertien keer, van hoog naar laag. Dit betekent dat de led in een paar milliseconde tijd zeven keer aan en uit gaat. Het effect is dat er niets zichtbaars gebeurt. Bij dender lijkt het systeem soms wel en soms niet goed te reageren. 1.11 Hardwarematige antidendermaatregelen Dender (bouncing) kan met software en met hardware worden voorkomen. In de literatuur en op het internet zijn verschillende antidenderschakelingen te vinden. Deze zijn te groeperen in een paar fundamentele oplossingen. Soms wordt van het ingangssignaal een one-shot gemaakt, maar meestal wordt het signaal gefilterd. In de schakeling van figuur 1.1 is het ingangssignaal gefilterd door een condensator parallel bij de drukknop te plaatsen. 1 3 1 3 4 U U t Figuur 1.1 : t Het signaal van een drukknop met en zonder antidendercondensator. Het signaal zonder condensator is dun getekend en licht grijs. Het signaal met condensator is dik en zwart getekend. In de linker figuur wordt de drukknop ingedrukt. Zonder de condensator gaat het signaal denderen. Met de condensator wordt het signaal ook direct nul. Het stijgen van het signaal gaat vanwege de pullupweerstand veel langzamer, zodat alleen bij overgang 1 het signaal van hoog naar laag gaat. Bij de andere overgangen is het signaal nog niet hoog genoeg geworden. In de rechter figuur wordt de drukknop losgelaten. Het signaal met condensator zal langzaam stijgen, maar wordt door de dender telkens nul. Na de laatste dender stijgt het signaal wel door en is bij 4 de enige overgang van laag naar hoog. De schmitttrigger wordt besproken in bijlage F.9. Het effect van deze condensator is in figuur 1.1 te zien. Bij het indrukken van de knop wordt het signaal snel laag en bij dender gaat het langzaam omhoog. Er is nu maar een enkele overgang van hoog naar laag. Bij het loslaten van de knop wordt het signaal langzaam hoog en bij dender weer snel laag. Pas na de laatste opgaande flank wordt het signaal na enige tijd hoog. Omdat deze laatste overgang zo traag verloopt, is een schmitttrigger gewenst. In figuur 1.1 is geen schmitttrigger getekend, omdat er in de Xmega al een aanwezig is, zoals in figuur 1.3 te zien is. De waarde van de condensator hangt af van de waarde van de pullupweerstand en vooral van het soort schakelaar of drukknop dat gebruikt wordt. Meestal is een RC-tijd van 1 ms tot 10 ms een redelijke keuze. Voor een RC-tijd van 1 ms en een pullupweerstand van 10 kω is, moet de C minimaal 100 nf zijn.

1.1 Softwarematige antidendermaatregelen 17 In paragraaf 16.6 staat een voorbeeld van een antidenderalgoritme met een timer en een interrupt. Het voordeel van deze methode is dat het hoofdprogramma ontlast wordt en de tijdplanning (scheduling) veel eenvoudiger is. 1.1 Softwarematige antidendermaatregelen Dender (bouncing) is ook softwarematig te bestrijden. In de literatuur en op het internet zijn vele antidenderalgoritmen (debouncing algorithms) te vinden. Deze zijn te verdelen in twee soorten oplossingen: het ene type maakt gebruik van timers en interrupts en het andere gebruikt polling en vertragingsfuncties. Het aantrekkelijke van een softwarematige oplossing is dat er geen extra componenten nodig zijn, de PCB eenvoudiger is en het product goedkoper zal zijn. Als de interne pullupweerstand wordt gebruikt, kan de weerstand uit figuur 1.1 ook worden weggelaten. Code 1.10 : De functie button_pressed voor het uitlezen van een drukknop. 1 #define F_CPU 000000UL 3 #include <avr/io.h> 4 #include <util/delay.h> 6 #define DEBOUNCE_PERIOD_MS 10 7 #define LOCK_PERIOD_MS 00 8 9 int button_pressed(void) 10 { 11 if ( bit_is_clear(portd.in,pin3_bp) ) { 1 _delay_ms(debounce_period_ms); 13 if ( bit_is_clear(portd.in,pin3_bp) ) return 1; 14 } 1 16 return 0; 17 } 18 19 int main(void) 0 { 1 PORTD.DIRCLR = PIN3_bm; // input pin button PORTD.PIN3CTRL = PORT_OPC_PULLUP_gc; // enable pull up 3 PORTC.DIRSET = PIN0_bm; // output pin led 4 while (1) { 6 if ( button_pressed() ) { 7 PORTC.OUTTGL = PIN0_bm; // toggles output 8 _delay_ms(lock_period_ms); // lock input 9 } 30 } 31 } pin laag ja wacht 10 ms pin nog steeds laag ja return 1 nee nee return 0 Figuur 1.16 : Het antidenderalgoritme om de drukknop uit te lezen. Als de ingang na 10 ms nog steeds laag is, is de knop ingedrukt. In figuur 1.16 staat een antidenderalgoritme voor het uitlezen van een drukknop. Als de drukknop ingedrukt is, wordt er 10 ms gewacht. Mits deze tijd bij de knop past, zal het ingangssignaal stabiel zijn en geen dender meer vertonen. Als de pin dan nog steeds laag is, is de knop ingedrukt. De functie button_pressed uit het programma van code 1.10 is een implementatie van antidenderalgoritme uit figuur 1.16. Het programma hoort bij figuur 1.1 waarbij de pullupweerstand en de condensator niet nodig zijn.

18 Generieke IO Het hoofdprogramma checkt voortdurend met de functie button_pressed of de knop ingedrukt is. Als dat het geval is, verandert de status van de led en wacht het programma 0, seconde. Als deze vertragingstijd wordt weggelaten, knippert de led een aantal keer. Een gebruiker houdt een drukknop altijd een fractie van een seconde ingedrukt. Na 0, seconde zal de knop losgelaten zijn. Als de gebruiker de knop langer ingedrukt houdt, zal de led blijven knipperen. Uitleg code 1.10 regel 11 bit_is_clear() bit_is_set() Regel 11 PIN3_bp Regel PORTD.PIN3CTRL Regel PORTD.PIN3CTRL Op regel 11 en op regel 13 is de macrodefinitie bit_is_clear gebruikt. Deze macro samen met de macro bit_is_set is gedefinieerd in avr/sfr_defs.h. Dit headerbestand wordt automatisch ingesloten als avr/io.h wordt gebruikt. De macrodefinitie bit_is_set test of een bit hoog is en bit_is_clear test of een bit laag is. Deze macrodefinities hebben twee ingangsparameters sfr en bit: #define bit_is_clear(sfr, bit) (!(_SFR_BYTE(sfr) & _BV(bit))) #define bit_is_set(sfr, bit) ( (_SFR_BYTE(sfr) & _BV(bit))) Parameter sfr is de naam van het register en bit het nummer van de bit. De uitdrukking: bit_is_clear(portd.in,pin3_bp) is identiek met:! (PORTD.IN & PIN3_bm) Bij bit_is_clear en bit_is_set wordt het bitnummer (PIN0_bp) gebruikt en niet het bitmasker (PIN0_bm). De macro s PINn_bp zijn gedefinieerd in avr/io.h en representeren bitnummers of bitposities. De macro PIN3_bp komt overeen met de waarde 3. Verwar de bitpositie PIN3_bp niet met het bitmasker PIN3_bm, zie ook code 1.. Met het pincontrolregister kan een individuele pinaansluiting worden aangepast. PORTD.PIN3CTRL is het pincontrolregister van pin 3 van poort D. Figuur 1.17 toont de inhoud van dit register. SRLEN staat voor slew rate limit enable, hiermee wordt 7 6 4 3 1 0 SLREN INVEN OPC[:0] ISC[:0] Figuur 1.17 : Het pincontrolregister PINnCTRL. Regel PORT_OPC_PULLUP_gc de slew rate gelimiteerd. INVEN staat voor inverted i/o enable, hiermee wordt de polariteit van de in- of uitgang geïnverteerd. OPC staat voor output and pull configuration. Deze bits stellen onder andere de pullup- en pulldownschakeling van de generieke IO in. ISC staat voor input/sense configuration. Deze bits regelen de triggergevoeligheid van een ingang bij interrupts en events. De drie OPC-bits uit het PINnCTRL-register worden gebruikt om de aansluiting als wired-and of wired-or te configureren en om de pullup- en pulldownschakeling in te stellen. Tabel 1. geeft de verschillende instelmogelijkheden. In code 1.10 hebben de OPC-bits de waarde PORT_OPC_PULLUP_gc en heeft ingang 3 van poort D een interne pullupweerstand. Alternatief antidenderalgoritme dat altijd maar één keer reageert In code 1.10 is de ontdendertijd 10 ms en wacht het hoofdprogramma 0, s. De tijdvertragingen voor het ontdenderen en het wachten hangen sterk af van het type knop en van wat de applicatie moet doen. Als de knop langer dan 0, s wordt ingedrukt, wordt er opnieuw een druk op de knop geregistreerd. Dat

1.1 Softwarematige antidendermaatregelen 19 Tabel 1. : De uitgangs- en pullup/pulldown-configuratie. OPC[:0] groepsconfiguratie betekenis 000 PORT_OPC_TOTEM_gc normaal 001 PORT_OPC_BUSKEEPER_gc buskeeper 010 PORT_OPC_PULLDOWN_gc pulldown 011 PORT_OPC_PULLUP_gc pullup 100 PORT_OPC_WIREDOR_gc wired-or 101 PORT_OPC_WIREDAND_gc wired-and 110 PORT_OPC_WIREDORPULL_gc wired-or met pulldown 111 PORT_OPC_WIREDANDPULL_gc wired-and met pullup kan ongewenst zijn. Natuurlijk kan de wachttijd langer gemaakt worden, maar dan bestaat juist de kans dat een korte indruk van de knop gemist wordt. Bij een toetsenbord is het juist plezierig dat de aanslag voortdurend herhaald wordt zolang de toets ingedrukt blijft. pin laag ja wacht 10 ms pin laag nee return 1 nee return 0 ja Code 1.11 : Alternatief voor uitlezen drukknop. Deze functie button_pressed detecteert dat de drukknop losgelaten wordt. 9 int button_pressed(void) 10 { 11 if ( bit_is_clear(portd.in,pin3_bp) ) { 1 _delay_ms(debounce_period_ms); 13 while ( bit_is_clear(portd.in,pin3_bp) ) ; 14 return 1; 1 } 16 return 0; 17 } Figuur 1.18 : Het antidenderalgoritme dat wacht op het loslaten van de drukknop. Een alternatief is om de functie button_pressed te laten wachten totdat de drukknop losgelaten wordt. Het algoritme voor deze methode staat in figuur 1.18 en de alternatieve functie button_pressed staat in code 1.11. Het enige verschil met de functie uit code 1.10 is dat de if op regel 6 vervangen is door een while. Het nadeel van de functie button_pressed uit code 1.11 is dat het programma in de functie blijft hangen zolang de gebruiker de knop ingedrukt houdt. Zeker bij programma s met een ingewikkelde tijdplanning (scheduling) kan dat er toe leiden dat het programma niet goed zal functioneren. Alternatieve functie button_pressed met parameters De functies button_pressed uit code 1.10 en code 1.11 werken alleen bij de aansluiting 3 van poort D. Voor een andere aansluiting moeten de functies worden aangepast. In code 1.1 staat een functie button_pressed met twee parameters: een pointer p die naar de poort wijst en een integer bit voor het bitnummer.

0 Generieke IO Code 1.1 : De functie button_pressed met parameters. 1 #define F_CPU 000000UL 3 #include <avr/io.h> 4 #include <util/delay.h> 6 #define LOCK_PERIOD_MS 00 7 8 int button_pressed(port_t *p, uint8_t bit) 9 { 10 if ( bit_is_clear(p->in, bit) ) { 11 _delay_ms(10); 1 loop_until_bit_is_set(p->in, bit); 13 return 1; 14 } 1 return 0; 16 } 17 18 int main(void) { 19 PORTD.DIRCLR = PIN3_bm; // input pin button 0 PORTD.PIN3CTRL = PORT_OPC_PULLUP_gc; // enable pull up 1 PORTC.DIRSET = PIN0_bm; // output pin led 3 while (1) { 4 if ( button_pressed(&portd, PIN3_bp) ) { PORTC.OUTTGL = PIN0_bm; // toggles output 6 _delay_ms(lock_period_ms); // lock input 7 } 8 } 9 } Om de betreffende poort te benaderen moet aan de functie het adres van de poort worden meegegeven. Pointer p wijst daarom naar het adres van een datastructuur PORT_t. Bij de aanroep van button_pressed op regel 4 staat voor de variabele PORTD de adresoperator &, zodat het adres van PORTD aan de functie wordt meegegeven. In de functie is p een pointer naar de registers van de poort. Het scheidingsteken tussen het veld en een pointer naar een datastructuur is een pijltje ->. Het ingangsregister IN van de poort wordt op regel 10 en regel 1 daarom gevonden met p->in. Op regel 1 is in plaats van een while de macrodefinitie loop_until_bit_is_set gebruikt. Het headerbestand sfr_defs.h bevat naast de definities bit_is_clear en bit_is_set nog twee macro s loop_until_bit_is_clear en loop_until_bit_is_set. Deze macro s wachten totdat de bit in het register respectievelijk laag is en hoog is. De uitdrukking: loop_until_bit_is_set(p->in, bit); is identiek met: while ( ( bit_is_clear(p->in, bit) ) ; Bij de Xmega-stijl op basis van datastructuren is het maken van algemene functies met parameters, zoals de functie button_pressed in code 1.1, relatief eenvoudig.