Bonjour à tous!
Je voudrais faire un horloge + timer qui allume un relais dépendement de l'alarme régler par l'utilisateur.
Ce circuit utilise un PIC16F887 et un DS1307.
Je fais le multiplexage des 7 segments, mais j'aimerais mieux utiliser la fonction interrupt et le TMR0 pour les multiplexés.
Je me demande comment pourrais-je faire? LA technique à utiliser?
Merci beaucoup!
Voici mon code :
Bonne journée!Code:/********************************************** * Programmateur version RELAIS * * 7 SEGMENT avec circuit intégré RTC DS1307 * * Microcontrôleur utilisé PIC16F887 * * Avec quartz 4 Mhz pour précision * * Date début : 26-07-2013 * * Date fin : ??-07-2013 * * Copyright (c) Marc Paradis 2013 * ***********************************************/ /*************************************************** * Déclaration des variables * ***************************************************/ // variables pour DS1307 RTC unsigned short heure; unsigned short minute; unsigned short seconde; unsigned short jour; unsigned short jour_semaine; unsigned short mois; unsigned short annee; volatile unsigned short minute_temp, heure_temp; // adresse du DS1307 const unsigned short DS1307 = 0xD0; unsigned short i, DD0, DD1, DD2, DD3; unsigned short Num; volatile short compteur, drapeau_minute = 0, drapeau_heure = 0, drapeau_alarme = 0; unsigned short heure_alarme = 0; unsigned short minute_alarme = 0; unsigned short heure_horloge = 0; unsigned short minute_horloge = 0; unsigned short heure_reveil = 0, secondes, OneSec; unsigned short int cptReveil = 0; unsigned short int transition_bp_inverser_relais = 0; unsigned short int etatanterieur_bp_inverser_relais = 1; // BP ouvert lors de la derniere scrutation unsigned short int etat_port; /*************************************************** * Déclaration des fonctions * ***************************************************/ // DS1307 RTC unsigned short read_ds1307(unsigned short address); void write_ds1307(unsigned short address,unsigned short w_data); // CONVERSION unsigned char BCD2UpperCh(unsigned char bcd); unsigned char BCD2LowerCh(unsigned char bcd); int Binary2BCD(int a); int BCD2Binary(int a); ////////////////////////////////////////////////////////////////////// sbit SET_HEURE_HORLOGE at RE0_bit; // PIC 8 sbit SET_MINUTE_HORLOGE at RE1_bit; // PIC 9 sbit SET_ALARME_HORLOGE at RE2_bit; // PIC 10 sbit ETAT_REVEIL at RB3_bit; // PIC 36 sbit RELAIS at RA2_bit; // PIC 4 sbit DEUX_POINTS at RA0_BIT; // PIC 2 unsigned short Num2Points = 0; // PORTB # define INVERSER_RELAIS_BIT F5 // PORT B (PIC 38) EN ENTRÉE # define BIT_LED F1 char message_EEPROM[] = "Copyright 2013 Marc Paradis"; char Edata[] = "000000000000000000000000000"; unsigned int ADD; // Start EEPROM Location char temp; // Fin déclaration variables void WriteToEEPROM() { ADD = 0; for (i=0; i<strlen(message_EEPROM); i++) { temp = message_EEPROM[i]; EEPROM_Write(ADD+i,temp); } } unsigned short int test_bp_inverser_relais() { // test du bouton poussoir INVERSER RELAIS etat_port = PORTB.INVERSER_RELAIS_BIT; // lecture du niveau du port if ((etat_port == 0) && (etatanterieur_bp_inverser_relais == 1)) { etatanterieur_bp_inverser_relais = etat_port; return 1; // BP a été appuyé } else { etatanterieur_bp_inverser_relais = etat_port; return 0; // BP inactif } } //------ Function to Return mask for common anode 7-seg. display en hexadécimal unsigned short mask(unsigned short num) { switch (num) { case 0 : return 0xC0; case 1 : return 0xF9; case 2 : return 0xA4; case 3 : return 0xB0; case 4 : return 0x99; case 5 : return 0x92; case 6 : return 0x82; case 7 : return 0xF8; case 8 : return 0x80; case 9 : return 0x90; } } void Debounce() { Delay_ms(300); } void Afficher_Heure() { for (i = 0; i <= 50; i++) { PORTD = DD0; RC0_bit = 0; // 15 // Select Ones Digit RC1_bit = 1; // 16 RC2_bit = 1; // 17 RA5_bit = 1; // 7 delay_ms(2); PORTD = DD1; RC0_bit = 1; RC1_bit = 0; RC2_bit = 1; RA5_bit = 1; delay_ms(2); PORTD = DD2; RC0_bit = 1; RC1_bit = 1; RC2_bit = 0; RA5_bit = 1; delay_ms(2); PORTD = DD3; RC0_bit = 1; RC1_bit = 1; RC2_bit = 1; RA5_bit = 0; delay_ms(2); } } void interrupt() { if (INTCON.T0IE == 1 && INTCON.T0IF == 1) // débordement du TMR0 { Num2Points++; if (Num2Points == 9) // à 1/2 seconde on fait clignoter les : { Num2Points = 0; DEUX_POINTS = !DEUX_POINTS; } INTCON.T0IF = 0; TMR0 = 39; } } unsigned short int Test_Heure_Reveil() { if (heure_temp == heure_alarme && minute_temp == minute_alarme) return 1; else return 0; } void check_device(unsigned short dev_address){ I2C1_Start(); if (I2C1_Wr(dev_address)) PORTB.BIT_LED = 0; else PORTB.BIT_LED = 1; // ok I2C1_Stop(); } void main() { C1ON_BIT = 0; C2ON_BIT = 0; ANSEL = 0; ANSELH = 0; TRISA = 0x00; TRISB = 0b00101000; TRISC = 0x00; TRISD = 0x00; TRISE = 0b00000111; // RE0 = SET_HEURE, RE1 = SET_MINUTE, RE2 = SET_ALARME PORTA = 0x00; PORTB = 0x00; PORTC = 0x00; PORTD = 0x00; PORTE = 0x00; heure_alarme = 6; minute_alarme = 30; I2C1_Init(100000); // Initialisation du DS1307 RTC I2C @ 100kHz crystal 32.768kHz check_device(DS1307); WriteToEEPROM(); RELAIS = 0; // appareil à OFF OPTION_REG = 0x07; // Prescaler (1:256) is assigned to the timer TMR0 INTCON = 0xA0; // Enable interrupt TMR0 and Global Interrupts TMR0 = 39; // Timer T0 counts from 39 to 255 /* write_ds1307(0, 0x00); // Reset second to 0 sec. and start Oscillator write_ds1307(1, 0x01); // on écrit les minutes dans le DS1307 write_ds1307(2, 0x00); // on écrit les heures dans le DS1307 write_ds1307(3, 0x06); // écrit le jour de la semaine dans le DS1307 write_ds1307(4, 0x27); // on écrit le jour dans le DS1307 write_ds1307(5, 0x07); // écrit le mois dans le DS1307 write_ds1307(6, 0x13); // écrit 2013 dans l'année */ do { seconde = read_ds1307(0); minute = read_ds1307(1); heure = read_ds1307(2); // jour_semaine = read_ds1307(3); // jour = read_ds1307(4); // mois = read_ds1307(5); //annee = read_ds1307(6); // covnersion nécessaire sinon l'affichage n'est pas correct heure_temp = Bcd2Dec(heure); minute_temp = Bcd2Dec(minute); if (!SET_ALARME_HORLOGE) drapeau_alarme = 1; else drapeau_alarme = 0; transition_bp_inverser_relais = test_bp_inverser_relais(); if (transition_bp_inverser_relais == 1) { delay_ms(150); // anti-rebond RELAIS = !RELAIS; } if (!SET_HEURE_HORLOGE) { if (drapeau_alarme == 0) { delay_ms(150); /// anti-rebond heure = BCD2Binary(heure); heure++; // on incrémente heure de 1 if (heure > 23) // on ne peut pas dépasser 23 heures dans une journée heure = 0; heure = Binary2BCD(heure); // on met les heures en binaire write_ds1307(2, heure); // on écrit les heures } else { delay_ms(150); // anti-rebond heure_alarme++; if (heure_alarme > 23) heure_alarme = 0; } } if (!SET_MINUTE_HORLOGE) { if (drapeau_alarme == 0) { delay_ms(150); // anti-rebond minute = BCD2Binary(minute); minute++; // on incrémente minute de 1 if (minute > 59) // on ne peut pas dépasser 59 minutes minute = 0; minute = Binary2BCD(minute); // on met les minutes en binaire write_ds1307(1, minute); } else { delay_ms(150); // anti-rebond minute_alarme++; if (minute_alarme > 59) minute_alarme = 0; } } if (drapeau_alarme == 0) { DD0 = minute_temp%10; DD0 = mask(DD0); DD1 = minute_temp/10; DD1 = mask(DD1); DD2 = heure_temp%10; DD2 = mask(DD2); DD3 = heure_temp/10; DD3 = mask(DD3); } if (drapeau_alarme == 1) { DD0 = minute_alarme%10; DD0 = mask(DD0); DD1 = minute_alarme/10; DD1 = mask(DD1); DD2 = heure_alarme%10; DD2 = mask(DD2); DD3 = heure_alarme/10; DD3 = mask(DD3); } // si la switch du réveil est à ON, on teste si c'est l'heure du réveil // sinon on ignore le if if (!ETAT_REVEIL) { heure_reveil = Test_Heure_Reveil(); // si c'est l'heure du réveil if ( (heure_reveil == 1) || (cptReveil == 1) ) { cptReveil = 1; RELAIS = 1; } } // IF (!ETAT_ALARME_REVEIL) Afficher_Heure(); } while(1); // infinite loop } // Lit contenu du DS1307 RTC unsigned short read_ds1307(unsigned short address) { unsigned short r_data; I2C1_Start(); I2C1_Wr(DS1307); //address 0x68 followed by direction bit (0 for write, 1 for read) 0x68 followed by 0 --> 0xD0 I2C1_Wr(address); I2C1_Repeated_Start(); I2C1_Wr(DS1307+1); //0x68 followed by 1 --> 0xD1 r_data=I2C1_Rd(0); I2C1_Stop(); return(r_data); } // Écrit dans le DS1307 RTC void write_ds1307(unsigned short address,unsigned short w_data) { I2C1_Start(); // issue I2C start signal //address 0x68 followed by direction bit (0 for write, 1 for read) 0x68 followed by 0 --> 0xD0 I2C1_Wr(DS1307); // send byte via I2C (device address + W) I2C1_Wr(address); // send byte (address of DS1307 location) I2C1_Wr(w_data); // send data (data to be written) I2C1_Stop(); // issue I2C stop signal } // Extrait le 1er chiffre du bcd unsigned char BCD2UpperCh(unsigned char bcd) { return ((bcd >> 4) + '0'); } // Extrait le 2ième chiffre du bcd unsigned char BCD2LowerCh(unsigned char bcd) { return ((bcd & 0x0F) + '0'); } // Convertion de binaire en BCD a int Binary2BCD(int a) { int t1, t2; t1 = a%10; t1 = t1 & 0x0F; a = a/10; t2 = a%10; t2 = 0x0F & t2; t2 = t2 << 4; t2 = 0xF0 & t2; t1 = t1 | t2; return t1; } // Convertion de bcd à binaire a int BCD2Binary(int a) { int r,t; t = a & 0x0F; r = t; a = 0xF0 & a; t = a >> 4; t = 0x0F & t; r = t*10 + r; return r; }
A+!
marC
-----