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 ---
Forum général sur le langage C !

Modérateur : Jérémy

Configuration ADC avec un Vref 2.48 V
TheTimax
Membre
Membre
Messages : 6
Enregistré en : janvier 2017

#21 Message par TheTimax » sam. 7 janv. 2017 00:02

Ok, je peux donc voir que les ports sont bien configurés...

Oui, comme indiqué page 140:
The time to complete one bit conversion is defined as
TAD. One full 10-bit conversion requires 11.5 TAD periods
as shown in Figure 16-2.


Ils disent que pour accomplir une conversion de 10bits, il faut 11.5 TAD...

Comme tu as 3 valeurs possibles dans ce tableau pour une fréquence de 8 Mhz, j'opterais pour celle du milieu, 2µs (fosc/16). Plus rapide, tu risques de ne pas laisser le temps au module ADC d'effectuer la conversion...

Configuration ADC avec un Vref 2.48 V
Jérémy
Administrateur du site
Administrateur du site
Messages : 2722
Âge : 44
Enregistré en : juillet 2015
Localisation : Dans le sud
Contact :

#22 Message par Jérémy » sam. 7 janv. 2017 07:49

Bonjour à tous,

Des fois la nuit porte conseil, des fois non . J'ai essayé toutes les fréquences de Tad , sans succès je reste figé autour de 512 !!!

Quoi que je fasse, rien ne change.

Voici ma configurration pour démarrer correctement :

Code : Tout sélectionner

//##############################################################################
//############################     MAIN     ####################################
//##############################################################################
void main(){

  
ANSELA 0b00000010;  // RA1 en Analogique
  
ANSELB 0;           // PORTB en Digital
  
TRISB 0b00000010;   // RB1 en entrée
  
TRISA 0b00000010;   // RA1 en entrée le reste en sortie

  
OSCCON =  0b01110110 // Pll disable; Freq=8Mhz; OSC:intern

//------------------------------------------------------------------------------
// Réglages du Timer 1 pour 100 ms
  
TMR1IE_bit 0;    // désactiver au départ
  
T1CON      0x21;
  
TMR1IF_bit 0;
  
TMR1H      0x3C;
  
TMR1L      0xB0;

//------------------------------------------------------------------------------
// Réglages du Timer 0 pour 1 ms
  
TMR0IE_bit 0;    // désactiver au départ
  
OPTION_REG 0x82// Presacler 1:8
  
TMR0       6;    // Offset
  
TMR0IF_bit 0;

//------------------------------------------------------------------------------
// INTCON  =  Réglages des interruptions
  
RCIE_bit 1;            // INT sur Rx UART activé
  
PEIE_bit  1;           // INT péripheriques Activé
  
GIE_bit   1;           // INT Global activé

//------------------------------------------------------------------------------
  
UART1_Init(9600);   // Initialisation de l'UART
  
Delay_ms(100);

//------------------------------------------------------------------------------

  
C1ON_bit 0;    // Désactive les comparateurs
  
C2ON_bit 0;

  
// Configuration de l'ADCON0
  
ADCON0 0b00000101;  //AN1  est selectionné, ADC enable
  
  // Configuration de l'ADCON1
  
ADCON1 0b11010011;  // Right jsutified, Fosc/16, ref du moins=GND,  REF+ par FVR reglé sur 2.048V

  // Configuration de Vref
  
FVREN_bit 1;  // Activation du Vref
  
FVRRDY_bit 1;      // Pret a etre utilisé
  
TSEN_bit 0;
  
TSRNG_bit 0;
  
CDAFVR0_bit 0;
  
CDAFVR1_bit 0;
  
ADFVR0_bit 0// Mise du Vref à 2.048V
  
ADFVR1_bit 1// ADFVR = 0b10
  
  //ADC_Init_Advanced(_ADC_INTERNAL_VREFL &_ADC_INTERNAL_FVRH2);

  
Envoi_tension 1;
  
Delay_ms(100);
  
Lecture_T2();
   


LA fonction Lecture_T2();

Code : Tout sélectionner

//------------------------------------------------------------------------
void Lecture_T2(){
   
int Tension 0;

   while(
1){
           
Tension =  ADC_Read(1);
            if (
Tension >= 1000){
                
Rouge 1;
               }
             else if (
Tension >= 950){
                
Orange 1;
               }
              else if (
Tension >= 500){
                
Jaune 1;
               }
             else if (
Tension 500){
                
Vert 1;
               }
             
delay_ms(300);
             
Rouge Orange Jaune Vert 0;
             
delay_ms(100);
      }



LA réaction en tournant le Potar reste toujours la même , la led passe de vert à jaune et vice versa.
Pour regarder la valeur, j'ai changer mon programme pour m'envoyer un sms avec la valeur réelle lue. Il m'envoie donc des valeurs entre 460 et 510 grosso-modo.

Quand ce fonctionnera, je devrais voir la led rouge ou orange s'allumer, me signifiant que la valeur lue est proche de 1024 , car ma batterie est pleine.

J'aurais donc une tension présente sur ma PIN AN1 de 2.1V environ ( 4.2V / 2 par le pont). donc avec une référence de 2.048 je devrais être a fond !
C'est en faisant des erreurs, que l'on apprend le mieux !!!

Configuration ADC avec un Vref 2.48 V
Jérémy
Administrateur du site
Administrateur du site
Messages : 2722
Âge : 44
Enregistré en : juillet 2015
Localisation : Dans le sud
Contact :

#23 Message par Jérémy » sam. 7 janv. 2017 08:18

J'ai beau tourné ma configuratio dans les sens rien n'y fait !!!

J'ai pourtant tout verifié plusieurs fois, je vois pas ou est le probléme !
Je n'utilise aucune focntion du compilateur pourtant.

Code : Tout sélectionner


  C1ON_bit 
= 0;    // Désactive les comparateurs
  C2ON_bit = 0;

  // Configuration de l'ADCON0  ------------------------------------
                        // bit 7 non utilisé
                        // CHS<4:0> = choix du canal AN1  = 00001
  ADCON0 = 0b00000101;  // Go/~DONE = ? je met 0 dans le doute
                        // ADON = 1, activation du module AD
                        
  
// Configuration de l'ADCON1  --------------------------------------
                        // ADFM = 1, justification à droite
                        // ADCS<2:0>= 001, Fosc/8
  ADCON1 = 0b10010011;  // bit 3 non utilisé
                        // ADNREF = 0, ref- = GND
                        // ADPREF = 11, REF+ = FVR ( reglé sur 2.048V)

  // Configuration de Vref  -----------------------------------------
                         //  FVREN_bit = 1;   // Activation du Vref
                         //  FVRRDY_bit = 1;  // Pret a etre utilisé
                         //  TSEN_bit = 0;
   FVRCON = 0b11000010 ; //  TSRNG_bit = 0;
                         //  CDAFVR0_bit = 0;
                         //  CDAFVR1_bit = 0;
                         //  ADFVR1_bit = 1;  // ADFVR = 0b10
                          // ADFVR0_bit = 0;  // Mise du Vref à 2.048V

C'est en faisant des erreurs, que l'on apprend le mieux !!!

Configuration ADC avec un Vref 2.48 V
TheTimax
Membre
Membre
Messages : 6
Enregistré en : janvier 2017

#24 Message par TheTimax » sam. 7 janv. 2017 08:22

Bonjour!

C'est vrai que la nuit est souvent bonne conseillère mais ont ne peut pas toujours compter sur elle... :(

Jérémy a écrit :Source du message FVRRDY_bit = 1;      // Pret a etre utilisé


Ceci est inutile, dans la datasheet il est spécifié:

Note 1: FVRRDY is always ‘1’ on devices with LDO (PIC16F1847).


Ce qui veut dire que sur ton PIC il est toujours a 1... De plus ce bit doit etre poolé, genre:

Code : Tout sélectionner

while(FVRRDY_bit != 1){

asm{NOP}



Je ne suis pas très fort en électronique analogique mais il me semble que ton montage de potar est un peu bancale. As tu essayé de l'utilisé autrement?
Genre d'un coté a la masse, l'autre au +5v via une résistance "talon" et son curseur sur l'entré analogique?
As tu aussi essayé de prendre ton +5v sur une source autre qu'une sortie de ton pic?

Bonne journée

Configuration ADC avec un Vref 2.48 V
Jérémy
Administrateur du site
Administrateur du site
Messages : 2722
Âge : 44
Enregistré en : juillet 2015
Localisation : Dans le sud
Contact :

#25 Message par Jérémy » sam. 7 janv. 2017 08:45

Le Potar est monté en résistance variable. J'ai vérifié hier soir au mulitmetre justement .

La tension arrivant sur ma PIN analogique varie bien de 2.1 à 1.8V grosso-modo .
La tension sortant de ma PIN RA0 ( recopie de Vbat et donc de Vdd) est bien de 4.15V .

Je pense que cette partie est bonne, j'avoue que sur le schéma j'ai mis un potar à la place d'une R variable ! Je souhaitais me rapprocher au plus prêt du montage final . qui aura un pont diviseur de 4.7K pour chaque résistance, divisant ainsi la Tension par deux.

Je pense à un truc, mais je ne vois pas pourquoi ca boguerais. La tension lue est peut-etre supérieur a 2.048V . donc j'ai plus que 1024 en valeur ? ca peut faire boger ca ?

Ou alors peut être que HULK28 parlait de la fonction ADC_Read qui ne prends pas en compte le VFR ?
Mais comment faire une fonction de lecture ?
C'est en faisant des erreurs, que l'on apprend le mieux !!!

Configuration ADC avec un Vref 2.48 V
Jérémy
Administrateur du site
Administrateur du site
Messages : 2722
Âge : 44
Enregistré en : juillet 2015
Localisation : Dans le sud
Contact :

#26 Message par Jérémy » sam. 7 janv. 2017 09:22

Mais comment faire une fonction de lecture ?


Le travail paye !!!!

Au lieu d'utiliser la fonction de lecture ADC_read, j'ia également fait ca manuellement, et vous savez quoi ! ca fonctionne enfin !!!

On place le bit Go/~DONE à 1 pour démarrer une conversion
Ce bit est automatiquement effacé quand la conversion est finie (p.145)
Il stock les valeurs dans les registres ADRESH et ADRESL.
Comme j'ai configurer une justifcation a droite , je mulitplie par 256 le registre de gauche pour obtenir les bonnes valeurs

Code : Tout sélectionner

//------------------------------------------------------------------------
void Lecture_T2(){
   int Tension = 0;

   while(1){
           
           ADCON0
.B1 = 1;     // On démarre la conversion
           while (ADCON0.B1==1); // J'attends que le bit soit effacer à la fin de la conversion
           
           Tension 
= ( (ADRESH*256) + (ADRESL) ); // j'enregistre les registres en valeur
            
            if 
(Tension >= 1010){
                Rouge = 1;
               }
             else if (Tension >= 990){
                Orange = 1;
               }
              else if (Tension >= 970){
                Jaune = 1;
               }
             else if (Tension < 970){
                Vert = 1;
               }
             delay_ms(300);
             Rouge = Orange = Jaune = Vert = 0;
             delay_ms(100);
      }
}
C'est en faisant des erreurs, que l'on apprend le mieux !!!

Configuration ADC avec un Vref 2.48 V
Guest
Confirmé
Confirmé
Messages : 800
Enregistré en : mars 2017

#27 Message par Guest » sam. 7 janv. 2017 09:53

Bonjour et :bravo: tu vas y arriver :lol:

A+

PS seule remarque je ne peux ... ta multiplication par 256 AVEC DES ROTATIONS

Configuration ADC avec un Vref 2.48 V
HULK28
Avatar de l’utilisateur
Amateur
Amateur
Messages : 106
Enregistré en : août 2015
Localisation : IdF

#28 Message par HULK28 » sam. 7 janv. 2017 10:31

TheTimax a écrit :Dans l'aide MikroC concernant la librairie ADC, tu peux lire concernant la fonction ADC_Read() que:

"This function doesn't work with the external voltage reference source, only with the internal voltage reference."

Je ne suis pas trés fort en anglais mais je pense que ton problème vient de la... Tu va devoir récupérer ta valeur ADC par les registres directement...



Bonjour,

oui c'est ce que je disais dans mon post.
Pour utiliser l'ADC avec ref interne il faut écrire une fonction, la fonction toute faite de MikroC ne sait pas faire cela, donc pas question d'utiliser Adc_Read().
"Pour la carotte, le lapin est la parfaite incarnation du mal" -Robert Shecley-

Configuration ADC avec un Vref 2.48 V
Jérémy
Administrateur du site
Administrateur du site
Messages : 2722
Âge : 44
Enregistré en : juillet 2015
Localisation : Dans le sud
Contact :

#29 Message par Jérémy » sam. 7 janv. 2017 10:39

Hum.....

Je suis une buse aussi en anglais mais :
La traduction veut dire, que cette fonction(on parle de ADC_read) ne fonctionne PAS avec la référence EXTERNE non ? seulement avec le Référence interne ?
Donc elle devrait fonctionner avec une référence interne de VFR non ?

En tout cas, il est vrai que ça fonctionne pas avec ADC_Read, bien vu HULK28 et merci

@Maï : tu as raison, je peux simplifier et optimiser comme ceci :

Code : Tout sélectionner

//------------------------------------------------------------------------
void Lecture_T2(){
   int Tension = 0;

   while(1){
           
           ADCON0
.B1 = 1;     // On démarre la conversion
           while (ADCON0.B1); // J'attends que le bit soit effacer à la fin de la conversion
           
           Tension 
= (ADRESH<<8) + ADRESL; // j'enregistre les registres en valeur
            
            if 
(Tension >= 1010){
                Rouge = 1;
               }
             else if (Tension >= 990){
                Orange = 1;
               }
              else if (Tension >= 970){
                Jaune = 1;
               }
             else if (Tension < 970){
                Vert = 1;
               }
             delay_ms(300);
             Rouge = Orange = Jaune = Vert = 0;
             delay_ms(100);
      }
}


Il ne me reste plus qu'à faire une moyenne sur 8 valeurs pour sortir une valeur cohérente.
Ensuite je fais faire des paliers pour faire une estimation en % de la batterie et le tour sera joué.

En // je prépare un Tutoriel la dessus.... :-D . Si une âme charitable voudrait jeter un oeil dessus avant publication se sera sympa ( me contacter en MP), histoire que je ne publie pas d'énorme bêtise ! Je m'occupe de toute la partie chiante y'aura juste à corriger
C'est en faisant des erreurs, que l'on apprend le mieux !!!

Configuration ADC avec un Vref 2.48 V
HULK28
Avatar de l’utilisateur
Amateur
Amateur
Messages : 106
Enregistré en : août 2015
Localisation : IdF

#30 Message par HULK28 » sam. 7 janv. 2017 11:14

Par exemple:

Code : Tout sélectionner


typedef union _ADCResult{
  int Tr;
  char Br[2];
}ADCResult;

ADCON0 = 0b00000000;
ADCON1 = 0b11010010; // Ref externe et Fosc/16

PIE1bits.ADIE = 1;

......

static unsigned int ReadADCchannel(char channel)
{
  unsigned int   adc_value;
  ADC_Result res;
  char  i;
       
  ADCON0 = (channel << 2) | 0x01;
       
  for (i = 0; i < 30; i++)  // Sample & Hold acquisition time
    Nop();
       
  ADCON0bits.GO = 1;
  while(ADCON0bits.GO == 1);
  res.Br[0] = ADRESL;       // Read ADRESL ->lower byte
  res.Br[1] = ADRESH;       // Read ADRESH -> high byte
  adc_value = res.Tr;        // résultat total
       
  return(adc_value);
}

// exemple d'utilisation:
unsigned int mesure_Volt (void)
{
static char i;
unsigned int result;

long val_temp;
float val_volt;

val_temp = 0;
  for(i = 0; i < 16 ; i++)
  {
  val_temp += ReadADCchannel(10); // exemple avec channel 10
  }
  val_temp >>= 4;  // On divise par 16
  val_volt = (val_temp * 5.0)/4096.0;
 

  result =  (unsigned int) val_volt;


return result;
}


Code non testé à adapter selon le µC...
"Pour la carotte, le lapin est la parfaite incarnation du mal" -Robert Shecley-


Retourner vers « Langage C »

Qui est en ligne

Utilisateurs parcourant ce forum : Aucun utilisateur enregistré et 24 invités