Estratto del documento

Guida veloce alla programmazione della scheda LandTiger V2.0 LPC17XX

ALCUNE REGOLE DEL C ............................................................................................................................................................ 1

LED ......................................................................................................................................................................................... 6

BUTTON_EINT ......................................................................................................................................................................... 8

INTERRUPT CONTROLLER....................................................................................................................................................... 13

CLOCK ................................................................................................................................................................................... 17

TIMER ................................................................................................................................................................................... 24

JOYSTICK ............................................................................................................................................................................... 39

RIT ........................................................................................................................................................................................ 40

ADC E POTENZIOMETRO ........................................................................................................................................................ 46

ASSEMBLY ............................................................................................................................................................................. 48

ESERCIZI ................................................................................................................................................................................ 62

FUNZIONI RIUTILIZZABILI ARM .............................................................................................................................................. 76

APPENDICE ............................................................................................................................................................................ 90

Alcune regole del C

• Tipo signed int (interi predefiniti) è formata da un certo numero di bit, rappresentati in complemento a due.

• Tipo unsigned int è formata da un certo numero di bit in binario naturale

• Tipo char (signed o unsigned) è formata da un certo numero di bit in complemento a due o in binario

naturale. In genere sono otto bit, ma non è un'affermazione assoluta. Quindi non serve solo per i caratteri

ASCII

• Tipo long int è formata da un certo numero di bit, in quantità maggiore o uguale a quelli presenti in un int

Il C non definisce la lunghezza di nessuno di ques interi; per esempio un int, a seconda del compilatore (e della sua

configurazione...) potrebbe per esempio avere una lunghezza variabile tra 8, 16, 32 o 64 bit. Utile la funzione sizeof().

uint8_t

uint16_t

uint32_t = unsigned int

int8_t

int16_t

int32_t

__int24 (non standard, specifico di XC8)

__uint24 (non standard, specifico di XC8)

Esempio d'uso:

int8_t simple_byte; // simple_byte potrà contenere valori compresi tra -128 e +127

uint16_t simple_word; // simple_word potrà contenere valori compresi tra 0 e 65535

Tipo C Bit Byte (spostamento Istruzione Load Istruzione Store (Salva) -

puntatore) (Carica) - ARM ARM

/ 8 1 (Byte) (Byte)

char int8_t LDRB STRB

/ 16 2 (Half-word) (Half-word)

short int16_t LDRH STRH

/ /float/ 32 4 (Word) (Word)

int long int32_t LDR STR

double LDRD STRD

64 8

Floating point single NON C’È IN ARM IL

32 4

precision FLOATING POINT

1

Floating point double 64 8

precision LDR STR

(es. ) 32 4

pointer int*

L’ondina si fa con AltGr + ì oppure Alt + 126

Variabili

Volatile

Dire al compilatore che una variabile è volatile significa: "Non ottimizzare questa variabile, perché il suo valore può

cambiare all'improvviso all'esterno del flusso normale del programma".

Normalmente, il compilatore cerca di rendere il codice più veloce. Se vede che leggi una variabile molte volte senza

mai modificarla esplicitamente nel main, il compilatore potrebbe decidere di copiarla in un registro della CPU (molto

veloce) e non andarla più a leggere nella RAM (più lenta).

Usando volatile, obblighi la CPU a rileggere il valore dalla memoria RAM ogni singola volta che viene usata,

garantendo che il valore sia sempre quello più aggiornato.

Static

A differenza delle variabili locali comuni (automatiche), che vengono distrutte al termine di una funzione, una variabile

dichiarata come static mantiene il suo valore tra una chiamata e l'altra. Viene allocata in una zona di memoria fissa

(Segmento Dati) e non nello stack e viene inizializzata una sola volta all'avvio del programma. È estremamente utile

nelle ISR (Interrupt Service Routines): ad esempio, se vuoi contare quante volte è stato premuto un pulsante o quante

volte è scattato un timer senza usare una variabile globale che sia visibile a tutto il progetto.

2

L'uso della parola chiave static serve anche a limitare l'accesso ai dati, seguendo il principio dell'incapsulamento:

• Static locale: Definita all'interno di una funzione, è visibile solo lì, ma "ricorda" lo stato precedente.

• Static globale: Definita all'inizio di un file .c, rende la variabile (o la funzione) privata per quel file. Nessun altro

file del progetto potrà vederla o modificarla tramite la parola chiave extern.

Maschere e shift

Nei sistemi embedded, spesso riceviamo dati a 32 bit, ma abbiamo bisogno di isolare solo un "pezzo" (un byte) per

