Questa pagina descrive l'uso dei moduli Timer1 e ECCP (Enhanced Capture, Compare, and PWM) in modalità Compare Mode.
Timer1, per alcuni aspetti, è simile a Timer0. Le differenze più importanti:
L'uso di Timer1 con le stesse modalità già viste per Timer0 è lasciato come esercizio.
Il modulo (E)CCP modulo, in collaborazione con TImer1 oppure TImer3 permette di generare forme d'onda complesse senza interveto del software secondo le tre modalità di compare, capture e PWM.
In particolare il modulo CCP in modalità compare, insieme a Timer1, permette di generare in modo totalmente hardware frequenze programmabili. Questo da una parte semplifica il lavoro del PIC18, dall'altra permette di generare intervalli temporali la cui precisione dipende esclusivamente da quella del clock.
Due sono i blocchi fondamentali:
Il codice di esempio, riportato a fondo pagina, configura CCP e Timer1 per generare in hardware ad intervalli regolari un interrupt che alternativamente accende e spegne un LED.
Il circuito è costituito semplicemente un LED ed una resistenza connessi a PORTC0:
Esaminiamo il codice. La funzione main():
La lettura o la scrittura di un contatore a 16 bit usando registri a 8
bit è sempre problematico: infatti è possibile che, durante la lettura dei
primi 8 bit, gli altri 8 cambino, "facendo il giro" (rollover) e dando un
risultato completamente errato. Una soluzione è fermare il timer prima di
leggere o scrivere; un'altra soluzione è attivare la seguente opzione e
prestare attenzione al fatto di leggere prima il byte basso e poi quello
alto:
T1CONbits.RD16 = 1; // Enables register read/write of TImer1 in one
16-bit operation
In questo esempio è indifferente, dato che Timer1 non è mai letto o scritto.
Vogliamo utilizzare come clock per Timer1 il clock di sistema (nel caso
specifico: 1 MHz / 4 = 250 KHz), senza prescaler:
T1CONbits.T1CKPS = 0; // 1:1 Prescaler value
T1CONbits.T1RUN = 0; // Main system clock is derived from another source
T1CONbits.TMR1CS = 0; // Internal clock (FOSC /4)
T1CONbits.T1OSCEN = 0; // Timer1 oscillator is shut off
Prima dell'uso è inoltre necessario attivare Timer1
T1CONbits.TMR1ON = 1; //Enables Timer1
Si osservi che Timer1 non deve generare alcune interrupt
Utilizzeremo questo modulo con due scopi:
Innanzitutto configuriamo il modulo CCP:
CCP1CONbits.CCP1M = 0b1011; //Compare mode, trigger special event
(ECCP resets TMR1 or TMR3, sets CC1IF bit)
Inoltre è necessario associare il modulo CCP1 a Timer1 (esistono infatti,
con caratteristiche simili, per esempio anche CCP2 e Timer3)
T3CONbits.T3CCP1 = 0b01; // Timer1 is the capture/compare clock source for
CCP1
Infine impostiamo il valore che farà scattare il reset, 50000
nell'esempio
CCPR1H = TIMER1_VALUE >> 8;
CCPR1L = TIMER1_VALUE & 0xFF;
Il modulo CCP deve essere configurato per generare un interrupt dopo
50000 conteggi. Scegliamo di utilizzare interrupt ad alta priorità:
IPR1bits.CCP1IP = 1; // CCP1 Interrupt Priority set to highc
PIE1bits.CCP1IE = 1; // Enables the CCP1 interrupt
Occorre evidentemente anche abilitare le interruzioni
RCONbits.IPEN = 1; // Enable priority levels on interrupts
INTCONbits.GIEH = 1; // Enables all interrupts
A questo punto l'attività del main() termina
L'attività della ISR è particolarmente semplice:
Un approfondimento sull'argomento. Un altro esempio, associato all'uso dell'ADC lo trovate in questa pagina.
Il modulo ECCP è molto più flessibile di quanto mostrato: si legga quanto proposto nell'approfondimento.
Data di creazione di questa pagina: settembre 2014
Ultima modifica: 29 febbraio 2016
PIC18 in C - Versione 0.991 - luglio 2019
Copyright 2014-2019, Vincenzo Villa (https://www.vincenzov.net)
PIC18 in C di Vincenzo Villa è distribuito con Licenza Creative Commons Attribuzione 4.0 Internazionale