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 :

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;
}
Bonne journée!
A+!
marC