Tesina esame di stato 2015
TASTIERA ELETTRONICA CONTROLLATA DA
UN MICROPROCESSORE
Marchi Michele, Sidibe David
5aeln
Indice
 Descrizione progetto
pag. 1
 Schema a blocchi
pag. 2
 Schema elettrico
pag. 3
o Micro dsPIC33FJ128MC706A
pag. 4
o Alimentazione
pag. 6
o Pulsanti
pag. 6
o DAC MCP4822
pag. 7
 Amplificatore LM386
pag. 10
 Software
pag. 10
 Conclusioni
pag. 14
Descrizione progetto
Il nostro obiettivo era quello di realizzare una tastiera elettronica controllata da un
microprocessore e composta da due ottave, più precisamente la quarta e la quinta.
Un'ottava è un intervallo di 8 note (do, re, mi, fa, sol, la, si, do) più 5 semitoni (diesis),
posizionate a diverse frequenze nella scala musicale. Nel nostro caso, per motivi di spazio,
abbiamo dovuto tralasciare l’ ultimo Do di entrambe le ottave, in modo da ottenere 7 note
e 5 semitoni per ottava. La nostra risulta quindi una tastiera composta da 14 note più 10
semitoni.
Per quanto riguarda le frequenze attribuite a ciascuna nota, si è stabilito che la nota La della
quarta ottava corrisponda ad una frequenza di 440 Hz, mentre per calcolare la frequenza
delle altre note si usa la seguente formula:
fnota = 440 * 2n/12 (dove n è la distanza della nota scelta dalla nota La della quarta ottava)
Se ad esempio volessimo ricavare la frequenza della nota Fa# della quarta ottava la formula
risulterebbe:
fnota= 440 * 2-3/12 = 369,99 Hz
Di seguito uno schema riportante le frequenze delle 13 note della quarta ottava:
Pag. 1
Schema a blocchi
TASTI
I tasti rappresentano il nostro sistema di input.
Premendoli, sceglieremo quale nota verrà suonata.
MICRO
CONTROLLORE
DAC
AMPLIFI
CATORE
I segnali dei tasti premuti verranno acquisiti dal micro e
in seguito verranno creati e rielaborati i campioni digitali della
nota scelta.
Conversione del segnale digitale in ingresso in un segnale
analogico.
Amplificazione del segnale analogico (regolazione volume).
Le casse (speakers) emetteranno le note scelte.
Pag. 2
Schema elettrico
Pag. 3
Micro dsPIC33FJ128MC706A
3.3V
D3
1N4148 SMD
R26
10K
R27
JP1
C25
.1uF
1
2
3
4
5
3.3V
100
C26
1nF
HEADER 5
39
47
48
40
RD0
RD1
RD2
RD3
RD4
RD5
RD6
RD7
RD8
RD9
RD10
RD11
46
49
50
51
52
53
54
55
42
43
44
45
PWM1L/RE0
PWM1H/RE1
PWM2L/RE2
PWM2H/RE3
PWM3L/RE4
PWM3H/RE5
PWM4L/RE6
PWM4H/RE7
C1RX/RF0
C1TX/RF1
U1RX/SDI1/RF2
U1TX/SDO1/RF3
U2RX/SDA2/CN17/RF4
U2TX/SCL2/CN18/RF5
U1RTS/SCK1/INT0/RF6
OSC1/CLKIN/RC12
PGED2/SOSCI/T4CK/CN1/RC13
PGEC2/SOSCO/T1CK/CN0/RC14
OSC2/CLKO/RC15
SCL1/RG2
SDA1/RG3
SCK2/CN8/RG6
SDI2/CN9/RG7
SDO2/CN10/RG8
SS2/CN11/RG9
OC1/RD0
OC2/RD1
OC3/RD2
OC4/RD3
OC5/IC5/CN13/RD4
OC6/IC6/CN14/RD5
OC7/CN15/RD6
OC8/UPDN/CN16/RD7
IC1/FLTA/INT1/RD8
IC2/U1CTS/FLTB/INT2/RD9
IC3/INT3/RD10
IC4/INT4/RD11
9
25
41
dsPIC33FJ128MC706A
18
17
RB7
RB6
60
61
62
63
64
1
2
3
RE0
RE1
RE2
RE3
RE4
RE5
RE6
RE7
58
59
34
33
31
32
35
RF0
RF1
RF2
RF3
RF4
RF5
RF6
37
36
4
5
6
8
RG2
RG3
RG6
RG7
RG8
RG9
Vcap/Vddcore
RC12
RC13
RC14
RC15
PGED1/AN7/RB7
PGEC1/AN6/OCFA/RB6
PGED3/AN0/Vref +/CN2/RB0
PGEC3/AN1/Vref -/CN3/RB1
AN2/SS1/CN4/RB2
AN3/INDX/CN5/RB3
AN4/QEA/IC7/CN6/RB4
AN5/QEB/IC8/CN7/RB5
U2CTS/AN8/RB8
AN9/RB9
TMS/AN12/RB10
TDI/AN13/RB11
TCK/AN12/RB12
TDI/AN13/RB13
U2RTS/AN14/RB14
AN15/OCFB/CN12/RB15
Vss
Vss
Vss
RD0
RD1
RD2
RD3
RD4
RD5
RD6
RD7
RD8
RD9
RD10
RD11
16
15
14
13
12
11
21
22
23
24
27
28
29
30
AVss
RC12
RC13
RC14
RC15
RB0
RB1
RB2
RB3
RB4
RB5
RB8
RB9
RB10
RB11
RB12
RB13
RB14
RB15
20
RB0
RB1
RB2
RB3
RB4
RB5
RB8
RB9
RB10
RB11
RB12
RB13
RB14
RB15
MCLR
56
U?
7
C?
.1uF
19
C?
.1uF
AVdd
C?
.1uF
10
26
38
57
C?
.1uF
Vdd
Vdd
Vdd
Vdd
C?
.1uF
PROGRAMMAZIONE E
DEBUG
C?
10uF
Il pic da noi utilizzato necessita di una tensione di alimentazione di 3.3V, abbiamo quindi
dovuto convertire i 5V tramite l' LM1117.
Caratteristiche principali:
Architettura
Velocità CPU
Tipo di memoria
Memoria programmabile
RAM
16-bit
40 MIPS
Flash
128 KB
16,384 KB
Piedini totali
64
RE0
RE1
RE2
RE3
RE4
RE5
RE6
RE7
RF0
RF1
RF2
RF3
RF4
RF5
RF6
RG2
RG3
RG6
RG7
RG8
RG9
Timers
9 x 16-bit 4 x 32-bit
Comunicazione digitale periferica
2-SPI
Pag. 4
Il pic che abbiamo utilizzato fa parte della famiglia dei DSC (Digital Signal Controller).
I membri di tale famiglia integrano delle innovative caratteristiche riducendo
contemporaneamente i consumi, e sono inoltre molto più veloci dei vecchi micro.
In particolare, il nostro pic è molto veloce nelle risposte degli interrupt e offre periferiche di
comando come il PWM o il watchdogs molto precise, anche se noi non le abbiamo
utilizzate.
I pic della famiglia DSC sono utilizzati in una vasta gamma di applicazioni, ma la maggior
parte sono utilizzati per il controllo del motore, conversione di potenza e applicazioni di
elaborazione di un sensore.
Attualmente i DSC vengono commercializzati come le tecnologie verdi per il loro potenziale
di ridurre il consumo energetico nei motori elettrici e alimentatori.
La struttura dell' integrato è davvero ridotta, 12 mm x 12 mm, con un totale di 64 piedini.
Date le sue piccolissime dimensioni ci siamo dovuti fornire di un adattatore per la nostra
basetta a mille fori.
Porte utilizzate:
Abbiamo utilizzato tutti ingressi digitali per la lettura dei tasti:
Da RB0 a RB5
Da RB8 a RB15
Da RD0 a RD7
RC12 e RC15
Per programmare il pic e per effettuare il debug con l’ ICD3 abbiamo utilizzato le seguenti
porte:
RB6 e RB7, corrispondenti a PGEC1 e PGED1
Per la comunicazione SPI con il Dac abbiamo utilizzato le seguenti porte:
RF6 per il segnale del clock
RF3 comunicazione SDI
RE5 per il chip set
RG5 per il latch del DAC
Non abbiamo utilizzato l’ oscillatore al quarzo perché l oscillatore interno è
sufficientemente veloce.
Sul piedino MCLR abbiamo inserito un circuito di precauzione con un diodo 1N4148, una
resistenza R26 e un condensatore C25. Questi componenti sono necessari per prevenire
eventuali sovratensioni provenienti dal piedino 1 dello zoccolo di programmazione, che
potrebbero influenzare l' alimentazione del circuito.
Pag. 5
Alimentazione
Per far fronte al range di funzionamento del nostro micro compreso tra 3 e 3.6V abbiamo
dovuto utilizzare l' LM1117.
Esso si tratta di un regolatore di tensione grazie al quale possiamo diminuire la tensione in
entrata Vin, nel nostro caso 5V, ad un valore Vout a scelta tra 1.8V, 2.5V, 2.85V, 3.3V o 5V.
La Vref applicata al resistore R1 è di 1.25V, come suggerito dal datasheet, e genera una
corrente costante I1. In seguito la corrente I1 attraversa il resistore R2 e possiamo così,
attraverso la regolazione dei due resistori impostare la Vout ad un valore desiderato.
Nel nostro caso per trasformare la Vin da 5V a 3.3V abbiamo impostato R1 a 110 Ω e R2 a
180Ω.
Sostituendo tali valori alla formula di seguito riportata, e tenendo presente che la Iadj è
tendente a 0, si nota come Vout = 3.3:
Vref (1+
Pulsanti
VCC
SW8
SW PUSHBUTTON
R32
10K
DO
I segnali digitali provvenienti dall'
alimentazione a 3.3V passano attraverso i
tasti e successivamente su una resistenza di
pull-down da 10k per garantire l' ingresso
logico del pic.
Il valore delle resistenze di ciascun pulsante è
stato impostato a 10k poiché, anche se
venissero premute più note insieme, la somma di tutte le correnti deve stare entro certi
limiti per evitare il danneggiamento del micro.
Pag. 6
DAC MCP4822
Cenni riguardanti i DAC:
Il Digital to Analog Converter (DAC) è un componente elettronico in grado di produrre in
uscita un determinato livello di tensione o di corrente, in funzione di un valore numerico al
suo ingresso.
Una larga diffusione ad uso domestico dei DAC si ha nei riproduttori digitali di suoni, nel
controllo dell'apertura del diaframma nelle macchine fotografiche, nei controlli digitali
(volume, luminosità) dei televisori e in tutte quelle situazioni nelle quali un'informazione
numerica deve controllare una grandezza di tipo analogico.
Una delle caratteristiche da tenere maggiormente in considerazione nei DAC è la
risoluzione.
Si passa dagli 8 bit (256 livelli di tensione) dei DAC più semplici (telecomandi ecc.), ai 12 bit
per i controlli di precisione (strumenti di misura, multimetri, oscilloscopi), ai 16 bit per i
riproduttori musicali ad alta fedeltà, fino ad arrivare al DVD, con i suoi 24 bit di risoluzione.
All'aumentare della risoluzione corrisponde però un maggior numero di elaborazioni per
ottenere la tensione d'uscita; in altre parole, più è elevata la risoluzione del DAC e più la sua
elaborazione ne risulterà rallentata.
Nel nostro caso abbiamo utilizzato il DAC MCP4822 per convertire i dati della sinusoide in
uscita del pic in un segnale analogico.
pag. 7
Le principali caratteristiche del nostro DAC sono:
 n° bit: 12 bit
 Vref: 2,048 V
 Tensione di alimentazione: 2.7 - 5.5 V
 INL: ± 2 LSB
 DNL: ± 0.2 LSB
Il massimo errore di quantizzazione, secondo la seguente formula, è di circa 0.00025.
dove
N=
Il valore dell' LSB, cioè del bit meno significativo, è di 0.5mV, ovvero il valore del quanto.
L' MCP4822 presenta un errore di offset di circa ±0.02%, ossia potremmo trovare un errore
di più o meno 1.024mV.
Altri parametri da tenere in considerazione sono gli errori di INL e DNL. L' INL è il massimo
spostamento tra la caratteristica della curva reale e quello della retta ideale, mentre il DNL
è la massima variazione rispetto alla variazione ideale al cambio del bit meno significativo.
L' INL e il DNL devono essere compresi tra
eper garantire la monotonia della
mia funzione.
IL settling time, il tempo di assestamento, è un altro parametro importante e descrive il
tempo necessario alla Vo per mantenersi in una frazione del valore finale. Nel nostro caso
corrisponde a 4.5 µs.
pag. 8
Il tipo di interfaccia che abbiamo utilizzato è la SPI (Serial Peripheral Interface).
Questa connessione presenta un master, ovvero il micro, e uno o più slave, nel nostro caso
solamente uno ossia il dac, collegati tra di loro attraverso 4 segnali:
o SCK (Serial Clock): clock seriale che scandisce gli istanti di emissione e di lettura
dei bit sulle linee di dati. È un segnale emesso dal master ed è quindi quest'ultimo a
richiedere di volta in volta la trasmissione di un segnale.
o SDI (Serial Data Input): linea attraverso cui il dispositivo (master o slave) riceve il dato
seriale emesso dalla controparte.
o SDO (Serial Data Output): linea di output di dato.
o CS(Chip Select): emesso dal master per scegliere con quale dispositivo slave vuole
comunicare.
Il bus di dati è di tipo seriale sincrono e la trasmissione e ricezione può avvenire
contemporaneamente.
pag. 9
Amplificatore LM386
Questo componente è un circuito integrato
con un operazionale al suo interno.
All' uscita del dac c' è un condensatore di
accoppiamento da 1uF per collegarsi al
circuito in figura.
Questo componente è stato usato per
amplificare la piccola tensione che troviamo
in uscita al dac. Allo schema fornito dal
datasheet sono stati sostituiti vari
componenti essenzialmente per una
questione di disponibilità del materiale.
Ad esempio è stato cambiato il
condensatore sul piedino numero 8 con uno
più piccolo da 1uF poiché con il valore imposto in precedenza produceva troppa
distorsione. Il condensatore posto di seguito alla resistenza sul piedino 5 è stato invece
sostituito da uno da 100nF mentre l' ultimo condensatore da 250uF è stato sostituito da
uno da 220 uF.
Software
IL caricamento del software nel PIC dal PC avviene tramite un programmatore esterno,
come ad esempio il Pick-it o l ICD3.
L interfaccia software invece viene fornita dalla Microchip stessa: MPLAB X infatti, oltre a
permettere lo sviluppo del software, offre anche la possibilità di lanciare il debug, ossia di
eseguire le istruzioni una alla volta per individuare eventuali errori nel funzionamento del
software.
La parte principale del programma scritto in linguaggio C è su un file chiamato main.
Al programma principale è stato necessario includere delle librerie di intestazione, in cui
sono dichiarate le funzioni standard di input/output del C.
#include
#include
#include
<xc.h>
<stdio.h>
<string.h>
#include
#include
#include
<math.h>
<stdbool.h>
<stddef.h>
pag. 10
#include
#include
#include
#include
#include
#include
#include
<stdint.h>
"Spi.h"
"Rout.h"
"Menu.h"
"tglPin.h"
"Tast.h"
"Main.h"
All' inizio del programma vengono impostati I vari parametri dell' oscillatore interno, nel
nostro caso viene configurato a 40 MHz.
La frequenza a cui opera il dispositivo è:
Fcy =
Sono stati poi impostati i vari bit per la configurazione di N1 del prescaler, N2 del postscaler
e l' M, il moltiplicatore del PLL.
Fosc = Fn
,
La frequenza nominale è di 7.37KHz.
Per prima cosa è stata creata una funzione per la lettura dei tasti attraverso uno switch.
Nel primo stato viene presupposto che nessun tasto sia premuto, successivamente invece,
nel secondo stato, viene inserita un' attesa dell' antirimbalzo. A questo punto se un tasto
viene premuto viene ritenuto valido. Per finire è presente la decodifica e la lettura del tasto
per sapere quale tasto è stato premuto, il quale viene messo all' interno di una variabile.
Sono stati poi inizializzati dei prototipi delle funzioni dei due timer:
void Init_Timer6( void );
void Init_Timer8(void);
CONTROLLI
// TIMER A 2 ms
// TIMER IN FREE RUNNING PER INTERVALLO
IL PRIMO TIMER void Init_Timer6( void )
{
T6CON=0;
// IL TIMER viene RESETTATO
IFS2bits.T6IF = 0;
// viene resettato l interrupt del timer1
IPC11bits.T6IP = 2;
// priorità dell' interrupt di livello 3
TMR6= 0x0000;
PR6 = 40000;
// periodo del registro Timer1 = 1ms
IEC2bits.T6IE = 1;
// Abilita interrupt del Timer6
T6CONbits.TON = 1;
// Abilita il conteggio del Timer6
}
pag. 11
Queste impostazioni servono per la gestione dei tempi con la comunicazione con lo slave,
ovvero il dac.
Il timer 8 lo abbiamo invece utilizzato per una semplice divisione tra la frequenza di del
clock fissata a 40 MHz e la frequenza di campionamento fissata a 22kHz.
void Init_Timer8( void )
{
T8CON=0;
IFS3bits.T8IF=0;
TMR8= 0x0000;
PR8=TIMER8LOAD;
IEC3bits.T8IE = 1;
T8CONbits.TON = 1;
// TIMER RESET
//
// Abilita interrupt del Timer8
// Abilita il conteggio del Timer8
}
In seguito questi interrupt vengono gestiti attraverso la SIR (service interrupt routine) in
generale, l'utente deve azzerare il flag interrupt posto nell' adeguato registro IFSx per la
fonte di interrupt che SIR gestisce. In caso contrario, il SIR sarà attivato di nuovo dopo
l'uscita dalla routine. Quindi il SIR controlla soltanto le interruzioni del programma.
Il SIR invece per l' interrupt del timer8 sostanzialmente permette di avere una struttura per
le note con il valori di ogni nota e il numero di campioni.
IFS3bits.T8IF = 0;
tglPin();
Acc=0l;
nSum=1;
for(i=0; i < NUMNOTE;i++)
{
if (Note[i].Enabled)
{
k=Note[i].Index;
l=Note[i].Limit;
data=Note[i].Camp[k++];
if (k >=l)
k=0;
Note[i].Index=k;
//reset timer
Acc+=(long)data;
nSum++;
pag. 12
// Aggiunge alla variabile a sinistra il valore a destra
}
}
data =(int) (Acc / nSum);
LoadDac(data + 2047);
}
Da qui si è deciso che ogni singola nota avrà un numero massimo di 200 campioni e la
frequenza di campionamento per rispettare il teorema di Shennon è stata fissata a 22Khz,
cioè almeno il doppio della F massima.
Poi è stata inizializzata la tabella per le note attraverso un ciclo for in cui viene fatta una
semplice divisione tra la frequenza di campionamento e la frequenza di ogni singola nota.
Così abbiamo trovato i campioni per ogni nota. Viene creato poi l' angolo di 2π pari a 360°
comprendente il primo semicerchio positivo e il secondo semicerchio negativo. Adesso c' è
un piccolo step riguardante l'angolo: viene fatta una semplice divisione tra l'angolo giro
completo e i campioni trovati prima per ogni nota.
Successivamente viene controllato se il numero di campioni per nota non supera il numero
200, precedentemente fissato per il numero massimo di campioni, così attraverso un altro
ciclo for inizio a ricostruire i vari valori della sinusoide che voglio comporre per le varie note.
È da ricordare che il dac è a 12 bit quindi ho 4096 livelli possibili da assumere per la
sinusoide. Quindi vengono utilizzati 2048 valori per la parte positiva e 2048 per la parte
negativa.
for (i=0;i < NUMNOTE;i++)
{
Nstep=(int) (((float) FCAMP / (float)tabNote[i]) + 0.5 );
// CAMPIONI PER NOTA
StepAngolo=(2.0 * pi) / (float) Nstep;
//360°/campioni
Angolo=0;
if ( Nstep < STEPNOTE)
{
for (k=0; k < Nstep;k++)
{
tmp=(float) MAXDAC * sin(Angolo);
Note[i].Camp[k]=(int) tmp;
Angolo+=StepAngolo;
// Aggiunge alla variabile a sinistra il valore a destra
}
Note[i].Limit=Nstep;
Note[i].Index=0;
Note[i].Enabled=false; } } }
pag. 13
CONCLUSIONI
La scheda realizzata funziona correttamente ed è stata testata per quanto riguarda gli
ingressi digitali e l' uscita del dac. Il pic inoltre è stato correttamente programmato con l'
ICD3 . Durante l esperienza sono emerse alcune difficoltà riguardanti le resistenze di pulldown che hanno un maggior consumo di corrente. Ma tutto sommato sono la stessa cosa
per questo tipo di applicazioni. Inoltre sono state apportate alcune modifiche esterne
riguardanti la tensione di alimentazione per i tasti. Inizialmente erano stati portati due fili
esterni attraverso un header, in seguito però per motivi di spazio sono stati spostati
attraverso un bus di cavi.
pag. 14