controllare periferiche come i LED. Per farlo, usiamo due strumenti principali: lo Shift e la Maschera.

Lo shift a destra serve a "spostare" il byte che ci interessa verso le posizioni più basse (a destra), in modo che diventi

l'LSB (Least Significant Byte, ovvero gli ultimi 8 bit a destra).

- Se il byte è tra i bit 15-8, facciamo num >> 8.

- Se il byte è tra i bit 31-24, facciamo num >> 24.

Anche dopo lo shift, potrebbero esserci dei bit "residui" a sinistra. Usando l'operazione & 0xFF (che in binario è

11111111), "cancelliamo" tutto ciò che si trova oltre l'ottavo bit, tenendo solo il valore puro del byte scelto.

Per azzerare si usa l’AND (&): Se vogliamo azzerare i 16 bit meno significativi mantenendo invariati i 16 bit più

significativi, usiamo la maschera 0xFFFF0000. L'AND con F (tutti 1) mantiene il valore originale, l'AND con 0 impone

lo 0. Esempio: 0xABCDFEDE & 0xFFFF0000 = 0xABCD0000.

Per impostare a 1 si usa l’OR (|): Se vogliamo forzare a 1 gli ultimi 8 bit senza toccare il resto, usiamo la maschera

0x000000FF. L'OR con 0 mantiene il valore originale, l'OR con 1 forza il bit a 1.

Esempio: 0xABCDCABB | 0x000000FF = 0xABCDCAFF.

Operazione Simbolo Scopo Principale Effetto con la Maschera

&

AND Reset (Azzera); (Mantiene)

x & 0 = 0 x & F = x

|

OR Set (Setta a 1); (Mantiene)

x | F = F x | 0 = x

^

XOR Invert Inverte i bit dove la maschera è 1

⟷ 1)

~

NOT Reverse Ribalta l'intero byte (0

Esempio: LED_Out(~(num & 0xFF)); //Contenuto negato dell'LSB

Questa riga di codice isola l’LSB (gli ultimi 8 bit del numero) e inverte tutti i bit del risultato con ~.

Perché si nega? Sulla scheda LandTiger (e molte altre), i LED sono spesso collegati in logica negata: si accendono

quando il segnale è 0 e si spengono quando è 1. Negando il valore con ~, facciamo in modo che se il bit è 1, il LED

corrispondente si accenda effettivamente.

Numeri in complemento a due −1

−2

Per un numero a N bit il MSB ha peso negativo (pari a ) e gli altri bit hanno peso positivo. Ne consegue che il

MSB indica sempre il segno (0=+, 1=-).

2

Numeri rappresentabili con N bit: -1

Il più grande numero negativo rappresentabile è 1 seguito da tutti zeri (100..0), che ha un contributo positivo pari a

zero. ̿ ̅

= 2 − = +1.

Dato un numero binario A in N bits, il suo complemento a due si esprime con:

3

I numeri positivi sono identici alla rappresentazione binaria standard. Invece, per ottenere un numero negativo -X, si

prende il binario di X, si invertono tutti i bit e si aggiunge 1.

Esempio: su 8 bit 5 è 00000101

Inverto: 11111010 →

Aggiungo 1: 11111011 corrisponde a -5 in CA2

Non bisogna fare calcoli manuali per convertire i numeri, se ne occupa il processore, a patto di usare le istruzioni di

salto corrette:

- Confronto: Quando usi CMP R1, R2, il processore aggiorna i flag di stato.

- Salto per numeri con segno: Per i numeri int (con segno), devi usare:

o BGT (Branch if Greater Than) invece di BHI.

o BLT (Branch if Less Than) invece di BLO.

o BGE / BLE (Greater/Less or Equal).

- Estensione del segno: Se carichi un byte o un half-word e vuoi mantenere il segno, usa LDRSB o LDRSH.

Caricando un int a 32 bit con LDR, il segno è già preservato correttamente.

La scheda

Quando dobbiamo leggere un segnale da un pin (ad esempio la pressione di un tasto), abbiamo due strategie

principali: il Polling e l'Interruzione Esterna (EINT).

• Il Polling è un processo software sincrono in cui la CPU verifica periodicamente lo stato dei registri delle

periferiche. In questa modalità, configuriamo il pin come funzione GPIO (impostando i bit a 00 nel registro

PINSEL) e specifichiamo che la sua direzione è in ingresso agendo sul registro FIODIR (bit a 0). Dal punto di

vista del codice, il processore entra in un ciclo infinito (come un while(1)) e interroga continuamente il

