Bienvenue aux nouveaux arrivants sur FantasPic !
- Pensez à lire les règles durant votre visite, il n'y en a pas beaucoup, mais encore faut-il les respecter .
- N’hésitez pas à faire des remarques et/ou suggestions sur le Forum, dans le but de l'améliorer et de rendre vos prochaines visites plus agréables.
- Vous pouvez regarder votre "panneau de l'utilisateur" afin de configurer vos préférences.
- Un passage par "l'utilisation du forum" est recommandé pour connaître les fonctionnalités du forum.
--- L’équipe FantasPic ---
- Pensez à lire les règles durant votre visite, il n'y en a pas beaucoup, mais encore faut-il les respecter .
- N’hésitez pas à faire des remarques et/ou suggestions sur le Forum, dans le but de l'améliorer et de rendre vos prochaines visites plus agréables.
- Vous pouvez regarder votre "panneau de l'utilisateur" afin de configurer vos préférences.
- Un passage par "l'utilisation du forum" est recommandé pour connaître les fonctionnalités du forum.
--- L’équipe FantasPic ---
Modérateur : Jérémy
Problème de lecture d'un ADC - PIC16F1783
Bonjour à toutes et à tous,
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é :
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;
}
Vous n’avez pas les permissions nécessaires pour voir les fichiers joints à ce message.
Modifié en dernier par Alex le mar. 3 avr. 2018 09:50, modifié 1 fois.
Problème de lecture d'un ADC - PIC16F1783
-
Jérémy
Administrateur du site- Messages : 2725
- Âge : 45
- Enregistré en : juillet 2015
- Localisation : Dans le sud
- Contact :
En tout cas j'ai rpis la peine de regaerder ( ce qui n'empeche de modifier ton premier message ... ) , et je vois ceci :
Code : Tout sélectionner
TRISB = 0b00010000; // Setting RB3 as input
ANSELB = 0b00010000; // Setting RB3 as analog input
Avec ce code tu mets RB4 en entrée analogique et non RB3
Problème de lecture d'un ADC - PIC16F1783
Bonjour Jérémy, et merci de ta réponse.
J'ai modifié la configuration des entrées comme tu me l'as indiqué. Erreur bête de ma part.
Même avec cette modification, j'ai toujours un phénomène étrange.
Quand je lis la valeur de la tension lue, celle ci est parfois correcte, mais monte parfois à 65 XXX sans raison.
Je suppose que cela est dû à un overflow, mais je ne saisi pas exactement comment résoudre ce problème.
J'ai modifié la configuration des entrées comme tu me l'as indiqué. Erreur bête de ma part.
Même avec cette modification, j'ai toujours un phénomène étrange.
Quand je lis la valeur de la tension lue, celle ci est parfois correcte, mais monte parfois à 65 XXX sans raison.
Je suppose que cela est dû à un overflow, mais je ne saisi pas exactement comment résoudre ce problème.
Problème de lecture d'un ADC - PIC16F1783
- paulfjujo
Expert- Messages : 2597
- Âge : 73
- Enregistré en : juillet 2015
- Localisation : 01800
- Contact :
bonjour,
la declaration de variable doit etre faite en tete de programme , si globale
ou en tete du main
mais pas, en cours d'execution, dans une boucle while
Code : Tout sélectionner
while(1) {
UINT16 value = ADCRead();
}
la declaration de variable doit etre faite en tete de programme , si globale
ou en tete du main
mais pas, en cours d'execution, dans une boucle while
Problème de lecture d'un ADC - PIC16F1783
Problème de lecture d'un ADC - PIC16F1783
- paulfjujo
Expert- Messages : 2597
- Âge : 73
- Enregistré en : juillet 2015
- Localisation : 01800
- Contact :
Microchip recommande de mettre un NOP ou 2 entre l'armement du bit GO et sa lecture
tu peux toujours essayer ceci..
mikroC permet l'insertion d'instructio asm ou un Delay_us(2);
tu peux toujours essayer ceci..
mikroC permet l'insertion d'instructio asm ou un Delay_us(2);
Code : Tout sélectionner
ADCON0bits.GO = 1; //Start ADC conversion
_asm NOP;
while(ADCON0bits.GO){}; // Wait for conversion to be done
Problème de lecture d'un ADC - PIC16F1783
Problème de lecture d'un ADC - PIC16F1783
- paulfjujo
Expert- Messages : 2597
- Âge : 73
- Enregistré en : juillet 2015
- Localisation : 01800
- Contact :
au vu de la datasheet fig 17-3 page 143
tu fais une lecture en complement à 2
le bit 12 est repété 3 fois à gauche coté poids fort => debordement
il faut masquer ARDESH avec 0x1F
rajouter ADRESL
complementer le tout à 2
tu veux bien un resultat 12Bits signé ou non signé 0 à 4095 ?
ce qui me parait bizarre sur la datasheet c'est qu'ils representes bit 0 à bit 11 => 12bits + bit12 =signe
chez moi ça fait 13 bits ???
j'avais pas lu la suite ..
ce serait donc un ADC13 bits !!
Note 1: For the RSD ADC, the raw 13-bits from the ADC is presented in 2’s compliment format, so no data
translation is required for 2’s compliment results.
par contre , le resultat doit etre dans un Signed int 16 !
tu fais une lecture en complement à 2
le bit 12 est repété 3 fois à gauche coté poids fort => debordement
il faut masquer ARDESH avec 0x1F
rajouter ADRESL
complementer le tout à 2
tu veux bien un resultat 12Bits signé ou non signé 0 à 4095 ?
ce qui me parait bizarre sur la datasheet c'est qu'ils representes bit 0 à bit 11 => 12bits + bit12 =signe
chez moi ça fait 13 bits ???
j'avais pas lu la suite ..
ce serait donc un ADC13 bits !!
Note 1: For the RSD ADC, the raw 13-bits from the ADC is presented in 2’s compliment format, so no data
translation is required for 2’s compliment results.
par contre , le resultat doit etre dans un Signed int 16 !
Modifié en dernier par paulfjujo le mar. 3 avr. 2018 11:35, modifié 1 fois.
Problème de lecture d'un ADC - PIC16F1783
Oui, je souhaite bien avoir un résultat compris entre 0 et 4095.
Si j'ai bien compris, je dois modifier la partie où je récupère la valeur de ADRESH et ADRESL comm ceci :
Si j'ai bien compris, je dois modifier la partie où je récupère la valeur de ADRESH et ADRESL comm ceci :
Code : Tout sélectionner
ADCON0bits.GO = 1; //Start ADC conversion
NOP();
NOP();
while(ADCON0bits.GO != 0){}; // Wait for conversion to be done
Acqu_value = 0x0000;
Acqu_value = ADRESH && 0x001F;
Acqu_value = Acqu_value<<8;
Acqu_value += ADRESL;
Acqu_avg += Acqu_value;
}
Problème de lecture d'un ADC - PIC16F1783
- paulfjujo
Expert- Messages : 2597
- Âge : 73
- Enregistré en : juillet 2015
- Localisation : 01800
- Contact :
c'est ce que je pensais ,il y a quelques minutes , mais
la suite 17-2 montre un resultat DEJA NORMALISE en +-12 bits , soit 13 bits
Resultat signé => utiliser alors un signed int 16 ..
j"ai deja utilisé un ADC12 bits sur un PIC18F2523 ..mais ce n'etait pas un 13 bits !
la suite 17-2 montre un resultat DEJA NORMALISE en +-12 bits , soit 13 bits
Resultat signé => utiliser alors un signed int 16 ..
j"ai deja utilisé un ADC12 bits sur un PIC18F2523 ..mais ce n'etait pas un 13 bits !
Qui est en ligne
Utilisateurs parcourant ce forum : Aucun utilisateur enregistré et 52 invités