Bonjour,
je réalise un convertisseur analogique numérique que je souhaite afficher sur un lcd 2*16.
Je travaille avec un pic 18f4550 sur MPLAB avec le compilateur C18. J'ai parcouru la datasheet du pic
qui donne en gros les étapes pas à pas pour faire le CAN, et un peu internet ce qui m'amène au code suivant
mais rien ne s'affiche.
Je suppose que celà doit venir de ADRESH et ADRESL qui ne se remplisse pas, puisque lorsque que je fais
varier mon potentiomètre (je suis sur une easypic5) les valeurs que j'envoie sur le PORTB ( au lcd ) ne
varie pas (même combinaison clignotante des LEDs ).
J'ai étudié le watch de MPLAB pour voir les changements de valeurs, mais sans résultat (je compile pas à pas mais vu que yah pas de source de tension en entrée,
j'imagine qu'ils (ADRESH et ADRESL) ne peuvent prendre aucune valeur).
Est ce que vous pourriez m'aider à comprendre ce qui ne va pas dans mon code, ou me donner une soltution pour tester
les registres ADRESH et ADRESL avec le watch .
Normalement le lcd marche convenablement, j'ai essayé d'entrer n'importe quel floatant et il me l'affiche.
/* Programmation d'un convertisseur analogique numérique avec affichage sur LCD pour le pic18f4550 */
// déclaration :
#include <p18f4550.h>
#include <stdio.h>
#include <string.h>
#include <delays.h>
#include <monlcd.h>
#pragma config WDT = OFF // WatchDog désactivé.
#pragma config LVP = OFF // Mode basse consommation désactivé.
#pragma config FOSC = INTOSC_HS // Oscillateur interne.
typedef unsigned char byte;
// pour le convertisseur A/D
void initAna(void);
// void test_cligno(int x);
void initInterrupt(void);
void SelectVoie(int voie);
void startConvert(void);
int lectAna();
int ana1 = 0;
float ana2 = 0;
float ana3 = 0;
void initAna(void){
/*
#byte ADCON0 = 0xFC2;
#byte ADCON1 = 0xFC1;
#byte ADCON2 = 0xFC0;
#byte TRISA = 0xF92;
*/
// En détail :
/* I -conf anal pin I/O ADCON1
Les bits 7 & 6 ne servent à rien.
Puis nous règlons les tensions de références : VCFG1 à VSS (à la masse) & VCFG0 à VCC
Puis nous mettons AN7 à AN0 en entrée analogique et le reste en sorti digitale pour le moment.
*/
// TRISAbits.TRISA0 = 1; // AN0 à AN3 en entrée
// TRISAbits.TRISA1 = 1; // AN0 à AN3 en entrée
// TRISAbits.TRISA2 = 1; // AN0 à AN3 en entrée
// TRISAbits.TRISA3 = 1; // AN0 à AN3 en entrée
// ADCON1 = 0b00001011; // AN0 à AN3 en entrée
/* II- Select A/D input ADCON0 */
// ADCON0bits.CHS0 = 0; // AN3 en entrée
// ADCON0bits.CHS1 = 0;
// ADCON0bits.CHS2 = 1;
// ADCON0bits.CHS3 = 1;
/* Selection de la clock d'acquisition => 16 Tad. */
// ADCON2bits.ADFM = 1; // ADRESH:ADRSL sont justifiés à droite
// ADCON2bits.ACQT0 = 0;
// ADCON2bits.ACQT1 = 1;
// ADCON2bits.ACQT2 = 1;
/* Selection de la clock d'acquisition => Fosc/64 */
// ADCON2bits.ADCS0 = 0;
// ADCON2bits.ADCS1 = 1;
// ADCON2bits.ADCS2 = 1;
/* Activer le module A/D */
// ADCON2bits.ADFM = 1; // ADRESH:ADRSL sont justifiés à droite
// ADCON0bits.ADON = 1; // A/D activé.
// ADCON0bits.GO_DONE = 0; // GO/DONE = 0 conversion terminé.
// résumé :
TRISA = TRISA|0x0F;
ADCON1 = 0x0B;
ADCON2 = 0xBE;
ADCON0 = 0b00110000;
}
// Défini les paramètres interruptions avant la conversion.
void initInterrupt(void)
{
PIR1bits.ADIF = 0; // met le flag à 0.
PIE1bits.ADIE = 1; // active le flag d'interruption ?.
INTCONbits.GIE = 1; // active les interruptions ?.
}
// Sélection de la voie :
void selectVoie(int voie)
{
// #byte ADCON0 = 0xFC2;
/* Nous décalons de deux bits vers la gauche pour se placer au niveau des bits de sélection de voie du registre ADCON0
le masque & 0x3C est utilisé pour mettre les autres bits à 0 puis un masque OU avec ADCON0 pour garder les autres bits
(7 6 2 et 1) du registre ADCON1*/
ADCON0 = ADCON0|((voie<<2) & 0x3C);
}
// Nous démarrons la conversion en mettant le bit GO/DONE à 1 grace au masque | 0x01.
void startConvert(void)
{
ADCON0 = ADCON0|0x02;
}
/* Récuperation de ADRESH:ADRESL dans un long, nous plaçons les bits de poids forts en premier
puis nous les décalons vers la gauche de 8bits, puis nous mettons les bits de poids faible */
int lectAna()
{
// #byte ADRESH = 0xFC3;
// #byte ADRESL = 0xFC4;
int lectTemp = 0;
lectTemp = ADRESH;
lectTemp = ((lectTemp<<8) & 0xFF00) + ADRESL; // lectTemp << 8; // décalage à gauche, les bits faibles sont remis à 0 au cas ou...
return lectTemp;
}
void finConv(void)
{
// #byte ADCON0 = 0xFC2;
//Test sur GO/DONE, tant qu'il est à l'état haut, le while attends la fin de la conversion
while(ADCON0bits.GO_DONE == 1){};
}
void main(void)
{
initAna();
config();
clearDisplayDebut();
initLcd();
display_on();
curseurGauche();
clearDisplay();
curseurDroite();
clearDisplay();
position(0x06);
while(1)
{
clearDisplay();
selectVoie(0);
startConvert();
finConv();
ana1 = lectAna();
ana2 = (5*ana1)/1024.000;
waitData();
afficheFloat(ana2,4);
// Delay10KTCYx(1);
//ana2 = (ana1*5)/1024; // affichage en décimal.
// position(0x46);
// waitData();
// afficheFloat(50.2,4);
Delay10KTCYx(10);
}
}
-----