Sommario:

Microcontrollore AVR. Attiva/disattiva i LED utilizzando un interruttore a pulsante. Pulsante antirimbalzo: 4 passaggi
Microcontrollore AVR. Attiva/disattiva i LED utilizzando un interruttore a pulsante. Pulsante antirimbalzo: 4 passaggi

Video: Microcontrollore AVR. Attiva/disattiva i LED utilizzando un interruttore a pulsante. Pulsante antirimbalzo: 4 passaggi

Video: Microcontrollore AVR. Attiva/disattiva i LED utilizzando un interruttore a pulsante. Pulsante antirimbalzo: 4 passaggi
Video: AVR Microcontroller. Toggle LED’s using a Push Button Switch. Push Button Debouncing. 2024, Novembre
Anonim
Image
Image

In questa sezione, impareremo come creare il codice C del programma per ATMega328PU per alternare lo stato dei tre LED in base all'input da un interruttore a pulsante. Inoltre, abbiamo esplorato una soluzione al problema di "Switch Bounce". Come di consueto, assembleremo il circuito elettrico sulla base dell'AVR ATmega328 per verificare il funzionamento del codice del programma.

Passaggio 1: scrittura e creazione di applicazioni per microcontrollori AVR in codice C utilizzando la piattaforma di sviluppo integrata Atmel Studio 7

Scrittura e creazione di applicazioni per microcontrollori AVR in codice C utilizzando la piattaforma di sviluppo integrata Atmel Studio 7
Scrittura e creazione di applicazioni per microcontrollori AVR in codice C utilizzando la piattaforma di sviluppo integrata Atmel Studio 7
Scrittura e creazione di applicazioni per microcontrollori AVR in codice C utilizzando la piattaforma di sviluppo integrata Atmel Studio 7
Scrittura e creazione di applicazioni per microcontrollori AVR in codice C utilizzando la piattaforma di sviluppo integrata Atmel Studio 7
Scrittura e creazione di applicazioni per microcontrollori AVR in codice C utilizzando la piattaforma di sviluppo integrata Atmel Studio 7
Scrittura e creazione di applicazioni per microcontrollori AVR in codice C utilizzando la piattaforma di sviluppo integrata Atmel Studio 7

Se non hai Atmel Studio, dovresti scaricarlo e installarlo.

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

Le prime righe che abbiamo definito dal compilatore.

F_CPU definisce la frequenza di clock in Hertz ed è comune nei programmi che utilizzano la libreria avr-libc. In questo caso viene utilizzato dalle routine di ritardo per determinare come calcolare i ritardi.

#ifndef F_CPU

#define F_CPU 16000000UL // indica la frequenza del cristallo del controller (16 MHz AVR ATMega328P) #endif

#include // header per abilitare il controllo del flusso di dati sui pin. Definisce pin, porte, ecc.

Il primo file di inclusione fa parte di avr-libc e verrà utilizzato praticamente in qualsiasi progetto AVR su cui lavori. io.h determinerà la CPU che stai utilizzando (motivo per cui specifichi la parte durante la compilazione) e a sua volta includerà l'intestazione di definizione IO appropriata per il chip che stiamo utilizzando. Definisce semplicemente le costanti per tutti i tuoi pin, porte, registri speciali, ecc.

#include // header per abilitare la funzione di ritardo nel programma

La libreria util/delay.h contiene alcune routine per brevi ritardi. La funzione che useremo è _delay_ms().

Usiamo defines per dichiarare il nostro pulsante e le porte e i pin dei LED. L'utilizzo delle istruzioni defines come questa ci consente di modificare solo 3 linee facili da trovare se spostiamo il LED su un pin I/O diverso o utilizziamo un AVR diverso.

#define BUTTON1 1 // interruttore a pulsante collegato al pin 1 della porta B

#define LED1 0 // Led1 connesso alla porta B pin 0 #define LED2 1 // Led2 connesso alla porta C pin 1 #define LED3 2 // Led3 connesso alla porta D pin 2