registro FIOPIN per vedere se il valore è cambiato.

o Sebbene semplice da implementare, risulta inefficiente in termini di consumo energetico e

prestazioni, a causa dell'alta latenza e dell'impossibilità di gestire carichi annidati.

• L'interruzione (EINT) è un meccanismo hardware asincrono in cui le periferiche (UART, GPIO, Timer)

interagiscono direttamente con la CPU. Questo permette al processore di entrare in modalità Idle e di

attivarsi solo quando è richiesto un servizio specifico, garantendo efficienza e bassa latenza.

o In questo caso, non usiamo il pin come un semplice GPIO, ma attiviamo una sua Funzione Speciale

tramite il registro PINSEL (ad esempio selezionando EINT0, EINT1, ecc.). È l'hardware stesso che

"osserva" il pin; non appena avviene un cambiamento di stato (un fronte di salita o di discesa), il

modulo EINT invia un segnale immediato al processore.

Al reset tutti I pin sono impostati GPIO 4

Questa tabella decide "chi comanda il pin". Ogni pin fisico ha 2 bit dedicati in questo registro per scegliere tra 4 funzioni

possibili.

• Valore 00: Il pin è un GPIO (General Purpose I/O). Lo controlli tu manualmente tramite i registri della seconda

tabella.

• Valore 01, 10, 11: Il pin viene "ceduto" a una periferica interna (PWM, UART, o EINT per le interruzioni esterne).

• Nota importante: Se selezioni una funzione diversa da GPIO, il controllo della direzione (input/output) diventa

automatico e gestito dalla periferica stessa.

I seguenti registri funzionano soltanto se in PINSEL hai scelto la modalità GPIO (00).

• FIODIR: Imposta se il pin è un'entrata (bit a 0) o un'uscita (bit a 1).

o Ad es per usare i LED, che stanno sulla porta 2, usiamo il registro FIO2DIR. Anche i pulsanti sono sulla

porta 2.

• FIOSET: Scrivere '1' qui porta il pin a livello ALTO (3.3V).

• FIOCLR: Scrivere '1' qui porta il pin a livello BASSO (0V). Comodo perché non devi preoccuparti di fare

operazioni logiche (AND/OR) per spegnere un solo bit.

• FIOPIN: Serve per leggere lo stato attuale del pin o scriverlo direttamente.

5

LED

Lib_led.c

volatile unsigned char led_value;

void LED_init(void)

Il codice configura i pin dei led come uscite digitali.

LPC_PINCON->PINSEL4 &= 0xFFFF0000;

Azzera i primi 16 bit del registro PINSEL4. Gli ultimi 16 bit (quelli con F) rimangono invariati. Guardando la Tabella 84,

i bit da 0 a 15 controllano i pin da P2.0 a P2.7. Mettendoli a 00, stai dicendo al chip: "Voglio che questi 8 pin siano

normali GPIO, non PWM o altro".

LPC_GPIO2->FIODIR |= 0x000000FF; 6

Mette a '1' i primi 8 bit del registro di direzione della PORTA 2 (Gli altri bit dal 9 al 31 rimangono come erano prima).

Secondo la tabella dei registri GPIO, il bit a '1' in FIODIR imposta il pin come Output. Ora i LED possono ricevere

corrente.

LPC_GPIO2->FIOSET = 0x000000FF;

Scrive '1' sui primi 8 bit del registro SET della PORTA 2. Questa operazione porta i pin corrispondenti (P2.0...P2.7) a

livello logico ALTO (3.3V), accendendo tutti i LED contemporaneamente. A differenza del registro FIOPIN, scrivere '0'

in questo registro non ha alcun effetto sui pin, il che permette di accendere bit specifici senza modificare lo stato

degli altri.

LPC_GPIO2->FIOCLR = 0x000000FF;

Scrive '1' sui primi 8 bit del registro CLEAR. Spegne tutti i LED portando i pin a 0V (assumendo che i LED siano

collegati verso massa). Nota che scrivi 1 per pulire (portare a 0) lo stato del pin.

void LED_deinit(void)

LPC_GPIO2->FIODIR &= 0xFFFFFF00;

Riporta i primi 8 bit a '0'. Trasforma i pin da Output a Input. In modalità input, il pin è "inerte" (alta impedenza) e non

pilota più il LED, risparmiando energia o evitando stati elettrici indesiderati quando il driver viene spento.

Funct_led.c

const unsigned long led_mask[] = { 1UL<<0, 1UL<<1, 1UL<<2, 1UL<< 3, 1UL<< 4,

1UL<< 5, 1UL<< 6, 1UL<< 7 };

