Inhoudsopgave:

AVR-microcontroller. Schakel LED's met behulp van een drukknopschakelaar. Debouncen met drukknop: 4 stappen
AVR-microcontroller. Schakel LED's met behulp van een drukknopschakelaar. Debouncen met drukknop: 4 stappen

Video: AVR-microcontroller. Schakel LED's met behulp van een drukknopschakelaar. Debouncen met drukknop: 4 stappen

Video: AVR-microcontroller. Schakel LED's met behulp van een drukknopschakelaar. Debouncen met drukknop: 4 stappen
Video: Светильник на адресных LED, для подсветки, уведомлений и аварийного освещения. ESP32 и WLED 2024, Juli-
Anonim
Image
Image

In deze sectie zullen we leren hoe we programma C-code voor ATMega328PU kunnen maken om de status van de drie LED's te wisselen volgens de invoer van een knopschakelaar. We hebben ook een oplossing onderzocht voor het probleem van 'Switch Bounce'. Zoals gewoonlijk zullen we het elektrische circuit monteren op de basis van de AVR ATmega328 om het werk van de programmacode te controleren.

Stap 1: AVR-microcontrollertoepassing schrijven en bouwen in C-code met behulp van het geïntegreerde ontwikkelplatform Atmel Studio 7

AVR-microcontrollertoepassing schrijven en bouwen in C-code met behulp van het geïntegreerde ontwikkelplatform Atmel Studio 7
AVR-microcontrollertoepassing schrijven en bouwen in C-code met behulp van het geïntegreerde ontwikkelplatform Atmel Studio 7
AVR-microcontrollertoepassing schrijven en bouwen in C-code met behulp van het geïntegreerde ontwikkelplatform Atmel Studio 7
AVR-microcontrollertoepassing schrijven en bouwen in C-code met behulp van het geïntegreerde ontwikkelplatform Atmel Studio 7
AVR-microcontrollertoepassing schrijven en bouwen in C-code met behulp van het geïntegreerde ontwikkelplatform Atmel Studio 7
AVR-microcontrollertoepassing schrijven en bouwen in C-code met behulp van het geïntegreerde ontwikkelplatform Atmel Studio 7

Als je Atmel Studio niet hebt, moet je het downloaden en installeren.

www.microchip.com/mplab/avr-support/atmel-studio-7

De eerste paar regels hebben we een aantal compiler-definities.

F_CPU definieert de klokfrequentie in Hertz en is gebruikelijk in programma's die de avr-libc-bibliotheek gebruiken. In dit geval wordt het gebruikt door de vertragingsroutines om te bepalen hoe tijdvertragingen moeten worden berekend.

#ifndef F_CPU

#define F_CPU 16000000UL // vertellende controller kristalfrequentie (16 MHz AVR ATMega328P) #endif

#include // header om gegevensstroomcontrole over pinnen in te schakelen. Definieert pinnen, poorten, enz.

Het eerste include-bestand maakt deel uit van avr-libc en wordt gebruikt in vrijwel elk AVR-project waaraan u werkt. io.h bepaalt de CPU die je gebruikt (daarom specificeer je het onderdeel bij het compileren) en neemt op zijn beurt de juiste IO-definitieheader op voor de chip die we gebruiken. Het definieert eenvoudig de constanten voor al uw pinnen, poorten, speciale registers, enz.

#include // header om de vertragingsfunctie in het programma in te schakelen

De bibliotheek util/delay.h bevat enkele routines voor korte vertragingen. De functie die we gaan gebruiken, is _delay_ms().

We gebruiken definities om de poorten en pinnen van onze knop en LED's aan te geven. Door gebruik te maken van de definities zoals deze, hoeven we slechts 3 gemakkelijk te vinden regels aan te passen als we de LED naar een andere I/O-pin verplaatsen of een andere AVR gebruiken.

#define BUTTON1 1 // knopschakelaar aangesloten op poort B pin 1

#define LED1 0 // Led1 aangesloten op poort B pin 0 #define LED2 1 // Led2 aangesloten op poort C pin 1 #define LED3 2 // Led3 aangesloten op poort D pin 2

De laatste twee definiëren de instellingstijden van de instructies, in milliseconden, om de schakelaar te debouncen en de tijd die moet worden gewacht voordat opnieuw op de knop wordt gedrukt. De debounce-tijd moet worden aangepast aan de tijd die de switch nodig heeft om van een digitaal hoog naar een digitaal laag te gaan na al het stuiteren. Het bounce-gedrag verschilt van switch tot switch, maar 20-30 milliseconden is meestal voldoende.

