Sommario:

Interruttori di lettura con ATtiny2313: 9 passaggi
Interruttori di lettura con ATtiny2313: 9 passaggi

Video: Interruttori di lettura con ATtiny2313: 9 passaggi

Video: Interruttori di lettura con ATtiny2313: 9 passaggi
Video: Domestic System DEMOnstration with an Atmel Microcontroller 2024, Luglio
Anonim
Interruttori di lettura con ATtiny2313
Interruttori di lettura con ATtiny2313

Ci sono stati diversi Instructables che si occupano delle uscite dall'ATtiny2313 e da dispositivi AVR simili. Ad esempio, https://www.instructables.com/id/Ghetto-Programming%3a-Getting-started-with-AVR-micro/, https://www.instructables.com/id/Drive-a-Stepper- Motore-con-un-microprocessore-AVR/. Lavorando sull'ultimo di The Real Elliot, che mostrava come controllare i motori passo-passo, ho scoperto che sarebbe stato davvero utile essere in grado di eseguire sezioni di codice alternative nello stesso programma in modo da non dover riprogrammare l'ATtiny2313 ciascuno volta ho voluto provare una leggera variazione del codice (come il mezzo passo o l'esecuzione dello stepper al contrario). Sebbene sia facile scrivere codice utilizzando un'istruzione switch/case per consentire la selezione di varianti alternative, è necessario un modo per selezionare il caso. Ciò significa che è necessario leggere una sorta di dispositivo di input per controllare il caso. Fortunatamente, l'ATtiny2313 ha molti pin I/O ed è ben progettato per leggere gli input dagli switch. Questo Instructable mostrerà come leggere gli input e prendere decisioni in base al loro stato. Dal momento che questo da solo renderebbe un Instructable piuttosto noioso, spiegherò un modo semplice di utilizzare la capacità di timer/contatore dell'ATtiny2313 per pilotare un piccolo altoparlante come segnale acustico. Ci sarà anche una piccola digressione sulle semplici tecniche di debugging.

Passaggio 1: il dispositivo di input

Il dispositivo di input
Il dispositivo di input
Il dispositivo di input
Il dispositivo di input

Questo Instructable si basa sull'eccellente lavoro di The Real Elliot e utilizza il sistema di sviluppo ATtiny2313 Ghetto che descrive. La scheda tecnica ATtiny2313 di Atmel è il riferimento definitivo per tutte le funzioni, ma non è necessariamente facile da leggere. https://www.atmel.com/dyn/products/datasheets.asp?family_id=607 (Link ha tutte le schede tecniche dell'AVR, individuare il 2313.) La figura mostra un semplice set di interruttori di ingresso. Questo è semplicemente un pacchetto di quattro interruttori on/off; noto anche come interruttori unipolari a una via (SPST). Tipicamente, una connessione, o polo, di ogni interruttore è collegata a terra mentre l'altra connessione è tirata in alto attraverso un resistore di limitazione di corrente (10K o giù di lì). Un ingresso del microcontrollore è collegato al polo con la resistenza. Se l'interruttore è aperto, il microcontrollore leggerà l'ingresso come HI. Se l'interruttore è chiuso, il microcontrollore leggerà l'ingresso LO. Fare riferimento allo schema per i dettagli. L'ATtiny2313 semplifica le cose fornendo resistori di pull-up programmabili sui pin I/O quando sono configurati come ingressi. Ciò significa che gli interruttori possono semplicemente avere un polo collegato a terra (LO) e l'altro polo collegato a un ingresso del processore. Il primo esempio mostra solo due interruttori. Gli interruttori vengono letti e configurati con il seguente codice. Configurare gli interruttori come ingressi: (nessun codice richiesto; questo è l'impostazione predefinita). Attivare i resistori di pull-up: PORTB = _BV(PB0) | _BV(PB1);Leggi gli ingressi: but1 = ~PINB & 0x03; Nota l'uso dell'inversione e del mascheramento per ottenere il valore corretto.

Passaggio 2: lampeggianti per un segnale

