Programació en C del PIC 16F690

Referència Trucs Perifèrics   Recursos CITCEA
Tutorial Exemples Projectes   Inici

Rellotge

Programa del grup 1

En aquest cas és un rellotge amb alarma. S'han preparat els polsadors per poder modificar la data i l'hora quan sigui necessari així com l'hora de l'alarma i si està activada o no.

Aquest grup no va implementar interrupcions per a la gestió del temps i, per tant, és probable que el rellotge tingui un endarreriment a mesura que passa el temps.

El programa és el següent:

#pragma config FOSC = INTRCIO, WDTE = OFF, PWRTE = OFF, MCLRE = OFF, CP = OFF
#pragma config CPD = OFF, BOREN = OFF, IESO = OFF, FCMEN = OFF
#include <xc.h>  // Carrega el fitxer de funcions necessari per al compilador XC8
#define _XTAL_FREQ  4000000  // La freqüència del rellotge és 4 MHz
#define FiTimer0 INTCONbits.T0IF
#define Selector RA3
#define clrbit(var, bit) ((var) &= ~(1 << (bit)))
#define flipbit(var, bit) ((var) ^= (1<<(bit)))
// Definició de les variables que farem servir
unsigned char Compta;
unsigned char SU;
unsigned char SD;
unsigned char MU;
unsigned char MD;
unsigned char HU;
unsigned char HD;
char Polsad;
unsigned char Cur;
unsigned char HHU;
unsigned char HHD;
unsigned char Mode;
unsigned char Data;
unsigned char Y4;
unsigned char Y3;
unsigned char Y2;
unsigned char Y1;
unsigned char M2;
unsigned char M1;
unsigned char D2;
unsigned char D1;
unsigned char AMU;
unsigned char AMD;
unsigned char AHU;
unsigned char AHD;
unsigned char T1;
unsigned char T2;
unsigned char T3;
unsigned char T4;
unsigned char Alm_ON;
char Q_Menu;
char Dia_Setmana;
char Dies_Mes[]={31,28,31,30,31,30,31,31,30,31,30,31};
char Setmana[]="SATSUNMONTUEWEDTHUFRI";
char Smes[]="GENFEBMARAPRMAYJUNJULAUGSEPOCTNOVDEC";
char Mes;
char Dia;
char Ret;
int J_Dia;
int Any;
char port;          
char controla;
int bucles;          
int silenci;
char Sona;
// Definició de les funcions que farem servir 
void EnviaL(char Caracter);  // Envia un caràcter
void Esborra(void);  // Esborra la pantalla i posa el cursor a l'inici
void Cursor(char Filera, char Columna);  // Posiciona el cursor
void Escriu_Temps(char HD, char HU, char MD, char MU, char SD, char SU);
void Rellotge(void);
void Escriu_Menu(void);
void Menu(void);
char Polsador(void);
void Escriu_Canvi_Mode(void);
void Canvi_Mode(void);
void Escriu_Canvi_Hora(char HD, char HU, char MD, char MU);
void Canvi_Hora(void);
void Canvi_Data(void);
void Menu_Canvi_Data(void);
void Escriu_Data(char D1, char D2, char Mes, char Y1, char Y2, char Y3, char Y4, char Dia_Setmana);
char Zeller(char zdia, char zmes,int zany);
int Juliano(int Any, char Mes, char J_Dia);
char Es_Bisiest(int Any);
void Juliano_a_Data(int Juliano);
void Pols_Funcio(char x, char p1, char p2, char p3, char p4, char c1, char c2, char c3, char c4);
void TocaNota(char valPre, char valPos, char valPR2, int numbuc, int numsil);
void main (void) {    
  SU = 0;
  SD = 0;
  MU = 0;
  MD = 2;
  HU = 3;
  HD = 1;
  Cur = 0;
  Mode = 0;
  Data = 0;
  Q_Menu = 0;
  Sona = 0;
  Alm_ON = 0;
  D1 = 1;
  D2 = 9;
  M1 = 1;
  M2 = 2;
  Y1 = 2;
  Y2 = 0;
  Y3 = 2;
  Y4 = 3;
  AMU = 0;
  AMD = 0;
  AHU = 0;
  AHD = 0;
  Any = Y1*1000+Y2*100+Y3*10+Y4;
  Mes = M1*10+M2;
  Dia= D1*10+D2;
  J_Dia = Juliano(Any, Mes, Dia);
  Dia_Setmana = Zeller(Dia, Mes, Any); 
  ANSEL = 0b00000101;  // Configura AN0 i AN2 com entrada analògica
  ANSELH = 0;  // Desactiva les altres entrades analògiques
  TRISC = 0;  // Tot el port C és de sortida
  TRISB = 0;  // Tot el port B és de sortida    
  __delay_ms(2000);  // Esperem que arrenqui la pantalla
  ADCON1 = 0b00010000;  // Posa el conversor a 1/8 de la freqüència
  ADCON0 = 0b00001001;
  TXSTAbits.BRGH = 1;  // Configuració de velocitat
  BAUDCTLbits.BRG16 = 0;  // Paràmetre de velocitat de 8 bits
  SPBRG = 25;  // Velocitat de 9600 baud
  TXSTAbits.SYNC = 0;  // Comunicació asíncrona
  TXSTAbits.TX9 = 0;  // Comunicació de 8 bits
  RCSTAbits.SPEN = 1;  // Activa comunicació sèrie
  TXSTAbits.TXEN = 1;  // Activa comunicació
  FiTimer0 = 0;  // Aquest bit es posarà a 1 quan el temporitzador acabi
  OPTION_REG = 0b10000111;  // Configuració de Timer0
  TMR0 = 58;
  Compta = 0;       
  while (1){
    if (Selector == 0){
      while (Selector==0)
        ;                
      __delay_ms(10);
      if (Sona == 1){
        Alm_ON = 0;
        Sona = 0;
        TRISC = 0b00100000;                    
      } else {
        Menu();                    
      }
    }
    if (FiTimer0 == 1) {  // Si ha acabat el temporitzador
      Rellotge();
      Escriu_Data(D1, D2, Mes, Y1, Y2, Y3, Y4, Dia_Setmana);
    }
    if (PIR1bits.TMR2IF) {  // Comprovem que hi ha interrupció per Timer2
      PIR1bits.TMR2IF = 0;  // Desactiva el bit que indica interrupció pel Timer2
      if (controla == 0){  // Si estem tocant una nota
        flipbit(port, 5);  // Inverteix la sortida del brunzidor
        PORTC = port;  // Ho copia al port C
      }
      bucles--;  // Comptador per a la durada de la nota
      if (bucles == 0){  // Si és zero, ja ha passat la durada de la nota
        if ((controla == 1) || (silenci == 0)){  // Si s'acaba el silenci
          T2CONbits.TMR2ON = 0;  // Desactiva el Timer2
          PIE1bits.TMR2IE = 0;  // Desactiva les interrupcions per Timer2
        }
        if (controla == 0){  // Si estem tocant una nota
          clrbit(port, 5);  // A l'acabar, deixa la sortida desactivada
          PORTC = port;  // Ho copia al port C
          if (silenci > 0){  // Si es preveu silenci
            bucles = silenci;  // Agafem la durada del silenci
            controla = 1;  // Toca silenci
          }
        }
      }
    }
  }
}    
void EnviaL(char Caracter) {
  TXREG = Caracter;  // Agafa el caràcter i l'envia
  __delay_ms(1);  // Donem temps
  while (PIR1bits.TXIF == 0)  // Esperem que s'acabi d'enviar
    ;  // No fem res
}
void Esborra(void) {
  EnviaL(254);  // Caràcter de control
  EnviaL(1);  // Esborra la pantalla i posa el cursor a l'inici
}
void Cursor(char Filera, char Columna) {
  char Posicio = 0;  // Variable per a calcular la posició
  if (Filera == 2) {
    Posicio = 64;  // La primera columna de la segona fila és 64;
  }
  if (Columna > 0 && Columna < 33) {  // Comprovem que sigui un valor raonable
    Posicio = Posicio + Columna;  // Sumem les adreces
    Posicio = Posicio - 1;  // Restem 1 perquè numera des de 0
  }
  Posicio = Posicio + 128;  // Posa el bit de posicionat a 1
  EnviaL(254);  // Control de la posició del cursor
  EnviaL(Posicio);  // Canvia el cursor de lloc
}
void Rellotge(void){
  TMR0 = 58;                  
  FiTimer0 = 0;
  Compta++;
  if (Compta == 20) {
    Compta = 0;
    SU++;
    if (SU == 10) {
      SU = 0;
      SD++;
    }
    if (SD == 6) {
      SD = 0;
      MU++;
    }
    if (MU == 10) {
      MU = 0;
      MD++;
    }
    if (MD == 6) {
      MD = 0;
      HU++;
    }
    if (HU == 10) {
      HU = 0;
      HD++;
    }
    if (HD == 2 && HU == 4) {
      HD = 0;
      HU = 0;
      J_Dia++;            
      if (J_Dia>365 && Es_Bisiest(Any)==0){
        J_Dia = 1;
        Y4++;
        if (Y4>9){
          Y4 = 0;
          Y3++;                    
        }
        if (Y3>9){
          Y3 = 0;
          Y2++;                    
        }                
        Any++;                
      }
      if (J_Dia>366){
        J_Dia = 1;
        Y4++;
        if (Y4>9){
          Y4 = 0;
          Y3++;
        }
        if (Y3>9){
          Y3 = 0;
          Y2++;                    
        }
        Any++;                
      }
      Juliano_a_Data(J_Dia);            
      Dia_Setmana = Zeller(Dia, Mes, Any);
    }
    if (Data == 0 && (Q_Menu == 0 || Q_Menu == 2)){
      Escriu_Temps(HD, HU, MD, MU, SD, SU);
    }
    if (AHD == HD && AHU == HU && AMD == MD && AMU == MU && Alm_ON==1){
      Sona = 1;
      TRISC = 0b00000000;
      TocaNota(0, 5, 253, 132, 132);  // Valor que correspon aproximadament a mi3        
    }
    return;    
  }
}
void Escriu_Temps(char HD, char HU, char MD, char MU, char SD, char SU) {    
  Esborra();
  EnviaL(254);
  EnviaL(12);
  if (Mode == 0){
    Cursor(1, 5);
    EnviaL((char) 48 + HD);
    EnviaL((char) 48 + HU);
    EnviaL((char) 58);
    EnviaL((char) 48 + MD);
    EnviaL((char) 48 + MU);
    EnviaL((char) 58);
    EnviaL((char) 48 + SD);
    EnviaL((char) 48 + SU);
  } else {
    if (HD*10 + HU < 13){
      HHD = HD;
      HHU = HU;
    }
    if (HD*10 + HU > 12){
      HHD = 0;
      HHU = HU - 2;
    }
    if (HD*10 + HU == 20 || HD*10 + HU == 21){
      HHD = 0;
      HHU = HU + 8;            
    }
    if (HD*10 + HU > 21){
      HHD = 1;
      HHU = HU - 2;            
    }
    if (HD == 0 && HU == 0){
      HHD = 1;
      HHU = 2;            
    }
    Cursor(1, 5);
    EnviaL((char) 48 + HHD);
    EnviaL((char) 48 + HHU);
    EnviaL((char) 58);
    EnviaL((char) 48 + MD);
    EnviaL((char) 48 + MU);
    EnviaL((char) 58);
    EnviaL((char) 48 + SD);
    EnviaL((char) 48 + SU);
    if (HD*10 + HU < 12){
      Cursor(1, 14);
      EnviaL('A');
      EnviaL('M');
    } else {
      Cursor(1, 14);
      EnviaL('P');
      EnviaL('M');
    }
  }
  if (Alm_ON==1){
    Cursor(1, 1);
    EnviaL('A');
  }
}
void Escriu_Menu(){    
  EnviaL('M');
  EnviaL('O');
  EnviaL('D');
  EnviaL(' ');
  EnviaL('H');
  EnviaL('O');
  EnviaL('R');
  EnviaL(' ');
  EnviaL('A');
  EnviaL('L');
  EnviaL('M');
  EnviaL(' ');
  EnviaL('D'); 
  EnviaL('A');
  EnviaL('T');
  EnviaL(254);
  EnviaL(14);
  return;
}
void Menu(void){
  Cur = 0;
  Cursor(2, 2);
  Escriu_Menu();
  while(1){
    Polsad = Polsador();              
    Pols_Funcio(2, 1, 1, 1, 1, 2, 6, 10, 14);
    if (FiTimer0 == 1) {  // Si ha acabat el temporitzador
      Rellotge();            
      Cursor(2, 2);
      Escriu_Menu();
      Cursor(2, 2+4*Cur);            
    }  
    if (Selector == 0){
      while(Selector==0)
        ;
      __delay_ms(10);
      switch (Cur){
        case 0:
          Canvi_Mode();
          break;
        case 1:
          Q_Menu = 1;                        
          Canvi_Hora();
          break;
        case 2:
          Q_Menu = 3;                        
          Canvi_Hora();                        
          break;
        case 3:
          Q_Menu = 2;
          Canvi_Data();
          break;                       
      }
    }
    if (Ret==1){
      return;
    }
  }
}
char Polsador(void) {
  char Pols = 0;
  ADCON0bits.GO = 1;  // Posa en marxa el conversor
  while (ADCON0bits.GO == 1)  // Mentre no acabi
    ;  // ens esperem
  if (ADRESH < 220 && ADRESH > 200) {
    Pols = 1;  // Comprova polsador 1
  }
  if (ADRESH < 194 && ADRESH > 174) {
    Pols = 2;  // Comprova polsador 2
  }
  if (ADRESH < 163 && ADRESH > 143) {
    Pols = 3;  // Comprova polsador 3
  }
  if (ADRESH < 90 && ADRESH > 70) {
    Pols = 4;  // Comprova polsador 4
  }
  if (ADRESH < 55 && ADRESH > 35) {
    Pols = 5;  // Comprova polsador 5
  }
  return Pols;
}
void Escriu_Canvi_Mode(){    
  EnviaL('H');
  EnviaL('2');
  EnviaL('4');
  Cursor(2, 5);
  EnviaL('A');
  EnviaL(':');
  EnviaL('O');
  EnviaL('N');
  EnviaL('/');
  EnviaL('O');
  EnviaL('F');
  EnviaL('F'); 
  Cursor(2,14);
  EnviaL('H'); 
  EnviaL('1');
  EnviaL('2');
  EnviaL(254);
  EnviaL(14);
  return;    
}
void Canvi_Mode(void){
  Cur=0;
  Cursor(2, 1);
  Escriu_Canvi_Mode();
  while(1){
    Polsad = Polsador();
    Pols_Funcio(2, 1, 1, 1, 0, 2, 14, 0, 0);  
    if (FiTimer0 == 1) {  // Si ha acabat el temporitzador
      Rellotge();
      Cursor(2, 1);
      Escriu_Canvi_Mode();
      if (Cur != 2){
        Cursor(2, 1+4*Cur);                
      } else {
        Cursor(2, 14);                
      }                        
    }
    if (Selector == 0){
      while(Selector==0)
        ;
      __delay_ms(10);
      switch (Cur){
        case 0:
          Mode=0;
          break;
        case 1:
          if (Alm_ON==1){
            Alm_ON=0;                            
          } else {
            Alm_ON=1;                            
          }
          break;
        case 2:
          Mode=1; 
          break;
      }              
    }
    if (Ret==1){
      return;
    }
  }
}
void Escriu_Canvi_Hora(char HD, char HU, char MD, char MU) {
  Esborra();
  Cursor(1, 6);
  EnviaL((char) 48 + HD);
  EnviaL((char) 48 + HU);
  if (Data == 0){
    EnviaL((char) 58);
    EnviaL((char) 58);
  } else if (Data == 1){
    EnviaL((char) 47);
    EnviaL((char) 47);
  } else {
    EnviaL((char) 32);
    EnviaL((char) 32);        
  }    
  EnviaL((char) 48 + MD);
  EnviaL((char) 48 + MU);    
}
void Canvi_Hora(void){
  if (Data == 1) {
    Escriu_Canvi_Hora(M1, M2, D1, D2);        
  } else if (Data == 2) {
    Escriu_Canvi_Hora(Y1, Y2, Y3, Y4);        
  } else {        
    Escriu_Canvi_Hora(HD, HU, MD, MU);        
  }    
  Cur = 0; 
  Cursor(1, 6);
  EnviaL(254);
  EnviaL(14);
  T1=HD;
  T2=HU;
  T3=MD;
  T4=MU;
  while (1){     
    Polsad = Polsador();
    Pols_Funcio(1, 1, 1, 1, 1, 6, 7, 10, 11);
    if (FiTimer0==1){ 
      if (Data != 0){
        Rellotge();
      }
    }
    if (Selector==0){
      while(Selector==0)
        ;
      __delay_ms(10);
      if (Data == 0){
        switch (Cur){
          case 0:
            T1++;
            if (T1>2){
              T1=0;
            }
            Escriu_Canvi_Hora(T1, T2, T3, T4);
            Cursor(1, 6);
            break;
          case 1:
            T2++;
            if (T1==2 && T2>3){
              T2=0;
            }
            if (T1<2 && T2>9){
              T2=0;
            }                    
            Escriu_Canvi_Hora(T1, T2, T3, T4);
            Cursor(1, 7);
            break;
          case 2:
            T3++;
            if (T3>5){
              T3=0;
            }
            Escriu_Canvi_Hora(T1, T2, T3, T4);
            Cursor(1, 10);
            break;
          case 3:
            T4++;
            if (T4>9){
              T4=0;
            }
            Escriu_Canvi_Hora(T1, T2, T3, T4);
            Cursor(1, 11);
            break;
        }
      } else if (Data == 1){
        switch (Cur){
          case 0:
            M1++;
            if (M1>1){
              M1=0;
            }
            Escriu_Canvi_Hora(M1, M2, D1, D2);
            Cursor(1, 6);
            break;
          case 1:
            M2++;
            if (M1==1 && M2>2){
              M2=0;
            }
            if (M1<1 && M2>9){
              M2=1;
            }
            Escriu_Canvi_Hora(M1, M2, D1, D2);
            Cursor(1, 7);
            break;
          case 2:
            D1++;
            if (D1>2 && M1*10+M2==2){
              D1=0;
            }
            if (D1>3){
              D1=0; 
            }
            Escriu_Canvi_Hora(M1, M2, D1, D2);
            Cursor(1, 10);
            break;
          case 3:
            D2++;
            if (D1<3 && D2>9){
              D2=0;
            }
            if (D1==3){
              if (Dies_Mes[Mes]==30){
                D2=0;                                    
              } else {
                if (D2>1){
                  D2=0;
                }
              }
            }
            Escriu_Canvi_Hora(M1, M2, D1, D2);
            Cursor(1, 11);
            break;
        }
      } else {
        switch (Cur){
          case 1:
            Y2++;
            if (Y2>9){
              Y2=0;
            }
            Escriu_Canvi_Hora(Y1, Y2, Y3, Y4);
            Cursor(1, 7);
            break;                        
          case 2:
            Y3++;
            if (Y3>9){
              Y3=0;
            }
            Escriu_Canvi_Hora(Y1, Y2, Y3, Y4);
            Cursor(1, 10);
            break;                        
          case 3:
            Y4++;
            if (Y4>9){
              Y4=0;
            }
            Escriu_Canvi_Hora(Y1, Y2, Y3, Y4);
            Cursor(1, 11);
            break;
        }                    
      }
    }
    if (Ret==1){
      Dia = D1*10+D2;
      Mes = M1*10+M2;
      Any = Y1*1000+Y2*100+Y3*10+Y4; 
      Dia_Setmana = Zeller(Dia, Mes, Any);
      Escriu_Canvi_Hora(M1, M2, D1, D2);
      Cursor(1, 11);
      return;
    }
  }
}
void Menu_Canvi_Data(){  
  EnviaL('M');
  EnviaL('O');    
  EnviaL('N');
  EnviaL('T');
  EnviaL('H');    
  EnviaL((char) 47);
  EnviaL('D');
  EnviaL('A');
  EnviaL('Y');         
  Cursor(2, 12);
  EnviaL('Y');
  EnviaL('E');        
  EnviaL('A');
  EnviaL('R');
  EnviaL(254);
  EnviaL(14);    
  return;
}
void Canvi_Data(void){
  Cursor(2, 1);    
  Cur = 0;
  Menu_Canvi_Data();  
  while(1) {        
    Polsad = Polsador();
    Pols_Funcio(2, 1, 1, 0, 0, 1, 13, 0, 0);
    if (FiTimer0==1){
      Rellotge();           
      Cursor(2, 1);
      Menu_Canvi_Data();            
      Cursor(2, 11*Cur+1);            
    }
    if (Selector==0){
      while(Selector==0)
        ;
      __delay_ms(10);
      switch (Cur){
        case 0:
          Data=1;
          Canvi_Hora();
          break;
        case 1:
          Data=2;
          Canvi_Hora();
          break;                    
      }              
    }
    if (Ret==1){
      return;
    }
  }
}
void Escriu_Data(char D1, char D2, char Mes, char Y1, char Y2, char Y3, char Y4, char Dia_Setmana) {    
  Cursor(2, 1);       
  EnviaL(Setmana[Dia_Setmana*3]);
  EnviaL(Setmana[Dia_Setmana*3+1]);
  EnviaL(Setmana[Dia_Setmana*3+2]);
  EnviaL((char) 44);
  EnviaL((char) 32);
  EnviaL((char) 48 + D1);
  EnviaL((char) 48 + D2);
  EnviaL((char) 32);
  EnviaL(Smes[(Mes-1)*3]);
  EnviaL(Smes[(Mes-1)*3+1]);
  EnviaL(Smes[(Mes-1)*3+2]);
  EnviaL((char) 32);
  EnviaL((char) 48 + Y1);
  EnviaL((char) 48 + Y2);
  EnviaL((char) 48 + Y3);
  EnviaL((char) 48 + Y4);    
}
char Zeller(char zdia,  char zmes, int zany){
  // Determina dia de la setmana a partir del dia, del mes i de l'any
  int h;
  char K;
  char J;
  // Tenim en compte el cas de gener i febrer
  if (zmes == 1) {
    zmes = 13;
    zany--;
  }
  if (zmes == 2) {
    zmes = 14;
    zany--;
  }
  // Calculem K y J.
  K = zany % 100;
  J = zany / 100;
  h = zdia + 13 * (zmes + 1) / 5 + K + K / 4 +  J/4 + 5 * J;
  h = h % 7;
  return h;
}
char Es_Bisiest(int Any){  // Determina si un any és bisiest    
  if ((Any % 4 == 0 && Any % 100 != 0) || (Any % 400 == 0)){
    return 1;
  } else {
    return 0;
  }          
}
int Juliano (int Any, char Mes, char Dia){
  // Transforma el dia, el mes i l'any a la nostra adaptació del concepte de dia Juliano
  int Dia_Juliano=0;
  for (char j=0;j<Mes-1;j++){
    Dia_Juliano = Dia_Juliano + Dies_Mes[j];
  }
  if (Mes>2 && Es_Bisiest(Any)==1){
    Dia_Juliano++;
  }
  Dia_Juliano = Dia_Juliano + Dia;
  return Dia_Juliano;
} 
void Juliano_a_Data(int Juliano){
  // Transforma la nostra adaptació del concepte de dia Juliano en data: en dia, mes i any 
  char g;
  int suma;
  char j;
  suma=0;
  j = 0;
  g = Es_Bisiest(Any);
  while(Juliano>=suma){
    j++;
    suma=suma+Dies_Mes[j];
    if(g==1 && j>2){
      suma++;
    }
  }
  if (Juliano == 60 && g==1){
    j--;
    suma = suma - 28;
  }
  Mes = j;
  M1 = Mes/10;
  M2 = Mes-M1*10;
  j = Juliano -(suma - Dies_Mes[Mes]);
  if(j<10){
    D1=0;
    D2=j;
  } else {
     D1=j/10;
     D2=j-D1*10;        
  }
  Dia = D1*10+D2;
}
void Pols_Funcio(char x, char p1, char p2, char p3, char p4, char c1, char c2, char c3, char c4){
  // Funció que determina quin polsador està actiu i en quina posició col:loca el cursor 
  Ret = 0;
  if (Polsad == 1 && p1==1) {
    Cursor(x, c1);
    Cur=0;        
  }
  if (Polsad == 2 && p2==1) {
    Cursor(x, c2);
    Cur=1;        
  }  
  if (Polsad == 3 && p3==1) {
    Cursor(x, c3);
    Cur=2;        
  }  
  if (Polsad == 4 && p4==1) {
    Cursor(x, c4);
    Cur=3;        
  }  
  if (Polsad == 5) {
    if (Q_Menu == 3){            
      AHD=T1;
      AHU=T2;
      AMD=T3;
      AMU=T4; 
    }
    if (Q_Menu == 1){
      HD=T1;
      HU=T2;
      MD=T3;
      MU=T4;
      SD=0;
      SU=0;
    }
    if (Q_Menu == 2){
       Dia_Setmana = Zeller(Dia, Mes, Any);
       J_Dia = Juliano (Any, Mes, Dia);
    }
    Q_Menu = 0;
    Data = 0;        
    Ret = 1;
    EnviaL(254);
    EnviaL(12);        
    Escriu_Temps(HD, HU, MD, MU, SD, SU);
    return;
  }  
}
void TocaNota(char valPre, char valPos, char valPR2, int numbuc, int numsil) { // Funció per tocar una nota
  while(T2CONbits.TMR2ON)  // Si està tocant una nota
    ;  // Esperem que acabi     
  valPos &= 0b00001111;  // Per precaució, posem a zero els bits no emprats
  valPre &= 0b00000011;  // Per precaució, posem a zero els bits no emprats
  T2CON = ((valPos<<3) | valPre);  // Ho posa a la configuració del temporitzador
  PR2 = valPR2;  // Preselecció del Timer2
  bucles = numbuc;  // Comptador d'iteracions
  silenci = numsil;  // Durada del silenci
  controla = 0;  // Comencem tocant la nota
  PIE1bits.TMR2IE = 1;  // Activem les interrupcions per Timer2
  T2CONbits.TMR2ON = 1;  // Activem el Timer2
}

 

 

Llicència de Creative Commons
Aquesta obra d'Oriol Boix està llicenciada sota una llicència no importada Reconeixement-NoComercial-SenseObraDerivada 3.0.