Architettura dei Microcontrollori Microchip PIC18Fromani/Dida01/lezioni/microcontrollori_v2.pdf ·...
Transcript of Architettura dei Microcontrollori Microchip PIC18Fromani/Dida01/lezioni/microcontrollori_v2.pdf ·...
Architettura dei
Microcontrollori
Microchip PIC18F
A. Romani
Elettronica dei Sistemi Digitali L-A
II Facoltà di Ingegneria
Università di Bologna
Cos’è un microcontrollore?
Differenza tra Microprocessore e Microcontrolloreà Microprocessore: normalmente si intende un
dispositivo limitato alla sola CPU, che richiede memoria, clock e componenti/periferiche esterni (maggior complessità di progetto)Es. Intel x86
à Microcontrollore: normalmente si intende un sistemaincluso in un unico package che comprende una CPU, memoria (RAM, ROM/Flash), periferiche digitali (registri I/O, timer, etc.) e analogiche (ADC, comparatori, etc.), oscillatori per generare il clock, etc.Es. Microchip PIC, Texas Instruments MSP430, etc.
MCU = Micro-Controller Unit
II Facoltà di Ingegneria
Università di Bologna
Architettura di un Microcontrollore Una MCU PIC contiene:
à datapath con ALU
à decoder per POCHEistruzioni.
à Oscillatori/PLL per la generazione del clock
à Registri generali (RAM)
à Registri con funzionispeciali (SFR)
à Interrupt Controller
à RAM per dati.
à FLASH per codice.
à Porte di I/O digitale.
à Altre periferiche Timer interno
AD Converter
USART (seriale)
SPI/I2C
PWM
EEPROM dati
II Facoltà di Ingegneria
Università di Bologna
Microcontrollori Microchip PIC18
Con pochissimi componenti esterni e poche righe di programma si può ottenere un SISTEMA COMPLETO FUNZIONANTE.
Facilità di lavoroà Semplice montaggio su scheda
à E’ tutto dentro (anche il clock!)
à Non serve progettare una MotherBoard!
Programmazione à Assembler con poche, semplici istruzioni
à Disponibili compilatori C, basic, …
Una volta programmato … VA!
Limiti nelle prestazionià c’e’ quello che c’è … (RAM e frequenza limitate)
à potenza di calcolo limitata
II Facoltà di Ingegneria
Università di Bologna
MCU Microchip
Diverse famiglie di Microcontrollori
à 8, 16, 32 bit
Ogni famiglia è composta da numerosi
componenti, distinti per:
à Memoria dati
à Memoria codice
à Periferiche
à Frequenza di
clock
à Consumi di
potenza
II Facoltà di Ingegneria
Università di Bologna
Famiglia PIC18
Caratteristiche:à Architettura a 8 bit
à Instruction word a 16 bit
à Architettura di memoria Harvard
Frequenza massima:à 32MHz – 64MHz (Internal PLL x4)
Memoria codice:à 4KB – 128KB
Costo: à 1.20$ - 8.44$
Data EEPROMà 0B – 1024B
Numero di pin:à 18 – 100 pin
Tensione di lavoro:à 1.8V – 5.5V
II Facoltà di Ingegneria
Università di Bologna
PIC18 Part numbering
Es.
PIC18F 87 20 – I/PT
memoria codice
flash1 = 18 pin
2 = 28 pin
4 = 40/44 pin
6 = 64 pin
8 = 80 pin
…
21 = 2K bytes
22 = 4K bytes
23 = 8K bytes
24 = 16K bytes
25 = 32K bytes
26 = 64K bytes
27 = 128K bytes
…
condizioni di
utilizzo
tipo di package
II Facoltà di Ingegneria
Università di Bologna
Architettura di memoria
I PIC18 includono 3 tipi di memoria:
à Memoria codice (max 128KB)
programma
dati permanenti (es. da ricopiare in RAM
durante l’esecuzione)
à Memoria dati RAM (max 3968B)
dati temporanei
à Memoria E2PROM (max 1024B)
dati permanenti
CPU
MemMem
Flash
Codice
bus
istruzioni
bus
dati
RAM
dati
perifericheperiferiche
EEPROMEEPROM
II Facoltà di Ingegneria
Università di Bologna
Architettura Data-path
Esecuzione
controllata da un
clock a 4 fasi
non sovrapposte
Struttura
della pipeline:
à A regime viene completata un’istruzione ogni 4 cicli di clock (eccetto branch).
Latenza 8 cicli di clock.
à MIPS = fCK(MHz)/4
II Facoltà di Ingegneria
Università di Bologna
PIC18 – Spazio di indirizzamento
RAM dati vista come insieme di registrià (GPR, General
Purpose Registers)
Le periferiche sono accessibili attraverso registri di controlloà detti Special Function
Register
à mappati alle locazioni alte dello spazio di indirizzamento (quindi omogenei alla RAM)
Indirizzamentoà a 12 bit
à A 8 bit + 4 bit per selezione banco
II Facoltà di Ingegneria
Università di Bologna
Programmazione C
E’ il modo più semplice per programmare un microcontrollore
I produttori forniscono Header files e Librerie per utilizzare il dispositivoà L’header file definisce tutti i tipi e strutture dati
necessarie alla programmazione,
à Definisce costanti simboliche per accedere ai registri di controllo delle periferiche
à Definisce costanti simboliche per i valori di configurazione dei registri di controllo
Es.à /* Esempio programma C */#include <p18f452.h>#include <adc.h>[…]
II Facoltà di Ingegneria
Università di Bologna
Registri di controllo Solitamente l’header file definisce nomi simbolici per i registri associandoli alla locazione di memoria
corrispondente
à es.
#define PORTA (*((volatile unsigned char *) (0xF60)))
à unsigned char: intero a 8 bit senza segno (0..255)
à volatile: keyword del linguaggio utilizzata per indicare al compilatore che la locazione di memoria può essere modificata anche da agenti esterni alla CPU (es. porta I/O in lettura da un pulsante esterno, o il valore di un timer, etc). Se non indicata il compilatore potrebbe fare “caching” sui registri interni e non “rileggere” dalla periferica il valore attuale.
à *: in C indica un puntatore, cioè un tipo di dato/variabile che contiene l’indirizzo di una locazione di memoria (che contiene un intero senza segno a 8 bit in queto caso)
à (tipo di dato): in C indica l’operazione di “casting”: cioè il valore o la variabile che seguono devono essere considerati dal compilatore come il tipo di dato entro parentesi. Es. 0xF60 da solo è un intero a 12 bit, ma con il casting (volatile unsigned char *) (0xF60) diventa un indirizzo di memoria a cui è contenuto un intero senza segno a 8 bit volatile.
à * in C indica anche l’operatore di “dereferenziazione”. Deve essere seguito da un puntatore. Es. *p = 12; scrive il valore 12 nella locazione di memoria contenuta nella variabile p, definita magari come int *p; (puntatore a intero). Quindi:
*( (volatile unsigned char *) (0xF60)) dereferenzia la locazione di memoria 0xF60 e quindi consente di leggere o scrivere a questo indirizzo, dove c’è la porta di I/O A:
à Es. *( (volatile unsigned char *) (0xF60)) = 12; // scrive 12 nel// registro PORTA
variabile1 = *( (volatile unsigned char *) (0xF60)); //copia il valore// del registor PORTA in variabile1
#define simbolo espressione implementa una “macro”: cioè una sostituzione testuale nel listato della parola “simbolo” con “espressione”
à Dunque per accedere alla locazione di memoria F60 dove c’è la porta dati A basta usare il simbolo PORTA invece della espressione corrispondente;Es. PORTA = 0b00001111; //scrive 4 zeri e 4 uni nella porta di uscita A
II Facoltà di Ingegneria
Università di Bologna
Programmazione C
Come deve essere impostato un programma per un microcontrollore?
Deve essere gestito come un LOOP INFINITOà Non c’è “uscita” o “ritorno” dal programma: A chi dovrebbe ritornare il
programma? E quando?
Es.à /* Esempio programma C */
#include <p18f452.h>#include <adc.h>
void main(void){
/* Inizializzazione datie periferiche */
[…]
/* Loop principale */while(1){[…]
}}
Ogni MCU ha il suo
header file, poiché
ha una diversa
architettura interna!
Esistono header file
anche per le
periferiche più
complesse
II Facoltà di Ingegneria
Università di Bologna
Esempio: Controllo di un semaforo pedonale
Esempio di schematico
Vdd
10kPGC
GND
PGD
VDD
MCLR
Vdd
5.6k
33pF
Vdd
1k 1k 1k
10k
100nF
II Facoltà di Ingegneria
Università di Bologna
Programmazione C
Es. Controllo di un semaforo.à Supponiamo luci verde, gialla, rossa e pulsante collegate come in slide precedente
#include <p18f452.h>#define VERDE PORTBbits.RB1#define GIALLO PORTBbits.RB2#define ROSSO PORTBbits.RB4#define PULSANTE PORTBbits.RB5
extern void delay_ms(unsigned int millisec);
void main(void){
/* Inizializzazione *)TRISB = 0b00100000; // porta B tutta in output tranne
//il bit 5
ROSSO = 0; GIALLO = 0; VERDE = 1;
while(1){
while (!PULSANTE) ; // il pulsante se premuto// manda a 1 il segnale// esterno ed esco dal loop
GIALLO = 1;delay_ms(2000);VERDE = 0; GIALLO = 0; ROSSO = 1;delay_ms(30000);ROSSO = 0; VERDE = 1;
}}
Indica che
l’oggetto è
definito in un
altro modulo (già
compilato) e che
verrà agganciato
nella fase di
linking quando
viene creato il file
binario
(“eseguibile”)
II Facoltà di Ingegneria
Università di Bologna
PIC18 - Periferiche
Porte I/O digitali:à Servono per
Generare segnali digitaliin uscita
Leggere segnali digitali iningresso
à Registri di uscita (PORTx)collegati: al bus dati come
periferiche (ogni reg. ha unsuo indirizzo nello spazio diindirizzamento)
ai pin del dispositivo in uscita
à Registro di controllo(TRISx) Collegato al bus dati come
periferica al suo spazio diindirizzamento
à Registro di ingresso LAT o I/O pin
II Facoltà di Ingegneria
Università di Bologna
PIC18 - Periferiche
Le porte di I/O sono
raggruppate in
registri a 8 bit,
accessibili
individualmente o
in parallelo
à PORTA, PORTB, …,
PORTE, etc.
PO
RT
B.R
B0
PO
RT
B.R
B1
PO
RT
B.R
B7
DA
TA
BU
SD
ATA
BU
S
II Facoltà di Ingegneria
Università di Bologna
Programmazione C – Porte I/O
Esempio:à /* PIC18F458 @ 10MHz */
#include <p18f458.h>
void MSDelay(unsigned int);
void main(void){
TRISB = 0x00; /* configura la porta B come 8 output */while(1) /* loop infinito */{
PORTB = 0b00000000;MSDelay(250);PORTB = 0b11111111;MSDelay(250);
}}
void MSDelay(unsigned int itime){
unsigned int i; unsigned char j;for (i=0;i<itime;i++)
for (j=0; j<165;j++); /* ritardo gestito contandole iterazioni comprese in1 ms. */
}
II Facoltà di Ingegneria
Università di Bologna
PIC18 – Convertitore A/D
Periferica che converte grandezze
analogiche (tensioni) in
numeri binari
II Facoltà di Ingegneria
Università di Bologna
PIC18 – Convertitore A/D
Risoluzione: 10 bit
4-28 canali analogici
Funzione ditrasferimento
Es.#define GODONE ADCON0bits.GO
#define ADON ADCON0bits.ADON
#define ADFM ADCON1bits.ADFM
void ADC_Init(void)
{
TRISA = 0b00000001; //1=input
ADCON1 = 0b00001110; //1=digital
//0=analog
ADFM=1; //10 bit
ADON=1;
}
int ADC_Convert(void)
{ GODONE=1; //faccio partire la
//conversione e
while(GODONE){} //aspetto che
//sia finita
return (ADRESH<<8)|ADRESL;
}
II Facoltà di Ingegneria
Università di Bologna
Scelta della frequenza di clock
Diverse modalità1. Quarzo esterno
(quando è richiestaprecisione ofrequenza elevate)
2. Generatore di ondaquadra esterno (es.quando lo stesso clockdeve arrivare a più dispositivi)
3. Oscillatore con RC esterno(semplice ed economico manon troppo preciso e stabile)
4. Oscillatore interno configurabile(non servono componenti esterni,ed è possibile solo un insieme limitato di frequenze)
II Facoltà di Ingegneria
Università di Bologna
Le interruzioni
Un meccanismo molto potente nella
programmazione dei microcontrollori è la
gestione delle interruzioni (interrupt)
à In risposta ad eventi esterni, il micro sospende
l’esecuzione del programma principale, esegue
apposite routine di servizio, e poi ritorna
all’esecuzione principale
à Es. Posso programmare una periferica Timer
(contatori) per generare un interrupt ogni secondo.
Il micro può ad es. avere un programma principale
in cui legge dati continuamente da un sensore con
l’ADC e, ogni secondo grazie all’interrupt,
aggiornare un display con l’indicazione dell’ora.
II Facoltà di Ingegneria
Università di Bologna
Gestione delle interruzioni Al RESET il micro esegue
l’istruzione contenuta alla locazione 0000H (detta reset vector)
Il RESET vector causa un salto all’entry point main 0020H, il programma inizia ad essere eseguito
Se durante l’esecuzione si verifica un interrupt a bassa priorità il micro automaticamente salta all’indirizzo 0018H ed esegue l’istruzione ivi contenuta
Un nuovo salto ci porta all’indirizzo 0040H dove risiede la procedura di gestione degli interrupt
Verificando i FLAG è possibile capire quale periferica ha fatto scattare l’interruzione, per poi eseguire la routine corrispondente
Terminata la routine di gestione il micro ritorna al punto del programma in cui era stato interrotto
memoria codiceindirizzo
0000H
0008H
0018H
0020H
GOTO 0020H reset vector
High priority
int. vector
Low priority
int. vector
GOTO 0040H
0040H
main program
start
GOTO 0040H
main:
inizializzazioni;
GIE=1;
while (1)
{ main loop; }
Check interrupt flag
if TMRIF==1
Routine_Timer;
if ADCIF==1;
Routine_ADC;
II Facoltà di Ingegneria
Università di Bologna
Gestione delle interruzioni Esempio#include <p18C452.h>
void main (void);
void InterruptHandlerHigh (void);
// Definisco l’high priority interrupt vector
#pragma code InterruptVectorHigh = 0x08
void InterruptVectorHigh (void)
{
_asm
goto InterruptHandlerHigh//jump to interrupt routine
_endasm
}
// Definisco la routine di servizio
#pragma code
#pragma interrupt InterruptHandlerHigh
void InterruptHandlerHigh ()
{
if (INTCONbits.TMR0IF)
{ //check for TMR0 overflow
INTCONbits.TMR0IF = 0; //clearint.flag
Flags.Bit.Timeout = 1; //indicate timeout
LATBbits.LATB0 = !LATBbits.LATB0;//toggle LED on RB0
}
}
union
{
struct
{
unsigned Timeout:1; //flag to indicate a TMR0 timeout
unsigned None:7;
} Bit;
unsigned char Byte;
} Flags;
//-------------------------------
// Main routine
Void main ()
{
// Inizializzazioni
Flags.Byte = 0;
INTCON = 0x20; //disable global and enable TMR0 interrupt
INTCON2 = 0x84; //TMR0 high priority
RCONbits.IPEN = 1; //enable prioritylevels
TMR0H = 0; //clear timer
TMR0L = 0; //clear timer
T0CON = 0x82; //set up timer0 -prescaler 1:8
INTCONbits.GIEH = 1; //enable interrupts
TRISB = 0;
while (1)
{
if (Flags.Bit.Timeout == 1)
{ //timeout?
Flags.Bit.Timeout = 0; //cleartimeout indicor
LATBbits.LATB7 = LATBbits.LATB0; //copy LED state from RB0 to RB7
}
}
}