Je viens vous faire part d'un problème que je rencontre lors de la programmation d'un AD sur mon PIC16F1783.
Après lecture de la datasheet, et une programmation minutieuse des différents registres, je me retrouve bloqué lors de l'expérimentation.
En effet, le mode debug qui me permet de voir la valeur lue par l'ADC à chaque conversion ne fait que m'indiquer la valeur maximale de 4096.
Ayant d'abord pensé à un problème hardware, j'ai testé plusieurs exemplaires du PIC16F1783 sans succès. J'ai mesuré la tension arrivant sur la pin de mesure, et obtenu une valeur de 3V, correspondant bien à ce qui était envoyé par le circuit.
Le problème me semble donc venir de mon programme.
Le PIC est programmé avec une fréquence d’acquisition de 4MHz, avec la PLL activée (ce qui nous porte à 16 MHz).
L'ADC est configuré avec 12 bits de précision, le résultat étant"right justified". Sa fréquence de fonctionnement est Fosc/16, qui d'après la datashhet doit être supérieur à 15 Tad.
La broche d'entrée est AN9 (RB3), et les tensions de références sont calquées sur Vss et Vdd.
Y-a-t-il une subtilité que je n'aurais pas saisie et qui pourrait justifier mon erreur ?
Je vous mets en pièce jointe le projet MPLAB X correspondant, pour vous éclaircir.
D'avance, je vous remercie du temps que vous prendrez pour analyser mon problème.
************** EDIT **************
Voici le code entre balises, pour une meilleur lisibilité :
Code : Tout sélectionner
/*
* File: main.c
* Author: Alexandre
*
* Created on 21 mars 2018, 16:41
*/
#define _XTAL_FREQ 32000000
#pragma config CLKOUTEN = OFF
#pragma config WDTE = OFF
#pragma config PWRTE = OFF
#pragma config CP = OFF
#pragma config BOREN = ON
#pragma config FCMEN = OFF
#pragma config MCLRE = ON
#pragma config CPD = OFF
#pragma config IESO= OFF
#pragma config FOSC = INTOSC
#pragma config STVREN = ON
#pragma config LPBOR = OFF
#pragma config BORV = HI
//#pragma configLVP = OFF
#pragma config WRT = OFF
#pragma config PLLEN = ON // PLL activée
#include <xc.h>
#include <pic16f1783.h>
#include "types_defines.h"
void chenilliard(void);
void ADCInit(void);
UINT16 ADCRead(void);
void main(void) {
// Configuration du port B
TRISB = 0b00001000; // Setting RB3 as input
ANSELB = 0b00001000; // Setting RB3 as analog input
// Clock configuration
OSCCONbits.IRCF = 0b1101; // Fosc = 4Mhz (à multiplier par 4 car PLL)
OSCCONbits.SCS1 = 1; // Internal osscilator source
ADCInit();
while(1) {
UINT16 value = ADCRead();
}
return;
}
/*void chenilliard() {
while(1) {
PORTBbits.PORTB = 0x01;
for (int i=0; i<8; i++) {
__delay_ms(3000);
PORTBbits.PORTB= PORTBbits.PORTB*2;
}
}
} */
void ADCInit(){
// ADCON0 Configuration
ADCON0bits.ADRMD = 0; //Précision 12 bits
ADCON0bits.CHS = 0b01001; // Pin selection AN9 (RB3)
// ADCON1 configuration
ADCON1bits.ADFM = 1; // 2's comlimentright justified
ADCON1bits.ADCS = 0b101; // Clock conversion, à calculer : Fosc/16 : 1µs
ADCON1bits.ADNREF = 0; // Vref- connected to Vss
ADCON1bits.ADPREF = 0b00; // Vref+ connected to Vdd
// ADCON2 Configuration
ADCON2bits.TRIGSEL = 0b1111; // Auto conversion enable
ADCON2bits.CHSN = 0b1111; // ADC Negative reference selected by ADNREF
}
UINT16 ADCRead(void)
{
UINT8 j;
UINT16 Acqu_value = 0;
UINT16 Acqu_avg = 0;
__delay_us(50);
//On moyenne sur 8 mesures consécutives
ADCON0bits.ADON = 1; // ADC ON
for (j=0;j<8;j++) {
__delay_ms(500);
ADRESH = 0x0000;
ADRESL = 0x0000;
ADCON0bits.GO = 1; //Start ADC conversion
while(ADCON0bits.GO){}; // Wait for conversion to be done
Acqu_value = 0x0000;
Acqu_value = ADRESH;
Acqu_value = Acqu_value<<8;
Acqu_value += ADRESL;
Acqu_avg += Acqu_value;
}
ADCON0bits.ADON = 0; // ADC OFF
//Moyennage sur 8 valeurs
Acqu_avg = Acqu_avg>>3;
return Acqu_avg;
}
