Problème au niveau de la conversion Analogique numérique par un PIC 16F690
-----
Problème au niveau de la conversion Analogique numérique par un PIC 16F690
Même pas bonjour ?
Problème au niveau de la conversion Analogique numérique par un PIC 16F690.
Pour expliquer un peu plus clairement mon problème , c'est que je reçois une tension proportionnelle à un courant que je reçois dans mon capteur à Effet Hall type LTS15(courant de décharge batteries), de l'ordre de 2.5V pour 0A et de 2.9V pour 7à8A. Je peux vous fournir des schémas si vous voulez voir plus clair. Mon problème est que je dois en sortie de mon CAN obtenir un donnée sur 4 Bits pour pouvoir envoyer sur un Encodeur type CTR44, mais que lorsque ma tension varie , j'effectue plusieurs cyle de conversion ( de 0x00 à 0xFF ) , environ 7 à 8 fois ...
Mon programme est le suivant :
\*============================ ============================== ============================== =================*/
// ENTREES - SORTIES
#define RC0 PORTC.0
#define RC1 PORTC.1
#define RC2 PORTC.2
#define RC3 PORTC.3 // Valeur numérique sur 4 bits
#define RC4 PORTC.4
#define RC5 PORTC.5
#define RC6 PORTC.6
#define RC7 PORTC.7
//============================== ============================== ============================== ================
// Constantes
//============================== ============================== ============================== ================
// Variables
//============================== ============================== ============================== ================
// DECLARATION DES FONCTIONS
void init0 (void); // Initialisation des registres du PIC au RESET
void tempo(); // Temporisation
/*============================= ============================== ============================== ================*/
/* PROGRAMME PRINCIPAL */
/*============================= ============================== ============================== ================*/
void main (void) // Début du programme principal
{
init0(); // Initialisation des registres du PIC au RESET
while(1) // Boucle de tâches:
{
tempo();
ADCON0 = ADCON0 | 0x02; // Début de conversion
ADCON0.1 = 1; // Début de conversion
while (ADCON0.1==0); // Attendre fin de conversion
PORTC.0 = ADRESH.0; // Recopie du résultat en sortie
PORTC.1 = ADRESH.1;
PORTC.2 = ADRESH.2;
PORTC.3 = ADRESH.3;
PORTC.4 = ADRESH.4;
PORTC.5 = ADRESH.5;
PORTC.6 = ADRESH.6;
PORTC.7 = ADRESH.7;
}
}
/*============================= ============================== ============================== ================*/
/* FONCTIONS */
/*============================= ============================== ============================== ================*/
// Initialisation des registres du PIC au RESET:
void init0 (void)
{
ANSEL = 0x01; // Entrée analogique sur RA0 uniquement
ANSELH = 0;
ADRESH = 0b00000000;
ADCON0 = 0b00000001; // Mise en marche du CAN ,canal 0 (RA0), VDD, Cadrage à gauche
TRISC = 0x00; // Configuration du PORTC en sortie
OPTION = 0b11000101; // Prédiviseur du timer = 32, entrée = clock/4
}
//============================== ============================== ============================== ================
// Temporisation de durée de 5µs pour la charge du condensateur:
void tempo()
{
nop();
nop();
nop();
nop();
nop();
}
Si vous avez des idées pour savoir comment m'en sortir je suis preneur .
Merci d'avance !
Excuse moi mais c'est parce que mon message c'etait envoyé trop vite , desolé !
BOnjour à tous et enchanté !
Salut à toi Spades92!!!
Et bien c'est cool pour toi, à mon avis cela viens.... de la configuration de ton microcontroleur, au PIF!Problème au niveau de la conversion Analogique numérique par un PIC 16F690
PS: Désolé, je n'ai pas vu ta réponse qui suivais , autant pour moi, je vais regarder ça.
Juste une rectification de mon programme d'origine , comme je suis sur une sortie obligatoire de 4 bits :
// ENTREES - SORTIES
#define RC0 PORTC.0
#define RC1 PORTC.1
#define RC2 PORTC.2
#define RC3 PORTC.3 // Valeur numérique sur 4 bits
//============================== ============================== ============================== ================
// Constantes
//============================== ============================== ============================== ================
// Variables
//============================== ============================== ============================== ================
// DECLARATION DES FONCTIONS
void init0 (void); // Initialisation des registres du PIC au RESET
void tempo(); // Temporisation
/*============================= ============================== ============================== ================*/
/* PROGRAMME PRINCIPAL */
/*============================= ============================== ============================== ================*/
void main (void) // Début du programme principal
{
init0(); // Initialisation des registres du PIC au RESET
while(1) // Boucle de tâches:
{
tempo();
ADCON0 = ADCON0 | 0x02; // Début de conversion
ADCON0.1 = 1; // Début de conversion
while (ADCON0.1==0); // Attendre fin de conversion
PORTC.0 = ADRESH.0; // Recopie du résultat en sortie
PORTC.1 = ADRESH.1;
PORTC.2 = ADRESH.2;
PORTC.3 = ADRESH.3;
}
}
/*============================= ============================== ============================== ================*/
/* FONCTIONS */
/*============================= ============================== ============================== ================*/
// Initialisation des registres du PIC au RESET:
void init0 (void)
{
ANSEL = 0x01; // Entrée analogique sur RA0 uniquement
ANSELH = 0;
ADRESH = 0b00000000;
ADCON0 = 0b00000001; // Mise en marche du CAN ,canal 0 (RA0), VDD, Cadrage à gauche
TRISC = 0x00; // Configuration du PORTC en sortie
OPTION = 0b11000101; // Prédiviseur du timer = 32, entrée = clock/4
}
//============================== ============================== ============================== ================
// Temporisation de durée de 5µs pour la charge du condensateur:
void tempo()
{
nop();
nop();
nop();
nop();
nop();
}
désolé , je n'avais pas vu que je ne l'avais pas actualisé
Bon,
pour ma part, je ne travaille pas généralement avec les 16F, mais dans ton initialisation, dit bien quand même que ta broche RA0 est une entrée même si tu dis que c'est une entrée analogique par le biais du registre ADCON0, donc ajoute:
Sinon, pour le reste , ça me parait correct...Code:TRISA = 0x01; // Configuration de de la broche A0 en entrée
As tu essayer de fonctionner de savoir si la conversion se faisait au moins?
Oui elle fonctionne sur plaque d'essais , mais le probleme c'est que quand je fais varier ma tension ma conversion se fait bien. Mais par exemple sur une tension analogique de 0 à 5V , j'obtiens en numérique sur 4 bits 7 ou 8 fois 0xFF .Bon,
pour ma part, je ne travaille pas généralement avec les 16F, mais dans ton initialisation, dit bien quand même que ta broche RA0 est une entrée même si tu dis que c'est une entrée analogique par le biais du registre ADCON0, donc ajoute:
Sinon, pour le reste , ça me parait correct...Code:TRISA = 0x01; // Configuration de de la broche A0 en entrée
As tu essayer de fonctionner de savoir si la conversion se faisait au moins?
Y a quand même une chose bizarre dans ton soft au niveau du lancement de la conversion:
Au début tu mets ADCON0.1 = 1, là d'accord, par contre sur la boucle while, moi j'aurai plutot mis:Code:ADCON0.1 = 1; // Début de conversion while (ADCON0.1==0); // Attendre fin de conversion
car tu attends que ton bit GO/DONE passe à 0...Code:while (ADCON0.1==1);
Essaye quand avec ce que je te dis...
Tu peux nous donner un exemple précis?mais le probleme c'est que quand je fais varier ma tension ma conversion se fait bien. Mais par exemple sur une tension analogique de 0 à 5V , j'obtiens en numérique sur 4 bits 7 ou 8 fois 0xFF
-Tension en entrée sur AN0
-Résultat sur tes 4 bits RC0 à RC3
ça sera plus concret...merci d'avance
Sa ne change rien , je trouve sa bizarre ..Y a quand même une chose bizarre dans ton soft au niveau du lancement de la conversion:
Au début tu mets ADCON0.1 = 1, là d'accord, par contre sur la boucle while, moi j'aurai plutot mis:Code:ADCON0.1 = 1; // Début de conversion while (ADCON0.1==0); // Attendre fin de conversion
car tu attends que ton bit GO/DONE passe à 0...Code:while (ADCON0.1==1);
Essaye quand avec ce que je te dis...
Tout d'abord pour tester mon CAN j'utilise une carte de développement , qui affiche le resultat de mon programme par des LEDS, je peux ainsi voir un resultat jusqu'à 8 bits. Ici le résultat de la conversion sur 4 bits s'effectue comme ceci :
http://dl.free.fr/jQGH0c9ZA
Je fais ainsi varier une tension de 0 à 5v à l'aide d'un potentiomètre sur la broche RA0 de mon PIC, j'obtient le resultat 1111 à peu pres 8 fois sur l'ensemble de ma plage de conversion.
Ma plage de conversion est elle trop grande sur 4 bits ?
J'ai du mal a suivre, tu passes du conversion analogique numérique 10 à un résultat sur 4 bits, je ne suis pas un expert en C, mais voila ce que je comprend,
Tu as une tension en entrée sur RA0 qui varie de 0 à 5V, donc après conversion analogique numérique, tu dois avoir un mot binaire (écrit sur ADRESL et ADRESH qui va évoluer entre 0 et 1024 (2^10) en décimal et toi dans ton cas tu récupères les valeurs entre ADRESH.0 et ADRESH.3 donc ta valeur max sera 2^4 soit 16 en décimal...Donc il y a un truc qui cloche... même si tu ne travail qu'avec le registre ADRESH (vu que tu as fait une justification a gauche, les 2 bits sur ADRESL sont négligeables) tu travaillerai donc sur 2^8bits = 256 en décimal
il est donc normal je pense que tes LEDs RC0 à RC3 soient toutes allumées environ 8 fois lorsque ta tension varie entre 0 et 5V...
Si tu veux avoir tes 4 LEDS (1111)allumées une fois donc pour 5V , il vaut que tu adaptes ton résultat.
Il faudrait que tu divises ton résultat de ADRESH par 16... et tu "affiches" ce que tu obtiens...
par contre ma proposition doit être confirmé, car comme je te l'ai dis je ne suis pas non plus un pro en C...
Bonne continuation
Voila exactement mais est ce que quelqu'un saurait si cela est possible ?Il faudrait que tu divises ton résultat de ADRESH par 16... et tu "affiches" ce que tu obtiens...
Rien ne t'empêche d'essayer...
tu peux essayer ça...mais je te garanti rien!!Code:void main (void) // Début du programme principal { char result16; init0(); // Initialisation des registres du PIC au RESET while(1) // Boucle de tâches: { tempo(); ADCON0 = ADCON0 | 0x02; // Début de conversion ADCON0.1 = 1; // Début de conversion while (ADCON0.1==1); // Attendre fin de conversion result16 = ADRESH/16; PORTC = result16; } }
Je débloque juste mon programmeur qui a bugué et j'essaie ta méthode. Peux tu m'expliquer ce que tu fais dans le programme ? Je te remercie d'avance
Le début est identique au tiens, je déclare une variable de type char (1 octet) ,pour :
je divise le résultat par 16 pour avoir ta plage 0 - 5V sur 4 bits (2^4 = 16) donc 5V / 16 = 312,5 mV donc tu auras logiquement un changement de valeurs sur tes LEDS tous les 321,5 mV.Code:result16 = ADRESH/16;
Pour:
j'attribue la valeur trouvé au PORTC... J'ai essayé, tout marche jusqu'a la dernière ligne PORTC = result16, cette ligne ne fonctionne pas...j'essaye de trouver et je te tiens au courant... autant sinon une réponse d'un autre...Code:PORTC = result16;
Sa marche nickel , bien joué . maintenant il va juste falloir que j'amplifie ma variation de tension car elle ne va que de 2.5V a 3.0V , pour la faire passer de 0v à 5V et normalement sa devrait marcher. Sachant qu'avec le 16f690 je ne peux pas déclarer une tension -Vref , elle ne peut etre qu'a Vss , je peux cependant declarer un +Vref mais je pense que ce n'est pas la bonne solution.Le début est identique au tiens, je déclare une variable de type char (1 octet) ,pour :
je divise le résultat par 16 pour avoir ta plage 0 - 5V sur 4 bits (2^4 = 16) donc 5V / 16 = 312,5 mV donc tu auras logiquement un changement de valeurs sur tes LEDS tous les 321,5 mV.Code:result16 = ADRESH/16;
Pour:
j'attribue la valeur trouvé au PORTC... J'ai essayé, tout marche jusqu'a la dernière ligne PORTC = result16, cette ligne ne fonctionne pas...j'essaye de trouver et je te tiens au courant... autant sinon une réponse d'un autre...Code:PORTC = result16;
Merci d'avoir perdu ton temps la dessus !
Pas de problème...
En fait pour la ligne :
PORTC = result16;
ça ne marchait pas chez moi car j'étais en mode simulation, j'ai donc modifié par
LATC = result16, et là nikel chez moi donc voila...
Bonne continuation...