#define DEBOUNCE_TIME 25 // tijd om te wachten terwijl de knop "ontstuiteren"

#define LOCK_INPUT_TIME 300 // tijd om te wachten na een druk op de knop

ongeldig init_ports_mcu()

{

Deze functie wordt aan het begin van ons programma slechts één keer aangeroepen om de invoer-uitvoerpinnen die we gaan gebruiken te initialiseren.

Voor de knop gebruiken we de PORT- en PIN-registers voor schrijven en lezen. Met AVR's lezen we een pincode met behulp van het PINx-register en schrijven we naar een pincode met behulp van het PORTx-register. We moeten naar het knopregister schrijven om de pull-ups in te schakelen.

Voor de LED hoeven we alleen het PORT-register te gebruiken om naar te schrijven, maar we hebben ook het data direction register (DDR) nodig omdat de I/O-pinnen standaard als ingangen zijn ingesteld.

Eerst stellen we de I/O-pinnen van de LED in als een uitgang met behulp van het gegevensrichtingsregister.

DDRB=0xFFu; // Stel alle pinnen van de PORTB in als uitvoer.

Stel vervolgens de knoppen expliciet in als invoer.

DDRB &= ~(1<

Vervolgens worden de PORTB-pinnen hoog gezet (+5 volt) om hem aan te zetten. De uitgangspinnen zijn aanvankelijk hoog en aangezien onze LED actief-hoog is bedraad, wordt deze ingeschakeld tenzij we deze expliciet uitschakelen.

En tot slot schakelen we de interne pull-up-weerstand in op de ingangspin die we gebruiken voor onze knop. Dit wordt eenvoudig gedaan door een één naar de poort te sturen. Wanneer geconfigureerd als een ingang, resulteert dit in het inschakelen van pull-ups en wanneer geconfigureerd als een uitgang, zou dit eenvoudigweg een hoge spanning afgeven.

POORTB = 0xFF; // Stel alle pinnen van de PORTB in op HOOG. Led is ingeschakeld, // ook de interne Pull Up-weerstand van de eerste pin PORTB is ingeschakeld. DDRC=0xFFu; // Stel alle pinnen van de PORTC in als uitvoer. PORTC=0x00u; // Stel alle pinnen van PORTC laag in, waardoor het wordt uitgeschakeld. DDRD=0xFFu; // Stel alle pinnen van de PORTD in als uitvoer. POORT=0x00u; // Stel alle pinnen van PORTD laag in, waardoor het wordt uitgeschakeld. }

unsigned char button_state()

{

Deze functie retourneert een booleaanse waarde die aangeeft of de knop al dan niet is ingedrukt. Dit is het codeblok dat voortdurend wordt uitgevoerd in de oneindige lus en dus de status van de knop opvraagt. Dit is ook waar we de schakelaar debouncen.

Onthoud nu dat wanneer we op de schakelaar drukken, de ingangsuitgangspin naar de grond wordt getrokken. We wachten dus tot de pin laag gaat.

/* de knop wordt ingedrukt wanneer BUTTON1 bit leeg is */

als (!(pincode & (1<

Dit doen we door te controleren of het bit helder is. Als het bit helder is, wat aangeeft dat de knop is ingedrukt, stellen we eerst de tijd uit die is gedefinieerd door DEBOUNCE_TIME, wat 25 ms is, en controleren vervolgens de status van de knop opnieuw. Als de knop na de 25 ms wordt ingedrukt, wordt de schakelaar beschouwd als debounced en klaar om een gebeurtenis te activeren en dus keren we terug naar onze belroutine. Als de knop niet wordt ingedrukt, keren we terug naar onze belroutine.

_delay_ms(DEBOUNCE_TIME);

als (!(pincode & (1<

int hoofd (void)

{

Onze belangrijkste routine. De hoofdfunctie is uniek en onderscheidt zich van alle andere functies. Elk C-programma moet precies één main()-functie hebben. main is waar de AVR begint met het uitvoeren van uw code wanneer de stroom voor het eerst wordt ingeschakeld, dus het is het startpunt van het programma.

niet-ondertekende char n_led = 1; // aanvankelijk is het LED-nummer nu aan

Aanroep van de functie om gebruikte I/O-pinnen te initialiseren:

init_ports_mcu();

oneindige lus waar ons programma draait:

terwijl (1)

{

Wanneer button_state er een retourneert die aangeeft dat de knop is ingedrukt en debounced, dan schakelt de huidige status van LED's beurtelings volgens de n_led parameter.

if (button_state()) // Als de knop wordt ingedrukt, schakelt u de status en vertraging van de LED in voor 300ms (#define LOCK_INPUT_TIME)

{switch(n_led){ geval 1: PORTB ^= (1<<LED1); PORTC ^= (1<<LED2); pauze;

Deze instructies maken gebruik van C bitsgewijze operatoren. Deze keer gebruikt het de exclusieve OR-operator. Wanneer u XOR de POORT XOR met de bitwaarde van het bit dat u wilt wisselen, wordt dat ene bit gewijzigd zonder de andere bits te beïnvloeden.

geval 2:

PORTC ^= (1<<LED2); POORT ^= (1<<LED3); pauze; geval 3: PORTD ^= (1<<LED3); POORTB ^= (1<<LED1); n_led=0; // reset LED nummer pauze; } n_led++; // volgende LED is ingeschakeld _delay_ms (LOCK_INPUT_TIME); } } retour (0); }

Dus nu, wanneer u dit programma uitvoert, zou u op de drukknop moeten kunnen drukken om de LED's te laten wisselen. Vanwege onze vertraging gedefinieerd door LOCK_INPUT_TIME, kunt u de knop ingedrukt houden waardoor de LED's met een constante snelheid (iets meer dan elke 275 ms) aan en uit gaan.

De programmering is voltooid.

De volgende stap is het bouwen van het project en het programmeren van het hex-bestand in de microcontroller met behulp van het avrdude-programma.

U kunt het main.c-bestand downloaden met programma in c-code:

Stap 2: Het HEX-bestand van het programma overbrengen naar het flashgeheugen van de chip

Het HEX-bestand van het programma overbrengen naar het flashgeheugen van de chip
Het HEX-bestand van het programma overbrengen naar het flashgeheugen van de chip
Het HEX-bestand van het programma overbrengen naar het flashgeheugen van de chip
Het HEX-bestand van het programma overbrengen naar het flashgeheugen van de chip

Download en installeer AVRDUDE. De nieuwste beschikbare versie is 6.3: Download het zip-bestand

Kopieer eerst het hex-bestand van het programma naar de AVRDUDE-directory. In mijn geval is het ButtonAVR.hex

Typ vervolgens in het DOS-promptvenster het commando: avrdude –c [naam van programmeur] –p m328p –u –U flash:w:[naam van uw hex-bestand].

In mijn geval is het: avrdude –c ISPProgv1 –p m328p –u –U flash:w:ButtonAVR.hex

Deze opdracht schrijft een hex-bestand naar het geheugen van de microcontroller.

Bekijk de video met een gedetailleerde beschrijving van het branden van flashgeheugen van de microcontroller:

Microcontroller-flashgeheugen branden…

OK! Nu werkt de microcontroller volgens de instructies van ons programma. Laten we het bekijken!

Stap 3: Debouncen van hardwareschakelaar

Debouncen hardwareschakelaar
Debouncen hardwareschakelaar

Naast software switch debouncen kunnen we hardware switch debouncing techniek gebruiken. Het basisidee achter een dergelijke techniek is om een condensator te gebruiken om snelle veranderingen in het schakelsignaal uit te filteren.

Welke waarde condensator moet worden geselecteerd? Dit zal uiteindelijk afhangen van hoe slecht de knop presteert met betrekking tot dit specifieke probleem. Sommige knoppen kunnen een enorm stuitergedrag vertonen, maar andere zullen heel weinig hebben. Een lage condensatorwaarde zoals 1,0 nanofarads zal zeer snel reageren, met weinig of geen effect op het stuiteren. Omgekeerd zal een hogere condensatorwaarde zoals 220 nanofarads (wat nog vrij klein is qua condensatoren) zorgen voor een langzame overgang van de start- naar de eindspanning (5 volt naar 0 volt). De overgang die wordt gezien met een capaciteit van 220 nanofarads is echter nog steeds behoorlijk snel in de praktijk en kan dus worden gebruikt op slecht presterende knoppen.

Stap 4: Elektrisch circuit

Electronisch circuit
Electronisch circuit
Electronisch circuit
Electronisch circuit
Electronisch circuit
Electronisch circuit

Componenten aansluiten volgens schema.

Aanbevolen: