Cuprins:

Microcontroler AVR. Comutați LED-urile folosind un comutator cu buton. Dezactivarea butonului: 4 pași
Microcontroler AVR. Comutați LED-urile folosind un comutator cu buton. Dezactivarea butonului: 4 pași

Video: Microcontroler AVR. Comutați LED-urile folosind un comutator cu buton. Dezactivarea butonului: 4 pași

Video: Microcontroler AVR. Comutați LED-urile folosind un comutator cu buton. Dezactivarea butonului: 4 pași
Video: Exemplu aprindere led folosind PIC16F877 2024, Iulie
Anonim
Image
Image

În această secțiune, vom învăța Cum se face codul programului C pentru ATMega328PU pentru a comuta starea celor trei LED-uri în funcție de intrarea de la un buton. De asemenea, am explorat o soluție la problema „Switch Bounce”. Ca de obicei, vom asambla circuitul electric pe baza AVR ATmega328 pentru a verifica funcționarea codului programului.

Pasul 1: Scrierea și construirea aplicației de microcontroler AVR în cod C folosind platforma de dezvoltare integrată Atmel Studio 7

Scrierea și construirea aplicației de microcontroler AVR în cod C folosind platforma de dezvoltare integrată Atmel Studio 7
Scrierea și construirea aplicației de microcontroler AVR în cod C folosind platforma de dezvoltare integrată Atmel Studio 7
Scrierea și construirea aplicației de microcontroler AVR în cod C folosind platforma de dezvoltare integrată Atmel Studio 7
Scrierea și construirea aplicației de microcontroler AVR în cod C folosind platforma de dezvoltare integrată Atmel Studio 7
Scrierea și construirea aplicației de microcontroler AVR în cod C folosind platforma de dezvoltare integrată Atmel Studio 7
Scrierea și construirea aplicației de microcontroler AVR în cod C folosind platforma de dezvoltare integrată Atmel Studio 7

Dacă nu aveți Atmel Studio, ar trebui să îl descărcați și să îl instalați.

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

Primele câteva linii pe care le definim de un compilator.

F_CPU definește frecvența ceasului în Hertz și este comună în programele care utilizează biblioteca avr-libc. În acest caz, este utilizat de rutinele de întârziere pentru a determina modul de calcul al întârzierilor.

#ifndef F_CPU

#define F_CPU 16000000UL // indicând frecvența cristalului (16 MHz AVR ATMega328P) #endif

#include // header pentru a permite controlul fluxului de date peste pini. Definește pini, porturi etc.

Primul fișier include include avr-libc și va fi folosit în aproape orice proiect AVR la care lucrați. io.h va determina procesorul pe care îl utilizați (motiv pentru care specificați partea la compilare) și, la rândul său, includeți antetul de definiție IO adecvat pentru cipul pe care îl folosim. Pur și simplu definește constantele pentru toți pinii, porturile, registrele speciale etc.

#include // header pentru a activa funcția de întârziere în program

Biblioteca util / delay.h conține câteva rutine pentru întârzieri scurte. Funcția pe care o vom folosi este _delay_ms ().

Folosim definiții pentru a declara butonul și porturile și pinii LED-urilor. Folosirea unor astfel de afirmații ne permite să avem nevoie să modificăm 3 linii ușor de găsit doar dacă mutăm LED-ul pe un alt pin I / O sau dacă folosim un AVR diferit.

#define BUTTON1 1 // buton comutator conectat la portul B pin 1

#define LED1 0 // Led1 conectat la portul B pin 0 #define LED2 1 // Led2 conectat la portul C pin 1 #define LED3 2 // Led3 conectat la portul D pin 2

Ultimele două definesc orele de configurare a instrucțiunilor, în milisecunde, pentru a elimina comutatorul și timpul de așteptare înainte de a permite o altă apăsare a butonului. Timpul de retragere trebuie să fie ajustat la timpul necesar pentru a trece de la un nivel maxim digital la un nivel digital, după toate săriturile. Comportamentul de respingere va diferi de la comutator la comutator, dar 20-30 de milisecunde este de obicei suficient.

#define DEBOUNCE_TIME 25 // timpul de așteptare în timp ce butonul „de-bouncing”

#define LOCK_INPUT_TIME 300 // timpul de așteptare după apăsarea unui buton

void init_ports_mcu ()

{

Această funcție este numită o singură dată la începutul programului nostru pentru a inițializa pinii de ieșire de intrare pe care îi vom folosi.

Pentru buton, vom folosi registrele PORT și PIN pentru scriere și citire. Cu AVR-uri, citim un pin folosind registrul PINx și scriem un pin folosind registrul PORTx. Trebuie să scriem în registrul de butoane pentru a activa extragerile.

Pentru LED trebuie să folosim doar registrul PORT pentru a scrie, totuși, avem nevoie și de registrul de direcție a datelor (DDR), deoarece pinii I / O sunt configurați ca intrări în mod implicit.

Mai întâi, setăm pinii I / O ai LED-ului ca ieșire folosind registrul său de direcție de date.

DDRB = 0xFFu; // Setați toți pinii PORTB ca ieșire.

Apoi, setați în mod explicit pinul butonului ca intrare.

DDRB & = ~ (1 <

Apoi, pinii PORTB sunt setați la înălțime (+5 volți) pentru a-l activa. Pinii de ieșire sunt inițial mari și, din moment ce LED-ul nostru este cablat activ-înalt, acesta va fi pornit dacă nu îl oprim în mod explicit.

Și, în cele din urmă, activăm rezistența de tragere internă pe pinul de intrare pe care îl folosim pentru butonul nostru. Acest lucru se face pur și simplu prin trimiterea unuia în port. Când este configurat ca intrare, acest lucru duce la activarea pull-up-urilor și atunci când este configurat ca o ieșire, acest lucru ar genera pur și simplu o tensiune înaltă.

PORTB = 0xFF; // Setați toți pinii PORTB ca HIGH. Ledul este pornit, //, de asemenea, este activat rezistorul Pull Up intern al primului pin PORTB. DDRC = 0xFFu; // Setați toți pinii PORTC ca ieșire. PORTC = 0x00u; // Setați toți pinii PORTC jos, ceea ce îl oprește. DDRD = 0xFFu; // Setați toți pinii PORTD ca ieșire. PORTD = 0x00u; // Setați toți pinii PORTD la nivel scăzut, ceea ce îl oprește. }

caracter nesemnat button_state ()

{

Această funcție returnează o valoare booleană care indică dacă butonul a fost sau nu apăsat. Acesta este blocul de cod cu care se execută continuu în bucla infinită și, prin urmare, sondează starea butonului. Acesta este, de asemenea, locul în care dezacordăm comutatorul.

Acum, amintiți-vă că atunci când apăsăm comutatorul, pinul de ieșire de intrare este tras la sol. Astfel, așteptăm ca pinul să scadă.

/ * butonul este apăsat când butonul BUTTON1 bit este liber * /

if (! (PINB & (1 <

O facem verificând dacă bitul este clar. Dacă bitul este clar, indicând faptul că butonul este apăsat, mai întâi amânăm pentru perioada de timp definită de DEBOUNCE_TIME care este de 25 ms și apoi verificăm din nou starea butonului. Dacă butonul este apăsat după 25 ms, atunci comutatorul este considerat a fi dezactivat și gata să declanșeze un eveniment și astfel revenim la 1 la rutina noastră de apelare. Dacă butonul nu este apăsat, returnăm 0 la rutina de apelare.

_delay_ms (DEBOUNCE_TIME);

if (! (PINB & (1 <

int main (nul)

{

Rutina noastră principală. Funcția principală este unică și separată de toate celelalte funcții. Fiecare program C trebuie să aibă exact o funcție main (). principal este locul în care AVR începe să-ți execute codul atunci când pornește pentru prima dată, deci este punctul de intrare al programului.

unsigned char n_led = 1; // inițial numărul LED-ului este aprins acum

Apelul funcției de inițializare a pinilor I / O utilizați:

init_ports_mcu ();

buclă infinită unde rulează programul nostru:

în timp ce (1)

{

Când button_state returnează unul care indică faptul că butonul a fost apăsat și respins, apoi comutarea la rândul său a stării curente a LED-urilor în funcție de parametrul n_led.

if (button_state ()) // Dacă butonul este apăsat, comutați starea LED-ului și întârziați 300ms (#define LOCK_INPUT_TIME)

{switch (n_led) {case 1: PORTB ^ = (1 << LED1); PORTC ^ = (1 << LED2); pauză;

Aceste declarații utilizează operatori C bit-bit. De data aceasta folosește operatorul exclusiv SAU. Când XOR PORT cu valoarea bitului pe care doriți să îl comutați, acel bit este schimbat fără a afecta celelalte biți.

cazul 2:

PORTC ^ = (1 << LED2); PORTD ^ = (1 << LED3); pauză; caz 3: PORTD ^ = (1 << LED3); PORTB ^ = (1 << LED1); n_led = 0; // resetează LED break break; } n_led ++; // următorul LED este pornit _delay_ms (LOCK_INPUT_TIME); }} return (0); }

Deci, acum, când rulați acest program, ar trebui să puteți apăsa butonul pentru a comuta LED-urile. Datorită întârzierii definite de LOCK_INPUT_TIME, puteți apăsa și menține apăsat butonul care va face ca LED-urile să se stingă și să se aprindă la o rată constantă (puțin mai mult de fiecare 275 ms).

Programarea este completă.

Următorul pas este construirea proiectului și programarea fișierului hex în microcontroler folosind programul avrdude.

Puteți descărca fișierul main.c cu programul în codul c:

Pasul 2: Transferul fișierului HEX al programului în memoria flash a cipului

Transferul fișierului HEX al programului în memoria flash a cipului
Transferul fișierului HEX al programului în memoria flash a cipului
Transferarea fișierului HEX al programului în memoria flash a cipului
Transferarea fișierului HEX al programului în memoria flash a cipului

Descărcați și instalați AVRDUDE. Cea mai recentă versiune disponibilă este 6.3: Descărcați fișierul zip

Mai întâi, copiați fișierul hexagonal al programului în directorul AVRDUDE. În cazul meu este ButtonAVR.hex

Apoi, tastați în fereastra de prompt DOS comanda: avrdude –c [numele programatorului -p m328p –u –U flash: w: [numele fișierului dvs. hex].

În cazul meu este: avrdude –c ISPProgv1 –p m328p –u –U flash: w: ButtonAVR.hex

Această comandă scrie un fișier hexagonal în memoria microcontrolerului.

Urmăriți videoclipul cu o descriere detaliată a arderii memoriei flash a microcontrolerului:

Microcontroler de memorie flash în curs de ardere …

Bine! Acum, microcontrolerul funcționează în conformitate cu instrucțiunile programului nostru. Hai să verificăm!

Pasul 3: Dezactivarea comutatorului hardware

Deconectarea comutatorului hardware
Deconectarea comutatorului hardware

În plus față de debouncing-ul de comutare software, putem utiliza tehnica de comutare a comutatorului hardware. Ideea de bază din spatele unei astfel de tehnici este de a utiliza un condensator pentru a filtra schimbările rapide ale semnalului de comutare.

Ce valoare condensator ar trebui să fie selectat? Acest lucru va depinde în cele din urmă de cât de slab funcționează butonul cu privire la această problemă specială. Unele butoane pot afișa un comportament de respingere extraordinar, dar altele vor avea foarte puțin. O valoare scăzută a condensatorului, cum ar fi 1,0 nanofarade, va reacționa foarte repede, cu un efect redus sau deloc asupra saltului. Dimpotrivă, o valoare mai mare a condensatorului, cum ar fi 220 nanofarade (care este încă destul de mică în ceea ce privește condensatorii) va oferi o tranziție lentă de la tensiunea de pornire la tensiunea finală (5 volți la 0 volți). Tranziția văzută cu o capacitate de 220 nanofarade este încă destul de rapidă în sensul real, totuși, și astfel poate fi utilizată pe butoane cu performanțe slabe.

Pasul 4: Circuit electric

Circuit electric
Circuit electric
Circuit electric
Circuit electric
Circuit electric
Circuit electric

Conectați componentele în conformitate cu diagrama schematică.

Recomandat: