Bonjour la communauté de futura-sciences
Je parcours ce forum depuis longtemps mais je n'avais jamais oser m'inscrire, voilà qui est fait
A mon tour de poser des questions et aussi d'aider à répondre a celle des autres
Je suis débutant dans la programmation de PIC, j'utilise actuellement un pic16F88 avec un JDM.
Je programme sur WinXP (vieux PC avec RS232) avec MikroC et WinPIC800.
Mon petit projet était le suivant : Afficher la température (avec un capteur DS18B20) sur un 4x7 segments.
Mon problème est le suivant : je dois balayer en permanence le 4x7 segments mais aussi récupérer la température grâce a la liaison serie (One-Wire) du capteur. Celui ci requière un délais pour parfaire sa conversion. J'ai essayé plusieurs chose avec l'interruption TRM0 : 1.Mettre l'affichage dans l'interruption 2. Mettre l'affichage en dehors de l'interruption
Dans le cas n°1, ça bug complet, le refresh de la température se fait aléatoirement. Dans le cas n°2, le PIC n'est pas assez rapide pour traiter la récupération du la température (sans parler des 300ms d'attente) sans perturber l'affichage.
Je ne sais comment faire un programme propre, qui fonctionne avec les bon délais etc.
Je met le schéma du petite montage + le code
Merci d'avance pour votre aide
Code:unsigned int temp; signed long tempinC; unsigned short C_Neg=0; unsigned int i; int num[5] = {10,10,10,10,10}; void interrupt() { for(i=1;i<5;i++) { PORTA = (0b00000001 << i); switch(num[i]){ case 0 : PORTB = 0xC0; break; case 1 : PORTB = 0xF9; break; case 2 : PORTB = 0xA4; break; case 3 : PORTB = 0xB0; break; case 4 : PORTB = 0x99; break; case 5 : PORTB = 0x92; break; case 6 : PORTB = 0x82; break; case 7 : PORTB = 0xF8; break; case 8 : PORTB = 0x80; break; case 9 : PORTB = 0x90; break; case 10 : PORTB = 0xFF; break; case 11 : PORTB = 0xBF; break; } delay_ms(6); } INTCON.TMR0IF = 0; // On reset le drapeau TMR0IF, on set a 1 le TMR0IE } void DS18B20() { Ow_Reset(&PORTA, 0); Ow_Write(&PORTA, 0, 0xCC); Ow_Write(&PORTA, 0, 0x44); delay_ms(300); Ow_Reset(&PORTA, 0); Ow_Write(&PORTA, 0, 0xCC); Ow_Write(&PORTA, 0, 0xBE); temp = Ow_Read(&PORTA, 0)/*LS_BYTE*/ + (Ow_Read(&PORTA, 0) << 8)/*MS_BYTE*/; } void Convert_Temperature() { if (temp & 0x8000) // Si negatif { num[1] = 11; temp = ~temp + 1; // complément a 2; } else { C_Neg = 0; num[1] = 10; } tempinC = temp*6.25; num[2] = (tempinC/1000)%10; num[3] = (tempinC/100)%10 ; num[4] = (tempinC/10)%10 ; } void main() { OSCCON = 0b01100110; // Clock interne a 4Mhz (110) /* REGISTRE OSCCON OSCILLATOR CONTROL REGISTER bit 7 bit 6 à bit 4 Frequence de la clock interne 111 = 8Mhz ; 110 = 4Mhz bit 3 bit 2 bit 1 à 0 Choix de la clock, ici Clock Interne (10) */ /********************************************DEBUT INITIALISATION INTERRUPTION*****************************************************/ OPTION_REG = 0x83; // 10000100 /* REGISTRE OPTION_REG bit 7 RBPU Pull_UP PORT B Desactivés à 1 bit 6 INTEDG bit 5 T0CS TMR0 Clock Source => à 0 sur la clock interne à 1 sur transition RA4/T0CKI/C2OUT bit 4 T0SE TMR0 Edge => Utile si T0CS à 1 à 1 incrementation du timer high to low à 0 incrementation du timer low to high bit 3 PSA Prescalar assigné a WDT (1) ou Timer0 (0) bit 2 Prescalar bit 1 Prescalar bit 0 Prescalar */ INTCON = 0xA0; //10100000 /* REGISTRE INTCON bit 7 GIE activer interruptions (set : 1) bit 6 PEIE bit 5 TMR0IE activer interruption TMR0 (set : 1) bit 4 INT0IE bit 3 RBIE bit 2 TMR0IF "drapeau" => a 1 quand overflow (reset : 0) bit 1 INT0IF bit 0 RBIF */ /*********************************************FIN INITIALISATION INTERRUPTION******************************************************/ ANSEL = 0x00; TRISA = 0x01; TRISB = 0x00; PORTA = 0x00; PORTB = 0x00; do { DS18B20(); Convert_Temperature(); delay_ms(1000); } while (1); }
-----