Crea una "mappa" dei bit. 1UL<<0 significa "prendi il numero 1 e spostalo di 0 posizioni" (resta 1), 1UL<<1 lo sposta

di 1 posizione (diventa 2), e così via. Questo array serve a identificare esattamente quale pin della Porta 2

corrisponde a quale LED.

void LED_On(unsigned int num)

Accende il LED numero num (da 0 a 7).

Comando Indice (num) Bit Maschera Pin LPC1798 Nome LED sulla scheda

LED_On(0) 0 1 << 0 P2.0 LD11 è quello più a destra

LED_On(1) 1 1 << 1 P2.1 LD10

LED_On(2) 2 1 << 2 P2.2 LD9

LED_On(3) 3 1 << 3 P2.3 LD8

LED_On(4) 4 1 << 4 P2.4 LD7

LED_On(5) 5 1 << 5 P2.5 LD6

LED_On(6) 6 1 << 6 P2.6 LD5

LED_On(7) 7 1 << 7 P2.7 LD4

LPC_GPIO2->FIOPIN |= led_mask[num];

Usa l'operatore |= (OR) per mettere a '1' solo il bit corrispondente al LED scelto nel registro FIOPIN. Questo porta il

pin a 3.3V senza spegnere gli altri LED che sono già accesi.

led_value = LPC_GPIO2->FIOPIN; 7

Legge lo stato attuale di tutti i pin della porta e aggiorna la variabile globale led_value.

void LED_Off(unsigned int num)

Spegne il LED numero num.

LPC_GPIO2->FIOPIN &= ~led_mask[num];

Qui usa l'operatore &= ~ (AND NOT). Prima "inverte" la maschera (tutti 1 tranne il bit del LED scelto) e poi fa l'AND. Il

risultato è che solo il bit scelto diventa '0', spegnendo il LED, mentre gli altri restano invariati.

void LED_Out(unsigned int value)

Questa funzione permette di visualizzare un numero binario (da 0 a 255) sugli 8 LED.

for (i = 0; i < LED_NUM; i++): Un ciclo che controlla ogni singolo bit del numero value.

if (value & (1<<i)): Controlla se l'i-esimo bit del numero passato è '1'. Se lo è, chiama LED_On(i),

altrimenti chiama LED_Off(i).

In pratica, se passi il valore 3 (che in binario è 00000011), si accenderanno i LED 0 e 1, cioè i LED11 e LED10.

void LED_Out_Inv(unsigned int value)

Fa esattamente la stessa cosa di LED_Out, ma inverte l'ordine dei LED.

LED_On (LED_NUM - i - 1): Invece di accendere il LED i, accende quello dalla parte opposta.

Se il bit 0 è '1', invece di accendere il LED11 (P2.0), accenderà il LED4 (P2.7).

Button_EINT

Quando usi un pulsante con le interruzioni, non ti limiti a leggere "se il tasto è premuto", ma chiedi al processore di

reagire a un evento di transizione (il passaggio da 0 a 1 o viceversa).

Per i pulsanti sulla tua scheda, devi prima di tutto "dire" al pin di non comportarsi più come un normale GPIO, ma

come un ricevitore di interruzioni.

• Pulsante INT0: Si trova sul pin P2.10. Guardando la tabella PINSEL4, devi impostare i bit 21:20 al valore 01

per attivare la funzione EINT0.

• Pulsante KEY1: Si trova su P2.11. Devi impostare i bit 23:22 di PINSEL4 a 01 per attivare EINT1.

• Pulsante KEY2: Si trova su P2.12. Devi impostare i bit 25:24 di PINSEL4 a 01 per attivare EINT2.

Nota: Se lasciassi 00, il pin sarebbe un GPIO e dovresti usare il Polling che abbiamo visto prima.

I pulsanti della tua scheda lavorano in logica negativa:

• Rilasciato: Il pin legge 1 (3.3V).

• Premuto: Il pin viene collegato a massa e legge 0 (0V).

Per gestire questo, nel registro di configurazione dell'interruzione (EXTMODE e EXTPOL), devi decidere se

l'interruzione deve scattare sul Livello (mentre tieni premuto) o sul Fronte (nell'istante esatto in cui premi). Di solito

si sceglie il Fronte di Discesa (Falling Edge), perché è il momento in cui il segnale passa da 1 a 0 (ovvero quando

premi il tasto).

Il registro EXTINT funge da "bandierina" (flag). Quando premi il tasto e avviene la transizione, l'hardware mette a 1 il

