Bonjour
Voila je rencontre un problème pour traiter un signal analogique avec un pic16f877a. Pour mon montage je travaille avec une horloge externe à quartz de 16mzh avec des condensateur de 22pf. Le but est de récupérer un signal sur 5v, le convertir sur 10bits en justifiant sur ADRESH, j’ignore donc les 2bits faibles se trouvant dans ADRESL et renvoyer les 8bits de ADRESH sur PORTB pour allumer (ou non) 8 led et retrouver la valeur de ADRESH. J’ai aussi mis une led sur PORTC qui doit clignoter à chaque fois que le programme boucle.
Seulement voila, ma led sur PORTC clignote bien, j’ai bien les led de PORTB qui s’allument mais la valeur sur PORTB ne change pas. La led sur PORTC clignote également de facon irrégulière. Je pense à un problème d’horloge mais je suis incapable de comprendre ce qui ne va pas.
Voici mon code :
void main() {
TRISA = 1;
TRISB = 0;
TRISC = 0;
ADCON1 = 0x00;
ADCON0 = 0x80; //0b10000000 - Canal sur AN0
ADCON0.ADON = 1;
while(1)
{
PORTC.F0 = 1;
Delay_us(12);
ADCON0.GO = 1;
while(ADCON0 == 0b10000100){};
PORTB = ADRESH;
PORTC.F0 = 0;
delay_ms(500);
}
}
Quelqu’un peut il m’aider ?
Je ne comprends pas trop ce que vous voulez faire mais…
« while(ADCON0 == 0b10000100){}; » devrait plutôt être « while(ADCON0.GO){}; »
Ensuite « PORTB = ADRESH; » est vraiment très curieux.
Je veux convertir un signal analogique en valeur numérique sur 8bits et renvoyer cette valeur sur le PORTB pour allumer 8 led, chaque led correspondant à un bit, et ainsi avoir visuellement ma valeur numérique.
Pour le while je ne pensait pas qu’il pouvait traiter la valeur d’un bit en particulier d’un registre.
Pour « PORTB == ADRESH » le but est de renvoyer la valeur de mes 8bits de ADRESH sur les 8 sorties du PORTB.
Quand vous avez lancé la conversion AD, après avoir récupéré le résultat, il faut impérativement relancer une nouvelle acquisition.
Pour faire quelque chose de propre, le mieux est d’utiliser l’interruption par un timer, qui déclenche périodiquement une acquisition AD,en fonction de l’interval du timer.
Attention à bien passer sur BANK1 lors de l’initialisation d’ADCON1.
MOVLW B’10000001’ ;AN0 selected
;Conversion ended
;A/D module ON
MOVWF ADCON0 ;Enable A/D converter
;
BANK1
MOVLW B’01001110’ ;Left justified
;A0 only = analog input
MOVWF ADCON1 ;Others are digital
BANK0
; suite du programme
Je ne vois pas le bit 0 (ADON) de ADCON0 levé dans votre code. Donc le convertisseur n’est pas actif et la valeur du registre ADRESH ne changera jamais.
Comme le soulignait Maître @Blaireau (que je salue au passage), il est préférable d’éviter les appels aux fonctions delay_ et d’utiliser les interruptions d’un timer à la place.
bit 0 ADON: A/D On bit
1 = A/D converter module is powered up
0 = A/D converter module is shut-off and consumes no operating current
Merci pour vos réponses.
Donc si je comprend bien il faut que je passe le bit ADON de ADCON0 a 0 a la fin de l’acquisition, puis que je le repasse a 1 quand je veux recommencer une nouvelle acquisition et ainsi de suite. C’est bien ça ?
Pour les timer je sais pas encore bien m’en servir, c’est pour ça que je me sert des delay
@Blaireau pour le passage en BANK1 c’est en codant en assembleur. Moi je code en C. C’est à faire également quant tu code en C ? Si oui comment tu fais ?
J’ai écrit une macro.
La commutation se fait en modifiant les deux bits du registre d’état dédiés à cette fonction. (sur l’accu)
Idem pour BANK 2 et 3
Ces deux bits sont RP0 et RP1
Il n’est pas obligatoire de repasser le bit ADON à zéro entre 2 acquisitions. C’est utile pour économiser l’énergie car l’entrée de l’ADC consomme un peu quand elle est active.
Les timers c’est un peu la base des microcontrôleurs, l’autre étant les interruptions. Le démarrage avec des codes Arduino qui sont farcis de temporisations et de polling des ports en dur fait prendre de mauvais plis.
Vérification faite, il faut surveiller le bit 2 de ADCON0, qui passe à 0 quand l’acquisition est terminée, récupérer ADRESH, puis relancer une nouvelle acquisition en remettant ce bit à 1
En C cette gestion est transparente.
Je crois comprendre un peu mieux mais je n’arrive pas a saisir comment relancer une acquisition si on peut laisser ADON a l’état 1
C’est cette ligne qui déclenche l’acquisition.
Exact, et ce bit (2) de ADCON0 repasse a 0 quand l’acquisition est terminée.
Attention aussi aux 9 LED’s branchées sur les ports. Si ce sont des chinoises qui ne consomment quasi rien tout va bien, mais si ce sont sont des 10 ou 20mA rien ne va plus, il faut interposer des transistors pour ne pas dépasser le courant maxi permis.
Ou un ULN 2803A pour le port B, si vous préférez faire plus compact.
Mais donc étant donné que dans ma boucle je repasse ADCON0.GO sur 1 je relance bien une acquisition non ?
Pour les led c’est bien de la chinoiserie de chine
Peut-être, mais assurez vous qu’elle soit bien terminée, en relisant l’état du fameux bit 2, (a zéro), avant d’en renvoyer une autre, sans quoi le résultat dans ADRESH ne changera jamais.
Faites un polling du bit 2, plutôt qu’une tempo.