Le ultime due istruzioni definiscono i tempi di impostazione, in millisecondi, per l'antirimbalzo dell'interruttore e il tempo di attesa prima di consentire un'altra pressione del pulsante. Il tempo di antirimbalzo deve essere regolato in base al tempo impiegato dall'interruttore per passare da un massimo digitale a un minimo digitale dopo tutto il rimbalzo. Il comportamento di rimbalzo sarà diverso da interruttore a interruttore, ma in genere 20-30 millisecondi sono sufficienti.

#define DEBOUNCE_TIME 25 // tempo di attesa per il pulsante "de-bouncing"

#define LOCK_INPUT_TIME 300 // tempo di attesa dopo la pressione di un pulsante

void init_ports_mcu()

{

Questa funzione viene chiamata solo una volta all'inizio del nostro programma per inizializzare i pin di output di input che utilizzeremo.

Per il pulsante, utilizzeremo i registri PORT e PIN per la scrittura e la lettura. Con gli AVR, leggiamo un pin usando il suo registro PINx e scriviamo su un pin usando il suo registro PORTx. Dobbiamo scrivere nel registro dei pulsanti per abilitare i pull-up.

Per il LED abbiamo solo bisogno di usare il registro PORT su cui scrivere, tuttavia, abbiamo anche bisogno del registro di direzione dei dati (DDR) poiché i pin I/O sono impostati come input per impostazione predefinita.

Innanzitutto, impostiamo i pin I/O del LED come uscita utilizzando il registro di direzione dei dati.

DDRB=0xFFu; // Imposta tutti i pin della PORTB come output.

Quindi, imposta esplicitamente il pin del pulsante come input.

DDRB &= ~(1<

Successivamente, i pin PORTB sono impostati su alti (+5 volt) per accenderlo. I pin di uscita sono inizialmente alti e, poiché il nostro LED è cablato active-high, verrà acceso a meno che non lo disattiviamo esplicitamente.

Infine, abilitiamo la resistenza di pull-up interna sul pin di input che stiamo usando per il nostro pulsante. Questo viene fatto semplicemente inviandone uno alla porta. Quando è configurato come ingresso, ciò comporta l'abilitazione dei pull-up e, quando configurato come uscita, ciò produrrebbe semplicemente un'alta tensione.

PORTAB = 0xFF; // Imposta tutti i pin di PORTB come HIGH. Il led è acceso, // è abilitato anche il resistore Pull Up interno del primo pin PORTB. DDRC=0xFFu; // Imposta tutti i pin del PORTC come output. PORTC=0x00u; // Imposta tutti i pin di PORTC bassi che lo disattivano. DDRD=0xFFu; // Imposta tutti i pin del PORTD come output. PORTD=0x00u; // Imposta tutti i pin di PORTD bassi che lo disattivano. }

unsigned char button_state()

{

Questa funzione restituisce un valore booleano che indica se il pulsante è stato premuto o meno. Questo è il blocco di codice con cui viene continuamente eseguito nel ciclo infinito e quindi interroga lo stato del pulsante. Questo è anche il punto in cui antirimbalziamo l'interruttore.

Ora, ricorda che quando premiamo l'interruttore, il pin di output di input viene messo a terra. Quindi, stiamo aspettando che il pin si abbassi.

/* il pulsante viene premuto quando il bit BUTTON1 è azzerato */

if (!(PINB & (1<

Lo facciamo controllando se il bit è chiaro. Se il bit è azzerato, indicando che il pulsante è premuto, prima ritardiamo per il tempo definito da DEBOUNCE_TIME che è 25ms e poi ricontrolliamo lo stato del pulsante. Se il pulsante viene premuto dopo i 25 ms, l'interruttore viene considerato antirimbalzo e pronto per attivare un evento e quindi torniamo 1 alla nostra routine di chiamata. Se il pulsante non viene premuto, torniamo 0 alla nostra routine di chiamata.

_delay_ms(DEBOUNCE_TIME);

if (!(PINB & (1<

int principale (vuoto)

{

La nostra routine principale. La funzione principale è unica e si distingue da tutte le altre funzioni. Ogni programma C deve avere esattamente una funzione main(). main è il punto in cui l'AVR inizia a eseguire il codice quando si accende per la prima volta, quindi è il punto di ingresso del programma.

carattere non firmato n_led = 1; // inizialmente il numero LED è acceso ora

Richiamo della funzione per inizializzare i pin di I/O in uso:

init_ports_mcu();

ciclo infinito in cui viene eseguito il nostro programma:

mentre (1)

{

Quando button_state restituisce uno che indica che il pulsante è stato premuto e antirimbalzo, quindi alternando lo stato corrente dei LED in base al parametro n_led.

if (button_state()) // Se il pulsante viene premuto, alterna lo stato del LED e il ritardo per 300 ms (#define LOCK_INPUT_TIME)

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

Queste istruzioni utilizzano operatori C bit per bit. Questa volta utilizza l'operatore OR esclusivo. Quando si esegue l'XOR della PORT con il valore del bit che si desidera commutare, quel bit viene modificato senza influenzare gli altri bit.

caso 2:

PORTC ^= (1<<LED2); PORTD ^= (1<<LED3); rottura; caso 3: PORTD ^= (1<<LED3); PORTAB ^= (1<<LED1); n_led=0; // resetta l'interruzione del numero del LED; } n_led++; // il LED successivo è acceso _delay_ms(LOCK_INPUT_TIME); } } restituisce (0); }

Quindi ora, quando esegui questo programma, dovresti essere in grado di premere il pulsante per far accendere i LED. A causa del nostro ritardo definito da LOCK_INPUT_TIME, puoi tenere premuto il pulsante che farà accendere e spegnere i LED a una velocità costante (poco più di ogni 275 ms).

La programmazione è completa.

Il prossimo passo è costruire il progetto e programmare il file esadecimale nel microcontrollore usando il programma avrdude.

Puoi scaricare il file main.c con il programma in codice c:

Passaggio 2: trasferimento del file HEX del programma nella memoria flash del chip

Trasferimento del file HEX del programma nella memoria flash del chip
Trasferimento del file HEX del programma nella memoria flash del chip
Trasferimento del file HEX del programma nella memoria flash del chip
Trasferimento del file HEX del programma nella memoria flash del chip

Scarica e installa AVRDUDE. L'ultima versione disponibile è la 6.3: scarica il file zip

Innanzitutto, copia il file esadecimale del programma nella directory AVRDUDE. Nel mio caso è ButtonAVR.hex

Quindi, digitare nella finestra del prompt di DOS il comando: avrdude –c [nome del programmatore] –p m328p –u –U flash:w:[nome del file esadecimale].

Nel mio caso è: avrdude –c ISPProgv1 –p m328p –u –U flash:w:ButtonAVR.hex

Questo comando scrive il file esadecimale nella memoria del microcontrollore.

Guarda il video con una descrizione dettagliata della masterizzazione della memoria flash del microcontrollore:

Masterizzazione della memoria flash del microcontrollore…

Ok! Ora, il microcontrollore funziona secondo le istruzioni del nostro programma. Controlliamolo!

Passaggio 3: antirimbalzo dell'interruttore hardware

Interruttore hardware antirimbalzo
Interruttore hardware antirimbalzo

Oltre all'antirimbalzo dell'interruttore software, possiamo utilizzare la tecnica dell'antirimbalzo dell'interruttore hardware. L'idea alla base di tale tecnica è quella di utilizzare un condensatore per filtrare i rapidi cambiamenti nel segnale dell'interruttore.

Quale condensatore di valore dovrebbe essere selezionato? Ciò dipenderà in definitiva da quanto male si comporta il pulsante riguardo a questo particolare problema. Alcuni pulsanti possono mostrare un tremendo comportamento di rimbalzo, mentre altri ne avranno molto poco. Un valore basso del condensatore come 1,0 nanofarad reagirà molto rapidamente, con poco o nessun effetto sul rimbalzo. Al contrario, un valore del condensatore più alto come 220 nanofarad (che è ancora piuttosto piccolo in termini di condensatori) fornirà una transizione lenta dalla tensione iniziale a quella finale (da 5 volt a 0 volt). Tuttavia, la transizione vista con una capacità di 220 nanofarad è ancora piuttosto veloce in senso reale, e quindi può essere utilizzata su pulsanti con prestazioni scadenti.

Passaggio 4: circuito elettrico

Circuito elettrico
Circuito elettrico
Circuito elettrico
Circuito elettrico
Circuito elettrico
Circuito elettrico

Collegare i componenti secondo il diagramma schematico.

Consigliato: