In questa pagina è descritto come usare l'ADC with computation module interno al PIC18F2xK42insieme a MPLAB Code Configurator. Prima di proseguire, consiglio la lettura di Usare l'ADC con MCC - Utilizzo di base
L'ADCC del PIC18F2xK42 permette di effettuare una serie di operazioni indipendentemente dalla CPU. Due i vantaggi:
In questa pagina è descritta (al momento...) una sola modalità di funzionamento:
La struttura di un ADCC è costituta:
Questa modalità permette di effettuare automaticamente la media tra N misure di tensione, al fine di migliorare il rapporto segnale rumore della misura. La configurazione dell'ADCC può essere fatta con MCC:
Sono evidenziati i tre parametri specifici di questa modalità:
Il codice non è molto diverso rispetto all'uso della modalità base dell'ADCC:
void main(void) {
volatile float VoltageAcc, VoltageLowNoise, Voltage;
SYSTEM_Initialize(); // Initialize the device
while (1) {
Voltage = ADCC_GetSingleConversion(A0);
// Start AD conversion and get last ADC result
if (!ADCC_HasAccumulatorOverflowed())
{ // Accumulator overflow?
VoltageLowNoise = ADCC_GetFilterValue(); // Get average value
VoltageAcc =
ADCC_GetAccumulatorValue(); // Get accumulato value
}
NOP();
__delay_ms(100);
}
}
Ovviamente il tempo di conversione è pari alla somma dei tempi di conversione singoli; con i numeri mostrati servono circa 2,8 ms.
Da notare che è necessario usare la funzione MCC ADCC_GetSingleConversion() per avviare la serie delle conversioni, azzerare automaticamente ADACC e ADCNT, attendere il termine della conversione multipla; successivamente occorre leggere il registro ADFLTR e/o ADACC con le funzioni MCC corrispondenti; è inoltre necessario verificare che non ci sia stato un overflow nel registro ADACC, cosa possibile se si sommano molti valori e questi sono grandi (nota 2).
L'uso della media permette di migliorare il rapporto segnale/rumore. Non ho fatto misure rigorose, ma indicativamente il passaggio dal singolo campione alla media di 16 oppure 64 valori porta il SNR da 71 dB a 81 dB a 88 dB, rispettivamente (nota 3).
Una delle cause del rumore di conversione è il funzionamento stesso della CPU. Per questo è una buona idea spegnere il processore mentre funziona l'ADC. Al termine della conversione una interruzione risveglierà la CPU che riprenderà il programma dove era stato sospeso
Per fare ciò è possibile configurare l'ADCC sia in Basic Mode che in Burst Average, come mostrato nelle due figure seguenti, alternative tra di loro:
Ho evidenziato nelle immagini precedenti alcune particolarità:
La lettura può essere fatta con una funzione simile alla seguente, scritta sulla falsariga di quella presente in MCC, scegliendo il valore di ritorno a cui si è interessati:
adc_result_t ADCC_LowNoise(adcc_channel_t channel) {
CPUDOZEbits.IDLEN = 0; // Sleep CPU, not doze
ADPCH = channel; // select the A/D channel
ADCON0bits.ADON = 1; // Turn on the ADC module
ADCON0bits.ADCONT = 0; //Disable the continuous mode.
ADCON0bits.ADGO = 1; // Start the conversion
SLEEP(); // Sleep CPU. Wakeup from interrupt
return (ADCC_GetConversionResult()); // Conversion finished, return the result
(single conversion)
// return (ADCC_GetFilterValue()); // Conversion finished, return the result
(average)
}
Due le differenze:
Il main() è praticamente identico al precedente, con l'unica avvertenza di attivare le interruzioni:
void main(void) {
volatile float ADCmeas;
SYSTEM_Initialize(); // Initialize the device
INTERRUPT_GlobalInterruptHighEnable(); // Enable high
priority global interrupts
while (1) {
ADCmeas = ADCC_LowNoise(channel_Temp);
}
NOP();
__delay_ms(10);
}
Si noti l'assenza di Interrupt Service Routine in quanto l'unica funzione della interruzione è il risveglio del processore.
Anche in questo caso non ho misure definitive sul miglioramento del SNR. Nel test preliminare ed usando il riferimento interno per misurare la temperatura, ho osservato un miglioramento del SNR di 3 dB abbondanti usando la modalità SLEEP. Si tratta comunque di misure da prendere con le pinze in quanto realizzate utilizzando un debugger e quindi in condizioni piuttosto diverse da quelle un circuito reale.
Data di creazione di questa pagina: luglio 2019
Ultima modifica: 26 luglio 2019
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