Useremo questi due interruttori per far lampeggiare un LED un numero programmabile di volte. I LED che utilizzeremo saranno i lampeggianti resi famosi da The Real Elliot. Gli interruttori 1 e 2 saranno trattati come due cifre binarie, quindi la combinazione può rappresentare i numeri 0, 1, 2 e 3. Il nostro programma leggerà i due interruttori e lampeggerà il LED il numero appropriato di volte, ma solo se l'interruttore le impostazioni sono cambiate. Gli interruttori vengono antirimbalzati per 500 millisecondi (non ottimizzati). L'algoritmo di antirimbalzo è piuttosto semplice. Gli interruttori vengono letti e la lettura viene annotata. Se è diverso dal valore oldBut (l'ultimo valore salvato), il programma viene ritardato di 500 millisecondi e gli interruttori vengono letti di nuovo. Se il valore è lo stesso letto in precedenza, il valore di oldBut verrà aggiornato e il LED lampeggerà il numero di volte implicato dal valore binario dei due interruttori. Notare l'inversione del valore poiché un interruttore che è "on" legge LO. Gli interruttori verranno scansionati continuamente per ulteriori modifiche. Fare riferimento a Instructables precedenti di The Real Elliot per saperne di più sui lampeggianti. Dai un'occhiata a questo https://www.ganssle.com/debouncing.pdf per saperne di più sugli interruttori antirimbalzo. Ecco il codice ATtiny2313 per questo esempio. In funzione, questo programma farà lampeggiare il LED su PB4 (pin fisico 8) due volte per mostrare che è inizializzato. Quindi leggerà gli interruttori uno e due e lampeggerà da una a tre volte a seconda dell'impostazione dell'interruttore ogni volta che vengono modificati. Quando gli interruttori non cambiano, il LED lampeggerà lentamente. Per eseguire questo codice, crea una nuova directory (chiamala "Basic" se vuoi) e scarica il seguente file di codice C e makefile al suo interno. Rinomina Makefile1.txt solo in Makefile. Usando WinAVR, compila il programma e caricalo nel tuo ATtiny2313.

Passaggio 3: una piccola digressione sul debug

Se sei come me (e ogni altro programmatore al mondo) probabilmente hai sperimentato momenti in cui il codice "senza errori" che hai accuratamente digitato e compilato non fa quello che ti aspetti che faccia. Forse semplicemente non fa nulla! Allora, qual'è il problema? Come lo scoprirai? Fortunatamente, ci sono diversi approcci per far funzionare le cose. (Procurati questo libro per una trattazione eccellente dell'argomento del debug. https://www.debuggingrules.com/) Vorrei offrire alcuni semplici suggerimenti relativi all'argomento del debug di applicazioni per microcontrollori. Il primo passo è costruire su cosa sai. Se hai fatto funzionare un lampeggiante una volta, usalo di nuovo per vedere dove ti trovi nel tuo programma. Mi piace che il LED lampeggi due volte per segnalare l'inizio del programma. Puoi inserire il codice per farlo inizialmente all'inizio del programma. Una volta che sai che non c'è niente di sbagliato nel tuo hardware, crea una funzione per fare il lampeggio. Ecco la funzione che uso./*------------------------------------------ ----------------** blinkEm - funzione per lampeggiare LED tramite PD4** PD4 deve essere configurato come uscita. ** ------------------------------------------------ ---------------------*/void blinkEm(uint8_t count){ while (count > 0){ PORTD = _BV(PD4); _delay_ms(1000); PORTAD = ~_BV(PD4); _delay_ms(1000); contare--; }}Ora è possibile utilizzare questa funzione in vari punti del codice come segnale che il codice è stato eseguito fino a quel punto. Sapere che il codice è in esecuzione significa che puoi esaminare attentamente ogni sezione che è stata eseguita, ma non come previsto, per trovare errori. Cambiare una cosa alla volta è una tecnica chiave anche per il debug (descritto nel riferimento sopra). Questo metodo classico funziona insieme al "divide et impera": fare piccoli passi per aggiungere funzionalità in modo incrementale. Questo può sembrare un approccio lento, ma non è così lento come provare a eseguire il debug di un'ampia sezione di codice non funzionante tutto in una volta.

Passaggio 4: più debug

Ci sono molte volte in cui vogliamo controllare una sezione di codice saltando la maggior parte delle righe in essa contenute, quindi abilitandole una alla volta mentre verifichiamo che ognuna funzioni. In genere, lo facciamo "commentando" le righe che vogliamo saltare. Un'estensione di questa tecnica consiste nel tagliare e incollare un blocco di codice, commentare l'originale (in modo da non perderlo) e modificare la copia. C ha quattro semplici modi per commentare le righe. Mettere "//" davanti a una riga commenta quella riga. Racchiudere una o più righe tra "/*" e "*/" commenterà un'intera sezione. Affinché questo metodo funzioni in modo efficace, non devono esserci altri "*/" nel blocco di codice (a parte quello finale). Quindi una disciplina efficace consiste nell'usare // per i commenti all'interno di blocchi di codice e riservare il costrutto /* */ per i blocchi di commento e per commentare le sezioni di codice. Posizionando "#if 0" all'inizio di un blocco per commentare e terminare la sezione con "#endif". Un controllo più selettivo è possibile utilizzando "#ifdef (identificatore)" all'inizio di un blocco e "#endif" alla fine. Se vuoi che il blocco venga compilato, usa "#define (identificatore)" in precedenza nel programma. Nota che le virgolette sono solo a scopo di enfasi e non devono essere incluse. La combinazione di queste tecniche dovrebbe fornire un approccio utile per il debug dei programmi ATtiny2313. Potresti trovare utili questi strumenti mentre procediamo attraverso questo Instructable.

Passaggio 5: utilizzo del timer/contatore 0 per i segnali acustici

Utilizzo del timer/contatore 0 per i segnali acustici
Utilizzo del timer/contatore 0 per i segnali acustici

L'ATtiny2313 dispone di due potenti risorse timer/contatore: una a 8 bit e una a 16 bit. Questi possono essere configurati come generatori di frequenza, controller di modulazione a larghezza di impulso variabile e registri di confronto delle uscite. La piena funzionalità di questi è descritta in 49 pagine della scheda tecnica. Tuttavia, useremo un caso semplice. Verrà utilizzato solo il Timer/Contatore 0 (quello a 8 bit) e verrà utilizzato semplicemente come generatore di frequenza. La frequenza verrà indirizzata a un piccolo altoparlante per produrre un segnale acustico. Timer/Contatore 0 è completamente descritto nelle pagine da 66 a 83 della scheda tecnica ATtiny2313. Una lettura attenta di questo materiale fornirà una comprensione completa di Tempo/Contatore 0. Fortunatamente, una modalità abbastanza semplice, Clear Timer on Compare (CTC), è tutto ciò che è necessario per generare il segnale acustico che vogliamo.

Per la modalità che utilizzeremo, il funzionamento del timer/contatore è semplice. Quando viene selezionato un segnale di clock, il contatore parte da zero e incrementa ogni impulso di clock. Quando il valore del contatore raggiunge il valore nell'Output Compare Register (TOP), il contatore si azzera e il conteggio ricomincia. Il bit di uscita associato al timer/contatore viene commutato per produrre un'uscita ad onda quadra. Questo guida direttamente un trasduttore audio per emettere un segnale acustico. Un piccolo trasduttore audio TDK emette il segnale acustico. Un'unità adatta è Digikey 445-2530-ND, TDK SD1209T3-A1 (ne ho usato una versione precedente). Questa è una versione da 3 volt; anche la versione a 5 volt funzionerà, mi aspetto. Lo guido direttamente dalla porta di uscita dell'Attiny2313 e sembra funzionare bene. Sparkfun ha un dispositivo simile.

Passaggio 6: configurazione del timer/contatore 0

La modalità CTC può essere utilizzata per commutare l'uscita OC0A sul pin 2, porta B (pin fisico 14). Per abilitare l'uscita su questo pin, DDRB deve essere impostato in modo appropriato. Il codice C per questo è proprio come impostare un'uscita per un lampeggiante. DDRB = _BV(PB2); // La porta B2 è un'uscita. Il passaggio successivo consiste nel fornire un segnale di clock e caricare il registro di confronto dell'uscita per produrre una forma d'onda come frequenza. L'equazione per la frequenza risultante è riportata nella scheda tecnica (pagina 72). I termini nell'equazione saranno descritti di seguito. Ecco l'equazione: fOC0A = fclk_I/O / 2*N*(1+OCR0A)Dove fOC0A:= frequenza di uscita fclk_I/O:= frequenza sorgente di clock N:= fattore di prescala del clock OCR0A:= valore nel registro di confronto dell'uscita per Timer/ Counter 0A. Clock Source Frequency, fclk_I/OQuesta è la frequenza del clock di sistema. Il valore predefinito è 1MHz. I bit CS00, CS01 e CS02 di TCCR0B controllano questa selezione. Poiché questi bit selezionano anche il valore di N, viene descritto di seguito. Valore di prescaler, NN è il valore utilizzato per dividere, o prescalare, l'orologio di sistema. I bit CS00, CS01 e CS02 di TCCR0B controllano questa selezione. La tabella 41 a pagina 81 della scheda tecnica ATtiny2313 descrive le combinazioni. Poiché si desidera una frequenza vicina a 1kHz, verranno impostati i bit CS00 e CS01 di TCCR0B. Si noti che l'impostazione di tutti e tre i bit su 0, selezionando quindi nessuna sorgente di clock, interrompe effettivamente l'output. Questo è il metodo che verrà utilizzato per avviare e interrompere il segnale acustico. Valore TOP, OCR0AQuesto valore è il valore TOP per il contatore che viene caricato nel registro di confronto uscita per Timer/Contatore 0A. Al raggiungimento di questo valore il contatore verrà azzerato e il conteggio ricomincerà fino al raggiungimento del TOP e il ciclo si ripeterà. TOP è facilmente modificabile, quindi la frequenza del segnale acustico è facile da cambiare. Poiché si desidera una frequenza vicina a 1kHz, TOP è impostato su 7. (Notare che il prescaler avrebbe potuto essere impostato su 8 e TOP impostato su 63. Stesso risultato - a tua scelta.) Frequenza di uscita, fOC0AUtilizzo dell'equazione per calcolare i risultati della frequenza di uscita in: fOC0A = 1, 000, 000 / 2 * 64 * (1+7) fOC0A = 977 Hz Abbastanza vicino! Ecco il codice per caricare il registro di confronto delle uscite e il registro di controllo del contatore timer 0B. Si prega di consultare il codice del programma effettivo per capire come vengono utilizzati. OCR0A = 7; // Valore temporale TCCR0B = _BV(CS01) | _BV(CS00); // Seleziona il clock interno & prescale=8 TCCR0B = 0; // nessuna sorgente di clock disattiva il tonoImpostazione della modalità Time/Counter Come ultimo dettaglio, specificheremo la modalità Timer/Counter che desideriamo impostando i bit appropriati nel registro di controllo Timer/Counter 0A. La modalità CTC viene selezionata impostando il bit WGM01 come descritto nella Tabella 40, pagina 79 della scheda tecnica. Poiché si vuole che l'uscita commuti ogni ciclo, anche il bit COM0A0 deve essere impostato come descritto nella Tabella 34 a pagina 77. Ecco il codice: TCCR0A = _BV(COM0A0) | _BV(WGM01); // CTC Commuta modalità

Passaggio 7: utilizzo di quattro interruttori

Mentre implementiamo il segnale acustico, estendiamo il nostro hardware e software per gestire quattro interruttori. Poiché l'output del Timer Counter 0A è sulla porta B, pin 2, non possiamo semplicemente collegare più interruttori in sequenza alla porta B. Una soluzione semplice sarebbe usare la porta D, ma manteniamo quella porta disponibile per altre funzioni (forse un motore passo-passo). Quindi colleghiamo gli interruttori aggiuntivi a PB3 e PB4. La lettura degli interruttori è per lo più invariata. Il valore della maschera viene modificato in 0x1B (00011011 binario) per mascherare il bit 2 insieme a 5, 6 e 7. Un ulteriore trucco viene utilizzato per creare un numero binario a 4 bit. Sposta i bit 3 e 4 a destra di un bit e combinali con i bit 0 e 1 in un numero binario a 4 bit. Questa è la sintassi C standard per lo spostamento e la combinazione di bit, ma potrebbe non essere ben nota ai principianti. ma1a = (ma1 & 0x03) | ((ma1 & 0x18) >> 1); // ma1 ha la lettura dell'interruttore In funzione, il programma lampeggerà due volte e emetterà due segnali acustici per segnalare l'inizializzazione. Ogni volta che gli interruttori vengono modificati, il numero che rappresentano verrà emesso un segnale acustico. Quando gli interruttori non cambiano, il LED lampeggerà. Per eseguire questo codice, crea una nuova directory (chiamala Beep se vuoi) e scarica il seguente file di codice C e makefile al suo interno. Rinomina Makefile2.txt solo in Makefile. Usando WinAVR, compila il programma e caricalo nel tuo Attiny2313.

Passaggio 8: utilizzo del costrutto switch/case

Il passaggio finale è "solo software": come promesso, implementeremo il costrutto switch/case. Sebbene questo esempio mostri solo due azioni alternative, dovrebbe essere molto chiaro come utilizzare questo costrutto per selezionare una delle numerose sezioni di codice alternative. In funzione, questo programma controlla gli interruttori e se c'è un cambiamento, emetterà un segnale acustico il numero appropriato se è dispari; lampeggerà se il numero è pari. Non fa nulla a meno che non cambi un interruttore.

Per eseguire questo codice, crea una nuova directory (chiamala Switch se vuoi) e scarica il seguente file di codice C e makefile al suo interno. Rinomina Makefile3.txt solo in Makefile. Usando WinAVR, compila il programma e caricalo nel tuo Attiny2313.

Passaggio 9: conclusione

Conclusione
Conclusione

Quindi è così! Ora sai come usare gli interruttori per controllare l'esecuzione del tuo programma leggendoli e selezionando un'azione in base all'impostazione dell'interruttore. Sai anche come creare un segnale acustico e hai anche imparato alcune strategie di debug.

Se desideri testare la tua comprensione, prova a modificare l'ultimo programma in modo che emetta un segnale acustico acuto se pari, emette un segnale acustico basso se dispari e lampeggia continuamente il LED se non ci sono cambiamenti negli interruttori. Potresti voler guardare torna alla sezione sul debug per chiedere aiuto.

Consigliato: