PrettyPrint

mercoledì 11 agosto 2010

Timer AVR in 5min: 3) VMLAB e linux

< Timer AVR in 5min: 2) Il modo CTC Timer AVR in 5min: 4) Generare forme d'onda con CTC >




Ultima revisione: 26/Apr/2012 


timer1.zip


VMLAB è un software di simulazione di micro (AVR e ST62) per Windows, completamente gratuito, che si appoggia su WinAVR (l'ambiente di sviluppo gratuito per AVR su Windows).

La sua peculiarità è quella di avere anche un oscilloscopio, mediante il quale è possibile fare delle misure di tempo sulle forme d'onda generate dal micro.

VMLAB si installa e funziona bene anche sotto Linux (grazie a Wine).
 
In ambiente Linux non essendoci WinAVR bisognerà provvedere manualmente alla compilazione, al collegamento ecc. dei vari file.

Dopo una rapida occhiata su Google, ho proceduto in questo modo:

1. Scaricare e installare (tramite Wine) VMLAB, disponibile all'indirizzo: http://amctools.com/download.htm

2. Successivamente scaricare e copiare nella propria home dir. il nuovo modello per l'ATmega168B già modificato per Linux  (curato da ThVortex)

Quindi decomprimerlo nella cartella di installazione di VMLAB. Da  bash shell:

$cd
~$ unzip -o useravr-0.6.zip -d ~/.wine/drive_c/VMLAB


N.B. Senza la modifica del punto 2, la simulazione del Timer1, in alcuni contesti di utilizzo, non avviene correttamente (e questo vale anche sotto Windows).

3.  assicurarci di avere installato sul nostro sistema il toolchain per lo sviluppo AVR con gcc. Con Debian il comando è:

# apt-get install gcc-avr binutils-avr avr-libc gdb-avr avrdude


(Con Ubuntu ricordarsi che c'è sudo)

Installato il necessario, si passa alla preparazione del makefile.

Per la generazione dei file necessari mi sono affidato all'ottimo Makefile di Winavr; l'ho solo modificato un poco per generare anche il file COFF con l'all, e per "spostare" tutta la parte di configurazione (micro, frequenza di clock, file, directory) in un altro file (che ho chiamato config) così da non mettere mani nel Makefile.

Il mio suggerimento è innanzitutto quello di crearsi una directory in cui mettere i propri lavori di Vmlab. Ogni progetto avrà dunque la propria directory nella quale ci sono tutti i file sorgenti, header, le librerie ecc. necessarie.

Creiamo allora una cartella nella nostra home: vmlabproj:

~$ mkdir vmlabproj


e una dir. in cui mettiamo il nostro primo progettino, di nome timer1:

~$ cd vmlabproj
~/vmlabproj$ mkdir timer1


In questa dir. ci copiamo dunque il file sorgente principale, quello dove c'è la main(), che chiamiamo sempre main.c e i file makefile e config. Il makefile non va modificato, il config, sì, secondo le proprie esigenze.

Il main.c è il nostro software per accendere e spegnere il LED ogni sec. che avevamo già scritto:


#include <avr/io.h>
#include <avr/interrupt.h>

#define N 62499 // 1s @ 4MHz/64

int main (void)
{

  DDRB |= (1 << PB1);  // Imposta il pin PB1 come di uscita
  TCCR1B |= (1 << WGM12); // imposta il Timer1 in modo CTC (su OCR1A)
  OCR1A = N;  // carica N nel registro OCR1A
  TIMSK1 = (1 <<  OCIE1A);  // abilita interrupt CTC su OCR1A
  TCCR1B |= (1 << CS11) | (1 << CS10) ; // abilita prescaler (fc/64)

  // Da questo punto in poi il timer è avviato!

  sei();  // abilita gli interrupt

  while(1)
  {
   /* non fa niente...aspetta l'interruzione */
  }
}


/* Routine gestione interrupt (viene eseguita ogni secondo)*/

ISR( TIMER1_COMPA_vect )
{
   PORTB ^=  (1 << PB1) ;  // Se PB1=0 allora PB1=1, se PB1=1 allora PB1=0
}


Il file config è riportato di seguito:

# MCU name

MCU = atmega168

# Processor frequency (in Hz)

F_CPU = 4000000

# Target file name (without extension)

TARGET = main

# Object files directory
#     To put object files in current directory, use a dot (.), do NOT make
#     this an empty or blank macro!

OBJDIR = .

# List C source files here. (C dependencies are automatically generated.)
# The first one must be TARGET above defined, the other ones
# must be separated by a space. Examples:
# SRC = $(TARGET).c lcd.c i2c.

SRC = $(TARGET).c


# List C++ source files here. (C dependencies are automatically generated.) spaced

CPPSRC =

# List Assembler source files here.
#     Make them always end in a capital .S.  Files ending in a lowercase .s
#     will not be considered source files but generated files (assembler
#     output from the compiler), and will be deleted upon "make clean"!
#     Even though the DOS/Win* filesystem matches both .s and .S the same,
#     it will preserve the spelling of the filenames, and gcc itself does
#     care about how the name is spelled on its command-line.

ASRC =



# List any extra directories to look for include files here.
#     Each directory must be seperated by a space.
#     Use forward slashes for directory separators.
#     For a directory that has spaces, enclose it in quotes.

EXTRAINCDIRS =

# List any extra directories to look for libraries here.
#     Each directory must be seperated by a space.
#     Use forward slashes for directory separators.
#     For a directory that has spaces, enclose it in quotes.

EXTRALIBDIRS =




In MCU si definirà il tipo di micro (atmega168, atmega328, attiny2313 ecc.),

in F_CPU la frequenza di lavoro in Hz (nel nostro caso 4000000 Hz, cioè 4MHz).

TARGET è il solo nome (senza estensione) del nostro file principale.

OBJDIR lasciamo il punto (i file oggetto verranno copiati nella stessa directory).

In SRC, se abbiamo più file sorgenti (es. lcd.c, i2c.c, serial.c ecc.) li specificheremo dopo il target, separandoli con uno spazio.

Stesso discorso per CPPSRC, che riguarda i file C++. Le altre definizioni le useremo se i nostri file si trovano in altre directory, se abbiamo anche file asm ecc.

Con il config preparato, portiamoci nella dir. del nostro progetto e lanciamo un make

~$ cd vmlabproj/timer1
~/vmlabproj/timer1$ make


Dopo questo comando dovremmo trovarci nella nostra directory di lavoro alcuni file, fra i quali quelli che interessano a VMLAB sono:

main.cof
main.elf


Nel caso volessimo cancellare i file generati, basterà il classico clean:

~/vmlabproj/timer1$ make clean


Fatto questo creiamo il file progetto per VMLAB, con un editor di testi, TIMER1.PRJ

.MICRO     "ATmega168b" "CKSEL=0000 CKDIV8=1"
.CLOCK     4MEG
.TOOLCHAIN "GENERIC"
.TARGET    "main.hex"
.COFF      "main.cof"
.STORE 5   ; Time stop della simulazione

; ------------------------------------------------------------

D1 VDD K        ; D1 (LED), morsetto 1: A del LED (obbligatoriamente su VDD), morsetto 2: catodo
R1 K PB1 0.62K  ; R1 (620Ohm), morsetto 1 sul K del LED, morsetto 2 su PB1
.PLOT V(PB1)

Il ";" inizia un commento e quindi tutto quello che cìè scritto dopo è ignorato da VMLAB.

Nelle prime direttive si vanno a definire il micro, la frequenza di clock in MHz, i file che abbiamo generato e il tempo fino al quale vogliamo far eseguire i calcoli di simulazione. Dal momento che il nostro timer genera un periodo di 2 secondi ci si può fermare a po' più del doppio del periodo.

La seconda parte, invece, è quella che riguarda il nostro LED collegato all'uscita PB1

VMLAB mette a disposizione diversi componenti (fino a 8 LED, slide, tastierino ecc.), che possono essere richiamati dall'utente con una particolare sintassi (vedi help).

La sintassi è molto simile a quella di Spice.

Per il LED, la sintassi è:

Dx VDD nomecatodo


Con x che va da 1 a 8, a secondo del LED che vogliamo usare.

L'anodo del LED (il morsetto n.1) deve essere sempre collegato all'alimentazione VDD. Il secondo morsetto del LED (il catodo) lo chiamiamo, per esempio, "K" e lo colleghiamo all'uscita PB1, mediante la resistenza R1 di 620 Ohm.

Questo perché VMLAB impone di collegare +5V sull'anodo e dunque il nostro LED (come già avevamo scelto in partenza) si accenderà sul livello logico 0.

Lo schema quindi è:




L'ultima direttiva, chiede a VMLAB di visualizzare sull'oscilloscopio la tensione sul piedino PB1.

Avviamo VMLAB dal menù Wine...e apriamo il file progetto, dalla barrà dei menù con:
Project -> Open.

Visualizziamo sia il "Panel control" (dove ci sono tutte le periferiche di I/O e quindi anche i LED) e l'oscilloscopio con i comandi, con:

View -> Scope
View -> Control Panel


e lanciamo un build...che in effetti è solo un build per VMLAB, in quanto i file già sono stati "buildati" manualmente con make...

Project -> Project Build

A questo punto lanciamo il Run (premendo F5) e osserviamo il segnale PB1 sull'oscilloscopio.

Notiamo subito che la simulazione di VMLAB non è in tempo reale: il LED non rimane acceso/spento per 1s, ma i tempi computati sull'oscilloscopio sono invece esatti.

Considerati i tempi in gioco, conviene impostare l'oscilloscopio su un Time/DIV di 50ms/DIV e su "Full View".

Ci sono due cursori a disposizione per la misura dei tempi, il primo viene attivato cliccando sul bottone 1 e ha lo stile di una linea continua, il secondo viene attivato cliccando sul bottone 2 e ha lo stile di una linea tratteggiata. Sotto questi bottoni, viene riportata la differenza di tempo: t2-t1

La misura dei tempi avverrà per il tempo in cui l'uscita è bassa e per il tempo in cui l'uscita è alta.

Ovviamente occorrerà fermare la simulazione a un istante in cui si visualizza tutto il semiperiodo, fare la misura e poi riavviarla fino a visualizzare per intero il successivo semiperiodo.

I risultati della simulazione sono riportati di seguito e come si può notare i tempi risultano perfettamente uguali a 1s.

Tempo "on" - LED acceso (PB1=0V):



Tempo "off" - LED spento (PB1=5V)



Buon divertimento!



timer1.zip


< Timer AVR in 5min: 2) Il modo CTC Timer AVR in 5min: 4) Generare forme d'onda con CTC >



I contenuti di questo documento, sono stati resi possibili grazie ai seguenti strumenti gratuiti:
- FidoCADJ (disegno grafici)
- Google Code Prettify (sorgenti con sintassi evidenziata)
- gEDA (disegno schemi elettrici)
- Forum VMLAB: http://www.amctools.com/cgi-bin/yabb2/YaBB.pl?board=news
- Tutorial VMLAB: http://www.scienceprog.com/using-vmlab-as-virtual-oscilloscope/



Nessun commento:

Posta un commento