IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Embarqué Discussion :

Convertisseur AN ne change pas de channel de lecture [PIC]


Sujet :

Embarqué

  1. #1
    Nouveau Candidat au Club
    Profil pro
    Inscrit en
    Mars 2013
    Messages
    2
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2013
    Messages : 2
    Points : 1
    Points
    1
    Par défaut Convertisseur AN ne change pas de channel de lecture
    Bonjour à tous,

    Dans un premier temps, merci à ceux qui prendront le temps de lire ceci et de m'aider.

    Avant de poser ma question, voici le détail de mon application:
    - J'utilise un µC PIC16F1937-I/P en 40 broches que je programme avec MPLAB IDE via un ICD 3 de microchip. Le compilo utilisé est HI-TEC-C.
    - L'application est relativement simple, il s'agit d'une lecture analogique de 3 tensions (un réglage de vitesse via un potentiomètre sur RA0/AN0, un niveau de luminosité via une LDR sur RA1/AN1, une température via une CTN sur RA2/AN2).
    - Le schéma HW est celui-ci:
    Nom : Schéma elec.png
Affichages : 147
Taille : 15,0 Ko

    J'ai dans un premier temps paramétré l'ADC et mes ports comme suit (Je mets le paramétrage en entier mais seul le PORTA vous interessera):
    Code c : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
     
    void main(void)
    {
    //ADC configuration
    ADCON0=0;	// select Fosc/2
    ADCON1=0;	// select left justify result. A/D port configuration 0
    ADON=1;		// turn on the A2D conversion module
     
    //Définition des E/S pour chaque Port
    ANSELA = 0b00000111; //RA0, RA1 et RA2 en analogique. 1 = Analogique
    ANSELB = 0x00; //Port B en numérique. 0 = Numérique
    ANSELE = 0x00; //Port E en numérique.
     
    TRISA = 0b10111111; //RA6 en sortie. 1 = Entrée, 0 = sortie
    TRISB = 0x00; //Port B en sortie
    TRISC = 0x00; //Port C en sortie
    TRISD = 0x00; //Port D en sortie
    TRISE = 0b00000111; //RE0 RE1 et RE2 en entrée,
    }


    J'ai dans un second temps, intégrer la fonction locale (en dehors du main) read_a2d qui est la suivante:
    Code c : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    //Fonction locale n°1A : Lecture tension analogique
    unsigned char read_a2d(unsigned char channel)
    {
    	channel&=0x07;	// truncate channel to 3 bits
    	ADCON0&=0xC5;	// clear current channel select
    	ADCON0|=(channel<<3);	// apply the new channel select
    	ADGO=1;	// initiate conversion on the selected channel
    	while(ADGO)continue;
    	return(ADRESH);	// return 8 MSB of the result
    }


    Puis une fois cela fait, j'ai ensuite écrit les 3 fonctions locales (en dehors du main) permettant de lire la LDR, le potentiomètre et la CTN. Et c'est là que vous allez constater mon gros level en C ;-)
    Code c : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    //Fonction locale n°1B : Lecture_consigne_vitesse
    unsigned char lecture_consigne_vitesse(void)
    {
    	tension_vitesse = read_a2d(0); //Lecture tension potar vitesse sur RA0/AN0.
    	return(tension_vitesse); //Renvoi de la valeur.
    }

    Code c : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    //Fonction locale n°1C : Mesurer la luminosité ambiante
    unsigned char mesurer_luminosite(void)
    {
    	tension_ldr = read_a2d(1); //Lecture tension LDR sur RA1/AN1.
    	return(tension_ldr); //Renvoi de la valeur.
    }

    Code c : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    //Fonction locale n°1D : Mesurer la température sur CTN
    unsigned char mesurer_temperature(void)
    {
    	tension_ctn = read_a2d(2); //Lecture tension CTN sur RA2/AN2.
    	return(tension_ctn); //Renvoi de la valeur.
    }


    J'appelle ensuite ces 3 fonctions de manière régulière et indépendante dans une boucle while(1) lors de l'execution de mon programme. Sauf que voilà... il y a que la fonction Lecture_consigne_vitesse() sur la voie RAO/AN0 qui fonctionne, les autres ne fonctionnent pas.
    Les variables tension_ldr et tension_ctn restent à la valeur a laquelle elles ont été initiées lorsque je les ai créées...

    Après de multiples recherches sur le net, j'ai constaté que pour une lecture sur RA0/AN0, le paramètre "channel" de la fonction read_a2d(channel) est à 1. J'ai donc aussi essayé read_a2d(1) pour une lecture sur AN0/RA0 et là stupeur, la lecture du potentiomètre fonctionne toujours...

    Je suis donc incapable de sélectionner correctement le channel de l'ADC que je souhaite lire (AN0, AN1 ou AN2), et je soupçonne que la lecture sur AN0/RA0 écrase tout le reste, je sollicite donc votre aide car depuis le temps que je suis dessus, j'ai probablement perdu beaucoup de lucidité...

    Merci d'avance.

  2. #2
    Modérateur

    Avatar de Vincent PETIT
    Homme Profil pro
    Consultant en Systèmes Embarqués
    Inscrit en
    Avril 2002
    Messages
    3 190
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Pas de Calais (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Consultant en Systèmes Embarqués
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Avril 2002
    Messages : 3 190
    Points : 11 573
    Points
    11 573
    Par défaut
    Salut,
    Je n'ai pas encore eu le temps d'analyser toute l'initialisation cependant je vois au moins une erreur :

    Code C : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    unsigned char read_a2d(unsigned char channel)
    {
    	...
    	ADCON0|=(channel<<3);	// attention c'est (channel<<2)
    	...
    	...
    }

    Pour moi, channel doit être décalé de 2 et pas de 3. Sur l'image ci dessous, si tu veux sélectionner le canal 1 (AN1) il faut que la valeur binaire 00000001 soit décalée de 2 vers la gauche, soit 00000100 pour activer AN1. J'ai quelques questions, voir en bas du message (ça facilitera mon analyse, merci pour moi ) je pose des questions dans tes commentaires. // ton commentaire ====> Ma question


    Nom : image824.png
Affichages : 129
Taille : 162,5 Ko

    Code C : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    void main(void)
    {
    //ADC configuration
    ADCON0=0;	// select Fosc/2 ====> C'est pas plutôt dans ADCON1 qu'on règle ça ?
    ...
    ADON=1;		// turn on the A2D conversion module  ====> Je n'ai pas trouvé ce registre dans la datasheet ?
     
     
     
     
     //====> A partir de là je n'ai pas encore regarder mais je pense que ça doit être bon puisque tu arrives à faire des mesures
     
    //Définition des E/S pour chaque Port
    ...
    }

    Code C : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    //Fonction locale n°1A : Lecture tension analogique
    unsigned char read_a2d(unsigned char channel)
    {
    	channel&=0x07;	// truncate channel to 3 bits ====> Pourquoi pas
    	ADCON0&=0xC5;	// clear current channel select ====> Je ne comprends pas l'idée de faire ça ? Est ce que tu es bien dans le bon registre ?
    	...
    }
    La science ne nous apprend rien : c'est l'expérience qui nous apprend quelque chose.
    Richard Feynman

  3. #3
    Nouveau Candidat au Club
    Profil pro
    Inscrit en
    Mars 2013
    Messages
    2
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2013
    Messages : 2
    Points : 1
    Points
    1
    Par défaut
    Salut Vincent,

    Merci énormément pour ton aide et pour ton temps.

    J'ai corrigé l'erreur effectivement en décalant seulement de deux bits au lieu de trois.

    Tes interrogations m'ont aussi rappelé que je n'étais pas très clair dans la définition des registres ADCON0 et ADCON1. Je les ai donc re-définis à chaque début de fonction locale (avec la bonne sélection du channel concerné).

    Et bin tout fonctionne dorénavant ! Merci !

    Pour répondre à ta question ADON n'est pas un registre, c'est juste le bit 7 du registre ADCON pour activer la conversion analogique/numérique. Le compilo l'accepte en le nommant directement c'est plutôt pratique.

    Merci encore et bonne journée !

  4. #4
    Modérateur

    Avatar de Vincent PETIT
    Homme Profil pro
    Consultant en Systèmes Embarqués
    Inscrit en
    Avril 2002
    Messages
    3 190
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Pas de Calais (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Consultant en Systèmes Embarqués
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Avril 2002
    Messages : 3 190
    Points : 11 573
    Points
    11 573
    Par défaut
    Tant mieux si ça te va

    Pour les prochains sujets, si tu en créais, penses bien à cliquer sur le bouton "Résolu", en bas de la fenêtre, si c'est le cas.

    C'est important pour le fonctionnement du forum, ça permet à n'importe qui de voir qu'une solution a été trouvé. La personne sait tout de suite que même s'il y a 50 messages ça vaut le coup de tout lire. Je le fais pour toi cette fois ci

    A+
    La science ne nous apprend rien : c'est l'expérience qui nous apprend quelque chose.
    Richard Feynman

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 13
    Dernier message: 27/06/2006, 11h20
  2. Réponses: 4
    Dernier message: 04/06/2006, 14h35
  3. [WinCE/PDA] Pourquoi touche TAB ne change pas le focus ?
    Par zitoun dans le forum Windows Mobile
    Réponses: 7
    Dernier message: 24/04/2006, 09h26
  4. [POO] La valeur de l'attribut ne change pas...
    Par slydemusli dans le forum Langage
    Réponses: 3
    Dernier message: 26/03/2006, 12h10
  5. Frames : adresse ne change pas
    Par polo-j dans le forum Balisage (X)HTML et validation W3C
    Réponses: 6
    Dernier message: 14/02/2005, 16h56

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo