Bonjour à tous.
Je viens de découvrir les microcontrôleurs depuis une semaine.
Pour le moment, j'essaye de me faire un petit vu-mètre grâce à un PIC16F876A
Ma première version était plutôt satisfaisante.
Toutes les milisecondes environ (un peu plus), j'effectuai une conversion A->D d'un signal audio et, en fonction de la valeur de la tension, j'allumais une ou plusieurs diodes.
Le rendu est pas trop mal.
Mais j'ai eu envi de l'améliorer en faisant une moyenne sur 10 acquisitions. et là, c'est le drame. je fais une fonction initialiser qui allume les une après les autres les 4 leds pendant 100ms et je me rend compte qu'en fait, mon pic reset très très périodiquement ! (en gros, il reset tous les 100ms au mieux !!)
Le problème, c'est que je ne vois absolument pas pourquoi !! (j'ai désactiver le watchdog...)
Voila mon code :
Code:#include <16F876a.h> #fuses HS,NOPROTECT,NOWDT,NOLVP //HS : haute freq- watchdog - pas interruption #use delay(clock=4000000) // 4MHz vitesse Pic #define LED1 PIN_C3 #define LED2 PIN_C2 #define LED3 PIN_C1 #define LED4 PIN_C0 #define INPUT PIN_A2 // #define LED_TEST1 PIN_C4 // #define LED_TEST2 PIN_C5 //#define S1 (80) //#define S2 (84) //#define S3 (88) //#define S4 (93) #define S1 (10) #define S2 (20) #define S3 (30) #define S4 (40) void init_PIC(); // initialisation du ADC void refresh_led(int); // allume les led en fonction de la tension prélevé sur A2 void main() { int value, somme = 0; int compteur_moyenne = 10; // int test = 0; init_PIC(); while(1) { Delay_ms(1); value = read_adc(ADC_START_AND_READ); // aquisition Delay_us(20); somme = somme + value; compteur_moyenne--; // Output_bit(LED_TEST2, (compteur_moyenne%2)); if(compteur_moyenne == 0) // moyennage sur 10 valeurs { value = (int)(somme / 10); compteur_moyenne = 10; // remise à 0 somme = 0; refresh_led(value); // test++; // Output_bit(LED_TEST1, (test%2)); } // refresh_led(value); } } void init_PIC() { setup_adc(ADC_CLOCK_DIV_32); setup_adc_ports(RA0_RA1_RA3_ANALOG); set_adc_channel(1); // allume les 4 diodes pendant 100 ms les unes à la suite des autres Output_bit(LED1, 1); // <= reste bloqué ici Output_bit(LED2, 0); Output_bit(LED3, 0); Output_bit(LED4, 0); Delay_ms(100); Output_bit(LED1, 0); Output_bit(LED2, 1); Delay_ms(100); Output_bit(LED2, 0); Output_bit(LED3, 1); Delay_ms(100); Output_bit(LED3, 0); Output_bit(LED4, 1); Delay_ms(100); Output_bit(LED4, 0); } void refresh_led(int val) { if(val < S1) { Output_bit(LED1, 0); Output_bit(LED2, 0); Output_bit(LED3, 0); Output_bit(LED4, 0); } else if((val >= S1) && (val < S2)) { Output_bit(LED1, 1); Output_bit(LED2, 0); Output_bit(LED3, 0); Output_bit(LED4, 0); } else if((val >= S2) && (val < S3)) { Output_bit(LED1, 1); Output_bit(LED2, 1); Output_bit(LED3, 0); Output_bit(LED4, 0); } else if((val >= S3) && (val < S4)) { Output_bit(LED1, 1); Output_bit(LED2, 1); Output_bit(LED3, 1); Output_bit(LED4, 0); } else if(val >= S4) { Output_bit(LED1, 1); Output_bit(LED2, 1); Output_bit(LED3, 1); Output_bit(LED4, 1); } else { Output_bit(LED1, 0); Output_bit(LED2, 1); Output_bit(LED3, 1); Output_bit(LED4, 0); } }
Seconde petite question, pour qu'une conversion AD s'effectue, il faut combien de temps ? 20µs ? c'est le temps que prend la fonction read_adc( ou alors, c'est le temps qu'il faut attendre après l'appel de cette fonction avant de lire le résultat ?
Bonne soirée
-----