bit corrispondente in questo registro. Importante: Finché non "pulisci" questa bandierina scrivendoci sopra un 1, il

processore crederà che il tasto sia ancora in fase di pressione e continuerà a generare interruzioni.

8

Il registro E

Anteprima
Vedrai una selezione di 20 pagine su 91
Architetture dei sistemi di elaborazione - Il manuale definito per l'esame Pag. 1 Architetture dei sistemi di elaborazione - Il manuale definito per l'esame Pag. 2
Anteprima di 20 pagg. su 91.
Scarica il documento per vederlo tutto.
Architetture dei sistemi di elaborazione - Il manuale definito per l'esame Pag. 6
Anteprima di 20 pagg. su 91.
Scarica il documento per vederlo tutto.
Architetture dei sistemi di elaborazione - Il manuale definito per l'esame Pag. 11
Anteprima di 20 pagg. su 91.
Scarica il documento per vederlo tutto.
Architetture dei sistemi di elaborazione - Il manuale definito per l'esame Pag. 16
Anteprima di 20 pagg. su 91.
Scarica il documento per vederlo tutto.
Architetture dei sistemi di elaborazione - Il manuale definito per l'esame Pag. 21
Anteprima di 20 pagg. su 91.
Scarica il documento per vederlo tutto.
Architetture dei sistemi di elaborazione - Il manuale definito per l'esame Pag. 26
Anteprima di 20 pagg. su 91.
Scarica il documento per vederlo tutto.
Architetture dei sistemi di elaborazione - Il manuale definito per l'esame Pag. 31
Anteprima di 20 pagg. su 91.
Scarica il documento per vederlo tutto.
Architetture dei sistemi di elaborazione - Il manuale definito per l'esame Pag. 36
Anteprima di 20 pagg. su 91.
Scarica il documento per vederlo tutto.
Architetture dei sistemi di elaborazione - Il manuale definito per l'esame Pag. 41
Anteprima di 20 pagg. su 91.
Scarica il documento per vederlo tutto.
Architetture dei sistemi di elaborazione - Il manuale definito per l'esame Pag. 46
Anteprima di 20 pagg. su 91.
Scarica il documento per vederlo tutto.
Architetture dei sistemi di elaborazione - Il manuale definito per l'esame Pag. 51
Anteprima di 20 pagg. su 91.
Scarica il documento per vederlo tutto.
Architetture dei sistemi di elaborazione - Il manuale definito per l'esame Pag. 56
Anteprima di 20 pagg. su 91.
Scarica il documento per vederlo tutto.
Architetture dei sistemi di elaborazione - Il manuale definito per l'esame Pag. 61
Anteprima di 20 pagg. su 91.
Scarica il documento per vederlo tutto.
Architetture dei sistemi di elaborazione - Il manuale definito per l'esame Pag. 66
Anteprima di 20 pagg. su 91.
Scarica il documento per vederlo tutto.
Architetture dei sistemi di elaborazione - Il manuale definito per l'esame Pag. 71
Anteprima di 20 pagg. su 91.
Scarica il documento per vederlo tutto.
Architetture dei sistemi di elaborazione - Il manuale definito per l'esame Pag. 76
Anteprima di 20 pagg. su 91.
Scarica il documento per vederlo tutto.
Architetture dei sistemi di elaborazione - Il manuale definito per l'esame Pag. 81
Anteprima di 20 pagg. su 91.
Scarica il documento per vederlo tutto.
Architetture dei sistemi di elaborazione - Il manuale definito per l'esame Pag. 86
Anteprima di 20 pagg. su 91.
Scarica il documento per vederlo tutto.
Architetture dei sistemi di elaborazione - Il manuale definito per l'esame Pag. 91
1 su 91
D/illustrazione/soddisfatti o rimborsati
Acquista con carta o PayPal
Scarica i documenti tutte le volte che vuoi
Dettagli
SSD
Ingegneria industriale e dell'informazione ING-INF/05 Sistemi di elaborazione delle informazioni

I contenuti di questa pagina costituiscono rielaborazioni personali del Publisher Monica56789 di informazioni apprese con la frequenza delle lezioni di Architetture dei sistemi di elaborazione e studio autonomo di eventuali libri di riferimento in preparazione dell'esame finale o della tesi. Non devono intendersi come materiale ufficiale dell'università Politecnico di Torino o del prof Bernardi Paolo.
Appunti correlati Invia appunti e guadagna

Domande e risposte

Hai bisogno di aiuto?
Chiedi alla community