in Elettronica, Embedded Logs, Informatica, Uncategorized

Embedded Logs – From scratch pt.2: Progettare una semplice scheda con un AVR ATMega

I microcontrollori della serie ATMega fanno parte della famiglia 8-bit megaAVR, basati su architettura AVR, e sono tra i più utilizzati nel mondo dell’hobbistica, per la semplicità di utilizzo e l’ampio supporto a livello di strumentazione.

Continuiamo il progetto iniziato nel precedente articolo che trovate sempre qui su antima.it, procedendo con la fase di progettazione della scheda prototipale.

Come anticipato precedentemente userò un ATMega644, dato che, come molti altri membri della famiglia megaAVR, è disponibile in un package through hole, che lo rende particolarmente semplice da utilizzare con una batteria 9V.

I componenti

  • 1 ATMEGA644-20PU (64kB Flash, 2kB EEPROM, 32 I/O Pins)
  • 1 zoccolo DIP 40-pin con passo a 2.54mm
  • 1 programmatore/debugger ATMEL-ICE
  • 1 batteria 9V ed un connettore a clip
  • 1 Regolatore di tensione L7805 con uscita a 5V
  • Dei condensatori ceramici da 0,1 μF e 0,33 μF
  • Un paio di led e resistenze

Facoltativamente:

  • 1 cristallo di quarzo da 16 MHz
  • Dei condensatori da utilizzare con il quarzo (12-22 pF)

La documentazione

Tutti i componenti necessari per creare la scheda basata su atmega 644

 

Qui di seguito il circuito finale che utilizzeremo come riferimento:

Lo schematico del progetto, con tutti i collegamenti da effettuare con l'atmega

L’alimentazione

L’ATMega644 accetta un’alimentazione in un range tra i 2,7V ed i 5,5V, come molti degli altri microcontrollori ATMega (eccetto quelli con part number che terminano per ‘V’). Inoltre, nel caso in cui volessimo utilizzare il microcontrollore con una frequenza di funzionamento tra i 10 ed i 20MHz, dovremo fornire un’alimentazione nel range tra i 4,5 ed i 5,5V.

Poniamoci in quest’ultimo caso, così da avere la possibilità di far funzionare il tutto a 16MHz nel caso volessimo. Per potere fornire l’alimentazione con valore di tensione corretta partendo da una batteria 9V, ho usato un regolatore di tensione L7805CV della STMicroelectronics.

Consultando il datasheet linkato ad inizio articolo, è possibile notare che questo regolatore accetta ingressi a 7-18V ed offre un’uscita a 5V; sempre al suo interno, è inoltre possibile trovare lo schema elettrico utilizzabile per metterlo in funzione, che riporto qui sotto:

Il circuito di alimentazione usato su atmega 644

Connettendo la batteria al circuito riportato, avremo un’uscita a circa 5V, che possiamo testare connettendo una resistenza in uscita al circuito e misurando con un multimetro. Possiamo utilizzare le uscite del circuito di alimentazione per alimentare il nostro microcontrollore, come mostrato nello schematico iniziale.

Da notare quanto viene effettuato per i pin AVCC ed AREF, che vengono rispettivamente connessi a VCC e GND, con l’aggiunta di un condensatore tra AREF e GND. Questa configurazione è quella consigliata dal datasheet nel caso di utilizzo dell’ADC con tensione di riferimento interna (l’ATMega644 offre un riferimento interno a 1,1V o 2,56V).

Connettere l’ATMEL-ICE via JTAG

Per potere programmare il microcontrollore, possiamo sfruttare l’interfaccia JTAG dell’ATMega tramite l’ATMEL-ICE, che rende possibile interfacciarsi con una moltitudine di micro AVR ed ARM Cortex-M della linea SAM. Il programmatore ha due connettori nell’estremità inferiore del suo involucro esterno, uno con su scritto SAM ed uno con su scritto AVR: dovremo sempre connettere i flat cable al connettore AVR per interfacciarci con l’ATMega.

Prendendo lo squid-cable incluso nel kit del programmatore, è possibile notare come ogni cavetto abbia un numero stampato su, dove il cavo numero 1 è quello di colore rosso. Qui di seguito riporto lo schema da seguire per connettere il cavo in uscita dal programmatore con i pin del microcontrollore.

I pin a cui fare attenzione per quanto riguarda l’interfaccia JTAG dell’ATMega sono PC2 (TCK), PC3 (TMS), PC4 (TDO), PC5 (TDI).

L'interfaccia jtag del microcontrollore

A questo punto si può procedere con un veloce test per capire se la comunicazione con il microcontrollere avviene con successo.

Una volta connesso il programmatore, e connessa la pila per alimentare l’ATMega, dovremmo potere interfacciarci con il chip tramite l’utilizzo di avrdude, una delle applicazioni installate nel primo articolo di questa serie.

Dopo aver connesso l’ATMEL-ICE tramite USB al computer, si può utilizzare avrdude aprendo un’istanza di terminale, eseguendo:

avrdude -c atmelice -p atmega644 

L’applicazione dovrebbe rispondere con delle informazioni, tra cui la signature del device ed i valori dei fuse.

Il corretto output di avrdudecusando il chip atmega 644

Qui sotto allego una foto del risultato ottenuto seguendo i passi precedenti; ho aggiunto un led blu nella sezione in basso a sinistra della basetta per avere un feedback sul corretto funzionamento dell’alimentazione.

Il progetto completo, su breadboard

Fuse bits

I chip ATMega contengono un’area di memoria con dei bit di stato speciali, utilizzati per impostare alcune caratteristiche peculiari del controllore. Questi bit si dividono in tre byte chiamati fuse bytes: low, high ed extended.

Eseguendo il comando specificato nel paragragfo precedente, è possibile recuperare i valori dei fuse byte attualmente programmati. N.B. programmare erroneamente questi valori può potenzialmente mettere fuori uso il microcontrollore, fate attenzione!

I valori di default per l’ATmega644 sono i seguenti:

Low High Extended
0x62 0x99 0xFF

Utilizzare un oscillatore esterno

L’ATMega offre un oscillatore RC interno ad 8 MHz che, nella configurazione di base, è prescalato ad 1 MHz. Nel caso in cui si voglia utilizzare un’altra configurazione, bisognerà prima modificare alcuni valori dei fuse byte.

Le configurazioni esatte possono essere reperite dal datasheet del componente; in combinazione con questo documento, un sito molto utile che uso spesso per confermare i valori ottenuti è Fuse Calculator.

AVR® Fuse Calculator

Ad esempio, quando utilizzo l’ATMEL-ICE, tendo a disabilitare la programmazione via SPI, ed ad utilizzare un cristallo di quarzo con frequenza di 16MHz come segnale di clock.

In questo caso, la configurazione che utilizzo è la seguente:

Low High Extended
0xFF 0xB1 0xFF

Che può essere caricata sempre tramite avrdude:

avrdude -c atmelice -p atmega644 -U lfuse:w:0xff:m -U hfuse:w:0xb1:m -U efuse:w:0xff:m

Il circuito da utilizzare per usare il cristallo a 16MHz è riportato qui di seguito, ed è contenuto nel datasheet del chip. Bisogna sempre fare attenzione a seguire quanto contenuto all’interno del datasheet: in questo caso il valore dei condensatori è da scegliere nel range di 12-22 pF, ed entrambi i condensatori devono avere lo stesso valore.

Il circuito oscillatore

Interagire con il microcontrollore

A questo punto tutto è pronto per scrivere un primo programma, per confermare che tutto funziona alla perfezione.

Apriamo il progetto clonato nello scorso articolo, stando attenti a modificare il valore della frequenza del clock all’interno del file CMakeLists.txt (o del Makefile se state usando make).

Nel caso in cui le impostazioni legate al clock siano state mantenute intatte dai valori di fabbrica, staremo per usare un clock con frequenza ad un 1Mhz:

set(CLOCK_FREQ "1000000")

Nel caso in cui il clock sia stato settato a 16MHz con oscillatore esterno:

set(CLOCK_FREQ "16000000")

Blink

Per testare il funzionamento del setup, propongo un classico e semplicissimo hello-world basato sul lampeggiare un led con una frequenza di circa 1 Hz. Il led in questione va connesso al pin PA0, in serie con una resistenza.

Se avete seguito l’articolo precedente, potete incollare quanto riportato di seguito nel file main.c.

Altrimenti, il tutto è disponibile sul nostro github al seguente indirizzo: @github/antima/avr-blink. N.B. in questa repo il progetto è stato configurato per funzionare con un ATMega644 con frequenza di clock a 1MHz, utilizzando un atmelice come programmatore.

Apriamo il file main.c ed incolliamo il seguente codice al suo interno:

#include <avr/io.h>
#include <util/delay.h>

#define LED_PIN 0

int main(void) {
  DDRA = 1 << LED_PIN;
  PORTA = 0 << LED_PIN;
  for(;;) {
    PORTA ^= (1 << LED_PIN);
    _delay_ms(1000);
  }
}

Una volta fatto ciò, basterà eseguire :

mkdir build && cd build
cmake .. -B . -DCMAKE_BUILD_TYPE=Release
cd build/
make
make flash

Il risultato atteso è il seguente:

Conclusioni

La nostra piccola e semplice scheda funziona alla perfezione, ora è il momento di sfruttare quanto fatto per creare delle applicazioni complesse. Nei prossimi articoli esploreremo insieme l’utilizzo delle varie periferiche dell’ATMega, e di come debuggare un applicazione scritta in C per microcontrollori.

Per questo articolo è tutto, per eventuali approfondimenti o chiarimenti vi invito come al solito a commentare nella sezione qui sotto!

Scrivi un commento

Commento