Bonjour à tous!
Je viens une fois de plus à vous, car j'ai léger problème avec mon programme (enfin je pense que ca vient de la).
Je vous expose le problème : J'ai fais un programme relativement simple en .c (Je programme avec MPLABX et avec compilateur XC8), je gère une afficheur LCD OLED 4x20, et j''utilise trois boutons.
J'ai juste une interface d'IHM, avec différentes valeurs à afficher, et avec deux boutons, je monte ou je descend les différentes valeurs, et avec le troisième bouton, je choisis quelle valeur je veux modifier.
Voici le code du .c (il peut paraitre long mais rien de bien compliqué à mon avis) :
Et donc le problème que j'ai,, c'est que au bout de 4-5 minutes, on dirait que le programme se reboot, l'écran d'initialisation se réaffiche, et les variables se remettent a zero comme lorsque que l'on allume, je ne comprends pas trop pourquoi ...Code:#define _XTAL_FREQ 8000000 #include <stdio.h> #include <stdlib.h> #include <stdbool.h> #include <xc.h> #include <pic18f4431.h> #include "LCD_6800.h" //============================================================================== // Macro pour générer un pulse sur le E du LCD #pragma warning disable 361 #define LCD_STROBE {LCD_E = 1; __delay_us(5); LCD_E = 0; __delay_us(5);}; //============================================================================== //============================================================================== // Ecrit une commande //============================================================================== void LCD_Cmd(char out_char) { // C/D = 0 => Ecrit une Commande LCD_CD = 0; // 4 bits de poids fort LCD_D4 = (unsigned)((out_char & 0x10)?1:0); LCD_D5 = (unsigned)((out_char & 0x20)?1:0); LCD_D6 = (unsigned)((out_char & 0x40)?1:0); LCD_D7 = (unsigned)((out_char & 0x80)?1:0); LCD_STROBE // 4 bits de poids faible LCD_D4 = (unsigned)((out_char & 0x01)?1:0); LCD_D5 = (unsigned)((out_char & 0x02)?1:0); LCD_D6 = (unsigned)((out_char & 0x04)?1:0); LCD_D7 = (unsigned)((out_char & 0x08)?1:0); LCD_STROBE if(out_char == 0x01)__delay_ms(2); } //============================================================================== // Défini la position courante du curseur //============================================================================== void LCD_Set_Cursor(char Ligne, char colonne) { switch(Ligne){ case 0: LCD_Cmd((char)(0x80 + 0x00 + (colonne))); break; // Ligne 1 case 1: LCD_Cmd((char)(0x80 + 0x20 + (colonne))); break; // Ligne 2 case 2: LCD_Cmd((char)(0x80 + 0x40 + (colonne))); break; // Ligne 3 case 3: LCD_Cmd((char)(0x80 + 0x60 + (colonne))); break; // Ligne 4 } } //============================================================================== // Ecrit un caractère à la position courante //============================================================================== void LCD_Putc(char out_char) { // C/D = 1 => Ecrit une donnée LCD_CD = 1; // 4 bits de poids fort LCD_D4 = (unsigned)((out_char & 0x10)?1:0); LCD_D5 = (unsigned)((out_char & 0x20)?1:0); LCD_D6 = (unsigned)((out_char & 0x40)?1:0); LCD_D7 = (unsigned)((out_char & 0x80)?1:0); LCD_STROBE // 4 bits de poids faible LCD_D4 = (unsigned)((out_char & 0x01)?1:0); LCD_D5 = (unsigned)((out_char & 0x02)?1:0); LCD_D6 = (unsigned)((out_char & 0x04)?1:0); LCD_D7 = (unsigned)((out_char & 0x08)?1:0); LCD_STROBE } //============================================================================== // Ecrit une chaîne de caractère à partir de la position courante //============================================================================== void LCD_putrs(char *text) { while(*text) LCD_Putc(*text++); } //============================================================================== // Initialise le LCD //============================================================================== void LCD_Init() { TRISD = 0; // PORTD en sortie LCD_CD = 0; // Tous les bits à 0 LCD_E = 0; LCD_D4 = 0; LCD_D5 = 0; LCD_D6 = 0; LCD_D7 = 0; LCD_RST = 1; // RESET à 1 pour activer le LCD __delay_ms(1);//delay LCD_Cmd(0x2A);//function set (extended command set) LCD_Cmd(0x71);//function selection A LCD_Putc(0x00);// disable internal VDD regulator (2.8V I/O). data(0x5C) = enable regulator (5V I/O) LCD_Cmd(0x28);//function set (fundamental command set) LCD_Cmd(0x08);//display off, cursor off, blink off LCD_Cmd(0x2A);//function set (extended command set) LCD_Cmd(0x79);//OLED command set enabled LCD_Cmd(0xD5);//set display clock divide ratio/oscillator frequency LCD_Cmd(0x70);//set display clock divide ratio/oscillator frequency LCD_Cmd(0x78);//OLED command set disabled LCD_Cmd(0x09);//extended function set (4-lines) LCD_Cmd(0x06);//COM SEG direction LCD_Cmd(0x72);//function selection B LCD_Putc(0x00);//ROM CGRAM selection LCD_Cmd(0x2A);//function set (extended command set) LCD_Cmd(0x79);//OLED command set enabled LCD_Cmd(0xDA); //set SEG pins hardware configuration LCD_Cmd(0x10);//set SEG pins hardware configuration LCD_Cmd(0xDC);//function selection C LCD_Cmd(0x00);//function selection C LCD_Cmd(0x81);//set contrast control LCD_Cmd(0x7F);//set contrast control LCD_Cmd(0xD9);//set phase length LCD_Cmd(0xF1);//set phase length LCD_Cmd(0xDB);//set VCOMH deselect level LCD_Cmd(0x40);//set VCOMH deselect level LCD_Cmd(0x78);//OLED command set disabled LCD_Cmd(0x28);//function set (fundamental command set) LCD_Clear(); //clear display LCD_Cmd(_LCD_TURN_ON); //display ON LCD_Set_Cursor(1,1); __delay_ms(100); } //============================================================================== // TEST //============================================================================== void Ecran_Init(){ LCD_Set_Cursor(0,0); LCD_putrs("--------Init--------"); __delay_ms(1500); for(int i=0; i < 20; i++){ LCD_Set_Cursor(1,i); LCD_putrs("*"); __delay_ms(200); } LCD_Set_Cursor(2,7); LCD_putrs("JACOB"); __delay_ms(1500); LCD_Set_Cursor(3,6); LCD_putrs("HENRIOT"); __delay_ms(9900); //Facteur 3.3 pour avoir la bonne base de temps, exemple pour 9900 on a 3 secondes LCD_Clear(); }//Initialisation graphique lorsque l'on allume void Check_Index(){ if (INDEX == LOW && ARB1 == 0){ index++; if(index > 2){index = 0;} ARB1 = 1; while (INDEX == LOW && tempo < 500){ __delay_ms(3); tempo = tempo++; } if(INDEX == LOW && tempo >= 500){ page = 1; tempo = 0; index = 0; LCD_Clear(); }//Si on fait un appui long sur le bouton d'index, on change de page LCD_Clear(); } else if (INDEX == HIGH){ARB1 = 0;} if (index == 0){ LCD_Set_Cursor(1,0); LCD_putrs("*"); } else if (index == 1){ LCD_Set_Cursor(2,0); LCD_putrs("*"); } else if (index == 2){ LCD_Set_Cursor(3,0); LCD_putrs("*"); } }//Fonction pour savoir ou l'on est dans l'index. void main(){ LCD_Init(); LCD_Cmd(_LCD_CURSOR_OFF); LCD_Clear(); Ecran_Init(); while(1){ if (page == 0){ //la variable page, sert a changer de page, pour afficher d'autres paramètres LCD_Set_Cursor(0,1); LCD_putrs("CONSIGNE"); LCD_Set_Cursor(0,10); LCD_putrs("|"); LCD_Set_Cursor(0,13); LCD_putrs("MESURE"); sprintf(s, "IDC= %d", IDC); LCD_Set_Cursor(1,1); LCD_putrs(s); LCD_Set_Cursor(1,10); LCD_putrs("|"); sprintf(s, "%d", IDC); LCD_Set_Cursor(1,12); LCD_putrs(s); LCD_Set_Cursor(1,18); LCD_putrs("A"); sprintf(s, "IAC= %d", IAC); LCD_Set_Cursor(2,1); LCD_putrs(s); LCD_Set_Cursor(2,10); LCD_putrs("|"); sprintf(s, "%d", IAC); LCD_Set_Cursor(2,12); LCD_putrs(s); //Texte à display de base. LCD_Set_Cursor(2,18); LCD_putrs("A"); sprintf(s, "Frq= %d", Frq); LCD_Set_Cursor(3,1); LCD_putrs(s); LCD_Set_Cursor(3,10); LCD_putrs("Hz"); Check_Index(); if (PLUS == LOW && ARB2 == 0){ if(index == 0){ IDC = IDC++; if (IDC > 20){IDC = 20;} } else if(index == 1){ IAC = IAC++; if (IAC > 100){IAC = 100;} } else if(index == 2){ Frq = Frq++; if (Frq > 100){Frq = 100;} } ARB2 = 1; }//Lorsque l'on appuie sur RB0, on check sur quel index l'on se trouve, et on incrémente en fonction. else if (PLUS == HIGH && MOINS == HIGH && INDEX == HIGH){ ARB2 = 0; tempo = 0; }//Lorsque le bouton RB0 est relaché, RAZ des variables. //****************************************** if (PLUS == LOW && tempo < 10){ __delay_ms(100); tempo = tempo++; } if(PLUS == LOW && tempo >=10){ if(index == 0){ IDC = IDC++; __delay_ms(150); if (IDC > 20){IDC = 20;} } else if(index == 1){ IAC = IAC++; __delay_ms(100); if (IAC > 100){IAC = 100;} } else if(index == 2){ Frq = Frq++; __delay_ms(100); if (Frq > 100){Frq = 100;} } } //****************************************** //Détection d'un appui long sur le bouton d'incrémentation //Cela permet d'incrémenter lorsque l'on laisse appuyer au bout de X secondes if (MOINS == LOW && ARB3 == 0){ if(index == 0){ IDC = IDC--; if(IDC == 9 || IDC == 99)LCD_Clear(); if(IDC < 0){IDC = 0;} } else if(index == 1){ IAC = IAC--; if(IAC == 9 || IAC == 99)LCD_Clear(); if (IAC < 0){IAC = 0;} } else if(index == 2){ Frq = Frq--; if(Frq == 9 || Frq == 99)LCD_Clear(); if (Frq < 5){Frq = 5;} } ARB3 = 1; }//Lorsque l'on appuie sur RB1, on check sur quel index l'on se trouve, et on décrémente en fonction. else if (MOINS == HIGH && PLUS == HIGH && INDEX == HIGH){ ARB3 = 0; tempo = 0; }//Lorsque le bouton RB1 est relaché, RAZ des variables de tembo et ARB. //****************************************** if (MOINS == LOW && tempo < 10){ __delay_ms(100); tempo = tempo++; } if(MOINS == LOW && tempo >=10){ if(index == 0){ IDC = IDC--; __delay_ms(150); if(IDC == 9 || IDC == 99)LCD_Clear(); if (IDC < 0){IDC = 0;} } else if(index == 1){ IAC = IAC--; __delay_ms(100); if(IAC == 9 || IAC == 99)LCD_Clear(); if (IAC < 0){IAC = 0;} } else if(index == 2){ Frq = Frq--; __delay_ms(100); if(Frq == 9 || Frq == 99)LCD_Clear(); if (Frq < 5){Frq = 5;} } } //****************************************** //Détection d'un appui long sur le bouton de décrémentation //Cela permet de décrémenter lorsque l'on laisse appuyer au bout de X secondes } if (page == 1){ LCD_Set_Cursor(0,1); LCD_putrs("Reglages du P.I.D"); sprintf(s, "Kp= %d", IDC); LCD_Set_Cursor(1,1); LCD_putrs(s); sprintf(s, "Ki= %d", IDC); LCD_Set_Cursor(2,1); LCD_putrs(s); sprintf(s, "Kd= %d", IDC); LCD_Set_Cursor(3,1); LCD_putrs(s); while (INDEX == LOW && tempo < 500){ __delay_ms(3); tempo = tempo++; } if(INDEX == LOW && tempo >=500){ page = 0; index = 0; tempo = 0; LCD_Clear(); } //si l'on fait un appuie long sur le bouton d'index, on change de page if (MOINS == HIGH && PLUS == HIGH && INDEX == HIGH){ ARB3 = 0; tempo = 0; }//si aucun bouton n'est appuyé, les variables de tempo et ARB se RAZ } } }
Voila, je vous remercie d'avance pour votre considération, et si vous avez de quelconques questions par rapport au code, demandez moi.
Bien à vous, Tom.
-----