En aquest cas és un rellotge despertador que, a més de poder ajustar la data i l'hora, incorpora una funció especial. En el moment que sona l'alarma es pot, prement alguns dels polsadors, canviar a una altra melodia.
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 "pic16f690.h" // Carrega el fitxer d'adreces i paràmetres del PIC 16F690 #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 Stop RA3 // Li assigna un nom a l'adreça del polsador
unsigned char Valor; char Polsad; char z=0; // Fer que alarma acabi char A; // Nombre decimal char E; // Dígit esquerre decimal char D; // Dígit dret decimal char L; // Lectura char X; // Dígit a introduir char HR; // Hora rellotge char MR; // Minuts rellotge char i=0; // Comptador de canvi d'hora char a=0; // Entrar modo alarma char interruptor=0; // Interruptor de poder canviar l'hora char h=00; // Hora alarma char m=00; // Minut alarma char w=0; // Activador d'alarma1 char q=0; // Activador d'alarma2 char c=0; // Activador cucaracha char r=0; // Activador música relax char cumple=0; char AdreI2C = 0b11010000; // Adreça del dispositiu I2C (1101000) // Rodada cap a l'esquerra (preparada per afegir el bit RW) char Posicio = 0; // Posició a la pantalla char Lectura; // Aquí guardarem el resultat de la lectura char Port = 0; // Valor a escriure al port C // RC7 és SDA // RC6 és SCL
char Polsador(void); char LlegirI2C(char AdreMem); // Llegeix un byte I2C void EscriuI2C(char AdreMem, char Dades); // Escriu un byte I2C void SDAentrada(void); // Posa SDA com a entrada void SDAsortida(void); // Posa SDA com a sortida void StartI2C(void); // Envia el bit d'inici I2C void StopI2C(void); // Envia el bit d'aturada I2C void ACK_S(void); // Reb un ACK des de l'esclau void NACK_M(void); // Envia un NACK a l'esclau void EnvByteI2C(char Buffer); // Funció interna que envia un byte a I2C char RebByteI2C(void); // Funció interna que rep un byte a I2C void EnviaL(char Caracter); // Envia un caràcter void EnviaBCD2(char Caracter); // Mostrem a la pantalla un valor BCD // a partir de dues xifres hexadecimals void EnviaBCD1(char Caracter); // Mostrem a la pantalla un valor BCD // a partir d'una xifra hexadecimal void Alarma(void); // Funció per l'alarma void Hora(void); // Funció canvi hora void Minuts(void); // Funció canvi minuts void TocaNota(char ValPR2, char ValCCPR1L, char ValDC1B); // Fes sonar notes void Esborra(void); // Esborra la pantalla void Bit1(void); // Fila inferior void Bit2(void); // Fila superior void Cucaracha(void); void Relax(void); void DO(void); void RE(void); void MI(void); void FA(void); void SOL(void); void LA(void); void SI(void); void DOO(void); void Cumple(void);
void main (void) {
ANSEL = 0b00000101; // Configura AN0 i AN2 com entrada analògica
ANSELH = 0; // Desactiva les altres entrades analògiques
TRISA = 0xFF; // Tot el port A és d'entrada
TRISB = 0; // Tot el port B és de sortida
TRISC = 0; // Tot el port C és de sortida
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ó
PORTB = 0; // Inicialitza a 0 el port B
PORTC = 0; // Inicialitza a 0 el port C
// Com a mostra, es posen les 23.58.34
// del dijous 31-3-2016
// per poder veure un canvi de dia i de mes
EscriuI2C(0, 0x45); // Segons
EscriuI2C(1, 0x01); // Minuts
EscriuI2C(2, 0x00); // Hores
EscriuI2C(3, 0x02); // Dia setmana (dijous)
EscriuI2C(4, 0x11); // Dia mes
EscriuI2C(5, 0x01); // Mes (març)
EscriuI2C(6, 0x18); // Any (2016)
EscriuI2C(7, 0x00); // Polsos desactivats
while (1) {
__delay_ms(100); //
Bit1(); // Posiciona't a la fila d'avall
Lectura = LlegirI2C(2); // Hores
EnviaBCD2(Lectura); // Mostrem a la pantalla el valor
EnviaL('.'); // Separador
Lectura = LlegirI2C(1); // Minuts
EnviaBCD2(Lectura); // Mostrem a la pantalla el valor
EnviaL('.'); // Separador
Lectura = LlegirI2C(0); // Segons
EnviaBCD2(Lectura); // Mostrem a la pantalla el valor
Bit2();
Lectura = LlegirI2C(4); // Dia
EnviaBCD2(Lectura); // Mostrem a la pantalla el valor
EnviaL('-'); // Separador
Lectura = LlegirI2C(5); // Mes
EnviaBCD2(Lectura); // Mostrem a la pantalla el valor
EnviaL('-'); // Separador
EnviaL('2'); // Any primer dígit
EnviaL('0'); // Any segon dígit
Lectura = LlegirI2C(6); // Any segona part
EnviaBCD2(Lectura); // Mostrem a la pantalla el valor
EnviaL(' '); // Espai
EnviaL(' '); // Espai
Lectura = LlegirI2C(3); // Dia
EnviaBCD1(Lectura); // Mostrem a la pantalla el valor
Polsad = Polsador(); // Llegim els polsadors
Port = Port & 0b11110000; // Abans de començar, SDA ha d'estar activat
if (interruptor==1){ // Si interruptor activat, entrem a poder canviar l'hora
if (Polsad == 2) { // Si s'ha premut el polsador 2, serveix per disminuir
if(i==0){ //Canviem hora
Bit1();
L=LlegirI2C(2); // Hores
E=L/16; // Dígit esquerre hora
D=L%16; // Dígit dreta hora
A=E*10+D; // Decimal hora
if (D==0){
if (E==0){ // Si l'hora és 00 passarem a 23
EnviaBCD2(23);
EscriuI2C(2, 0x23);
} else{ // Sinó disminuim 1 al dígit esquerre i el dret passa a ser 9
E=E-1;
D=9;
X=E*16+D;
EnviaBCD2(X);
EscriuI2C(2, X);
}
} else{ // Disminució normal de l'hora
D=A%10-1;
X=E*16+D;
EnviaBCD2(X);
EscriuI2C(2, X);
}
}
if(i==1){ // Disminució dels minuts
Bit1();
L=LlegirI2C(1); // Minuts
E=L/16;
D=L%16;
A=E*10+D;
if (D==0){
if(E==0){
EnviaBCD2(59);
EscriuI2C(1, 0x59);
} else{
E=E-1;
D=9;
X=E*16+D;
EnviaBCD2(X);
EscriuI2C(1, X);
}
} else{
D=A%10-1;
X=E*16+D;
EnviaBCD2(X);
EscriuI2C(1, X);
}
}
if(i==2){ // Disminució del dia
Bit2();
L = LlegirI2C(4); // Dia
E=L/16;
D=L%16;
if (D==1){
if(E==0){
EnviaBCD2(31);
EscriuI2C(4, 0x31);
} else{
D=0;
X=E*16+D;
EnviaBCD2(X);
EscriuI2C(4, X);
}
} else if (D==0){
E=E-1;
D=9;
X=E*16+D;
EnviaBCD2(X);
EscriuI2C(4, X);
} else{
D=D-1;
X=E*16+D;
EnviaBCD2(X);
EscriuI2C(4, X);
}
}
if (i==3){ // Disminuir dia del mes
Bit2();
L = LlegirI2C(5); // Mes
E=L/16;
D=L%16;
if (D==1){
if(E==0){
EnviaBCD2(12);
EscriuI2C(5, 0x12);
} else{
EnviaBCD2(10);
EscriuI2C(5, 0x10);
}
} else if (D==0){
if (E==1){
EnviaBCD2(9);
EscriuI2C(5, 0x9);
}
} else{
D=D-1;
X=E*16+D;
EnviaBCD2(X);
EscriuI2C(5, X);
}
}
if (i==4){ // Disminuim any
Bit2();
L=LlegirI2C(6);
E=L/16;
D=L%16;
if(D==0){
if(E==0){
EnviaBCD2(99);
EscriuI2C(6, 0x99);
} else{
E=E-1;
D=9;
X=E*16+D;
EnviaBCD2(X);
EscriuI2C(6, X);
}
} else{
D=D-1;
X=E*16+D;
EnviaBCD2(X);
EscriuI2C(6, X);
}
}
if(i==5){ // Disminuir dia setmana
Bit2();
L=LlegirI2C(3);
E=L/16;
D=L%16;
A=E*10+D;
if(A==1){
EnviaBCD2(07);
EscriuI2C(3, 0x07);
} else{
A=A-1;
D=A%16;
E=A/16;
X=E*16+D;
EnviaBCD2(X);
EscriuI2C(3, X);
}
}
}
if (Polsad == 1) { // Si s'ha premut el polsador 1, serveix per augmentar
if (i==0){ // Augmentem hores
Hora();
}
if(i==1){ // Augmentem minuts
Minuts();
}
if(i==2){ // Augmentem dies
Bit2();
L = LlegirI2C(4); // Dia
E=L/16;
D=L%16;
A=E*10+D;
if (D==1){
if(E==3){
EnviaBCD2(01);
EscriuI2C(4, 0x01);
} else{
D=D+1;
X=E*16+D;
EnviaBCD2(X);
EscriuI2C(4, X);
}
} else if (D==9){
E=E+1;
D=0;
X=E*16+D;
EnviaBCD2(X);
EscriuI2C(4, X);
} else{
D=A%10+1;
X=E*16+D;
EnviaBCD2(X);
EscriuI2C(4, X);
}
}
if (i==3){ // Augmentar dia del mes
Bit2();
L = LlegirI2C(5); // Mes
E=L/16;
D=L%16;
A=E*10+D;
if (D==9){
EnviaBCD2(10);
EscriuI2C(5, 0x10);
} else if (D==2){
if (E==1){
EnviaBCD2(01);
EscriuI2C(5, 0x01);
} else{
D=D+1;
X=E*16+D;
EnviaBCD2(X);
EscriuI2C(5, X);
}
} else{
D=D+1;
X=E*16+D;
EnviaBCD2(X);
EscriuI2C(5, X);
}
}
if(i==4){ // Augmentem any
Bit2();
L=LlegirI2C(6);
E=L/16;
D=L%16;
A=E*10+D;
if(D==9){
if(E==9){
EnviaBCD2(00);
EscriuI2C(6, 0x00);
} else{
D=0;
E=E+1;
X=E*16+D;
EnviaBCD2(X);
EscriuI2C(6, X);
}
} else{
D=D+1;
X=E*16+D;
EnviaBCD2(X);
EscriuI2C(6, X);
}
}
if(i==5){
Bit2();
L=LlegirI2C(3);
E=L/16;
D=L%16;
A=E*10+D;
if(A==7){
EnviaBCD2(01);
EscriuI2C(3, 0x01);
} else{
A=A+1;
D=A%16;
E=A/16;
X=E*16+D;
EnviaBCD2(X);
EscriuI2C(3, X);
}
}
}
}
if (Polsad == 3) { // Serveix per anar passant en el rellotge
// depenent del que volem canviar
if (interruptor==1){ // Si l'interruptor està 'activat'
__delay_ms(1000);
i=i+1; // Augmentem la i, avançant així en el rellotge
RC0 = 1; // Per cada lloc que s'avanci, encén el LED de la dreta
// per així controlar quants llocs ens hem mogut
if (i==6){ // Si ja hem recorregut tot el rellotge, tornem a les hores
i=0;
}
}
}
if (Polsad == 5){ // 'Activa' l'interruptor
__delay_ms(300);
interruptor=1;
}
if (Polsad==4){ // 'Apaga' l'interruptor
__delay_ms(300);
interruptor=0;
i=0;
}
if (interruptor==0){
HR=LlegirI2C(2);
MR=LlegirI2C(1);
if (Polsad==4){
a=1;
Alarma();
}
while (HR==h && MR==m && z==0 && w==1){
Esborra();
Bit1();
TRISC = 0b11110000; // Posa els bits 0 i 2 del port C com a sortida
PORTC = 0b00001111; // Activa els bits 0 i 2 del port C i,
// per tant, encén els LED de manera intermitent
EnviaL('A');
EnviaL('L');
EnviaL('A');
EnviaL('R');
EnviaL('M');
EnviaL('A');
EnviaL(' ');
EnviaL(' ');
EnviaL(' ');
EnviaL(' ');
EnviaL(' ');
EnviaL('O');
EnviaL('N');
TRISC = 0b00100000;
PORTC = 0;
CCP1CON = 0b00001100;
CCPR1L = 49;
PIR1bits.TMR2IF = 0;
T2CON = 0b00000011;
TocaNota(141,71,0);
if (RA3==0){ // Que s'apagui l'alarma
z=1;
}
Polsad=Polsador();
if (Polsad==1){ // Activar c perquè s'entri en el while
c=1;
}
while (c==1){ // Que soni la cucaracha
Cucaracha();
}
if(Polsad==2){
r=1;
}
while (r==1){ // Que soni cançó més relaxant
Relax();
}
if(Polsad==5){
cumple=1;
}
while (cumple==1){ // Que soni cumpleaños feliz
Cumple();
}
}
}
}
}
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;
}
char LlegirI2C(char AdreMem) {
char Rebut; // Valor rebut
SDAsortida(); // Posa SDA com a sortida
StartI2C(); // Envia el bit d'inici I2C
EnvByteI2C(AdreI2C); // Enviem l'adreça del dispositiu
// Amb un zero al final per indicar escriptura
SDAentrada(); // Posa SDA com a entrada
ACK_S(); // Reb un ACK des de l'esclau
SDAsortida(); // Posa SDA com a sortida
EnvByteI2C(AdreMem); // Adreça a enviar
SDAentrada(); // Posa SDA com a entrada
ACK_S(); // Reb un ACK des de l'esclau
SDAsortida(); // Posa SDA com a sortida
StartI2C(); // Envia el bit d'inici I2C
EnvByteI2C(AdreI2C+1); // Enviem l'adreça del dispositiu
// Amb un 1 al final per indicar lectura
SDAentrada(); // Posa SDA com a entrada
ACK_S(); // Reb un ACK des de l'esclau
Rebut = RebByteI2C(); // Rep el byte
SDAsortida(); // Posa SDA com a sortida
NACK_M(); // Envia un NACK a l'esclau
StopI2C(); // Envia el bit d'aturada I2C
return Rebut; // Retorna el valor
}
void EscriuI2C(char AdreMem, char Dades) {
SDAsortida(); // Posa SDA com a sortida
StartI2C(); // Envia el bit d'inici I2C
EnvByteI2C(AdreI2C); // Enviem l'adreça del dispositiu
// Amb un zero al final per indicar escriptura
SDAentrada(); // Posa SDA com a entrada
ACK_S(); // Reb un ACK des de l'esclau
SDAsortida(); // Posa SDA com a sortida
EnvByteI2C(AdreMem); // Adreça a enviar
SDAentrada(); // Posa SDA com a entrada
ACK_S(); // Reb un ACK des de l'esclau
SDAsortida(); // Posa SDA com a sortida
EnvByteI2C(Dades); // Dades a enviar
SDAentrada(); // Posa SDA com a entrada
ACK_S(); // Reb un ACK des de l'esclau
SDAsortida(); // Posa SDA com a sortida
StopI2C(); // Envia el bit d'aturada I2C
}
void SDAentrada() {
TRISCbits.TRISC7 = 1; // Posem SDA com a entrada
}
void SDAsortida() {
TRISCbits.TRISC7 = 0; // Posem SDA com a sortida
}
void StartI2C() {
Port = Port | 0b11000000; // Abans de començar, SDA ha d'estar activat
// i SCL també
PORTC = Port;
__delay_us(2); // Allarguem el pols
Port = Port & 0b01111111; // Bit d'inici, posem SDA a zero
PORTC = Port;
__delay_us(2); // Allarguem el pols
Port = Port & 0b10111111; // Fi del bit d'inici, posem SCL a zero
PORTC = Port;
}
void StopI2C() {
Port = Port & 0b01111111; // Desactivem SDA
Port = Port | 0b01000000; // i activem SCL
PORTC = Port;
__delay_us(2); // Allarguem el pols
Port = Port | 0b10000000; // Posem SDA a 1
PORTC = Port;
}
void ACK_S() {
Port = Port | 0b01000000; // Posem SCL a 1
PORTC = Port;
__delay_us(2); // Allarguem el pols
Port = Port & 0b10111111; // Posem SCL a zero
PORTC = Port;
Port = Port | 0b10000000; // Posem SDA a 1
PORTC = Port;
}
void NACK_M() {
Port = Port | 0b10000000; // Posem SDA a 1
PORTC = Port;
Port = Port | 0b01000000; // Posem SCL a 1
PORTC = Port;
__delay_us(2); // Allarguem el pols
Port = Port & 0b10111111; // Posem SCL a zero
PORTC = Port;
}
void EnvByteI2C(char Buffer) {
char Temp; // Variable temporal
for (int k = 1; k < 9; k++){
Port = Port & 0b10111111; // Posem SCL a zero per modificar SDA
PORTC = Port;
Temp = Buffer & 0b10000000; // Agafa el bit de més a l'esquerra
// Temp només podrà valer 0 o 128
if (Temp == 0) { // Si val 0
Port = Port & 0b01111111; // Desactivem SDA
} else { // Si val 128
Port = Port | 0b10000000; // Posem SDA a 1
}
Buffer = Buffer << 1; // Rodem els bits per situar el següent
PORTC = Port;
Port = Port | 0b01000000; // Activem SCL perquè el receptor llegeixi el bit
PORTC = Port;
}
Port = Port & 0b10111111; // Posem SCL a zero per modificar SDA
PORTC = Port;
}
char RebByteI2C() {
char Buffer; // Valor rebut
Port = Port & 0b10111111; // Posem SCL a zero
PORTC = Port;
for (int k = 1; k < 9; k++){
Port = Port | 0b01000000; // Posem SCL a 1
PORTC = Port;
Buffer = Buffer << 1; // Rodem els bits per situar el següent
// a la dreta hi quedarà un zero
if (RC7 == 1) {
Buffer = Buffer | 0b00000001; // Si SDA està activat, posem un 1
}
Port = Port & 0b10111111; // Posem SCL a zero
PORTC = Port;
}
return Buffer; // Retorna el valor
}
void EnviaL(char Caracter) {
TXREG = Caracter; // Agafa el caràcter i l'envia
_delay(5); // Donem temps
while (PIR1bits.TXIF == 0); // Esperem a que s'acabi d'enviar
; // No fem res
}
void EnviaBCD2(char Caracter) {
char Temp; // Variable temporal
Temp = Caracter & 0b11110000; // Agafem el primer dígit
Temp = Temp >> 4; // Rodem els bits per situar-los a la dreta
Temp = Temp + '0'; // Ho convertim a ASCII
EnviaL(Temp); // Envia el primer dígit
Temp = Caracter & 0b00001111; // Agafem el segon dígit
Temp = Temp + '0'; // Ho convertim a ASCII
EnviaL(Temp); // Envia el segon dígit
}
void EnviaBCD1(char Caracter) {
char Temp; // Variable temporal
Temp = Caracter & 0b00001111; // Agafem el segon dígit
Temp = Temp + '0'; // Ho convertim a ASCII
EnviaL(Temp); // Envia el segon dígit
}
void Alarma(void){
EscriuI2C(9, m); // Minuts
EscriuI2C(8, h); // Hores
z=0; // Activador1 encès
while(a==1){
__delay_ms(200);
Polsad=Polsador();
Esborra();
Bit1();
Lectura = LlegirI2C(8); // Hores
EnviaBCD2(Lectura); // Mostrem a la pantalla el valor
EnviaL('.'); // Separador
Lectura = LlegirI2C(9); // Minuts
EnviaBCD2(Lectura); // Mostrem a la pantalla el valor
EnviaL(' '); // Espai
EnviaL(' '); // Espai
EnviaL(' '); // Espai
EnviaL(' ');
EnviaL(' '); // Espai
EnviaL(' ');
EnviaL('O'); // Espai
if (RA3==0 && q==0){
__delay_ms(200);
q=1;
} else if (RA3==0 && q==1){
__delay_ms(200);
q=0;
}
if (q==1){
EnviaL('N'); // escriu 'ON'
w=1; // Alarma activada
} else if (q==0){
EnviaL('F');
EnviaL('F'); // escriu off
w=0; // Alarma apagada
}
if(Polsad==5){
h=LlegirI2C(8);
m=LlegirI2C(9);
a=0;
}
if (Polsad==1){ // Augmentem hores
Bit1();
L=LlegirI2C(8);
E=L/16;
D=L%16;
A=E*10+D;
if (A==9){
EnviaBCD2(10);
EscriuI2C(8, 0x10);
} else if (A==19){
EnviaBCD2(20);
EscriuI2C(8, 0x20);
} else if (A==23){
EnviaBCD2(00);
EscriuI2C(8, 0x00);
} else{
E=A/10;
D=A%10+1;
X=E*16+D;
EnviaBCD2(X);
EscriuI2C(8, X);
}
}
if (Polsad==2){
Bit1();
L=LlegirI2C(9); // Augmentem Minuts
E=L/16;
D=L%16;
A=E*10+D;
if (D==9){
if(E==5){
EnviaBCD2(00);
EscriuI2C(9, 0x00);
} else{
E=E+1;
D=0;
X=E*16+D;
EnviaBCD2(X);
EscriuI2C(9, X);
}
} else{
D=A%10+1;
X=E*16+D;
EnviaBCD2(X);
EscriuI2C(9, X);
}
}
}
}
void Esborra(void) {
EnviaL(254); // Caràcter de control
EnviaL(1); // Esborra la pantalla i posa el cursor a l'inici
}
void Hora(void){
Bit1();
L=LlegirI2C(2);
E=L/16;
D=L%16;
A=E*10+D;
if (A==9){
EnviaBCD2(10);
EscriuI2C(2, 0x10);
} else if (A==19){
EnviaBCD2(20);
EscriuI2C(2, 0x20);
} else if (A==23){
EnviaBCD2(00);
EscriuI2C(2, 0x00);
} else{
E=A/10;
D=A%10+1;
X=E*16+D;
EnviaBCD2(X);
EscriuI2C(2, X);
}
}
void Minuts(void){
Bit1();
L=LlegirI2C(1); // Minuts
E=L/16;
D=L%16;
A=E*10+D;
if (D==9){
if(E==5){
EnviaBCD2(00);
EscriuI2C(1, 0x00);
} else{
E=E+1;
D=0;
X=E*16+D;
EnviaBCD2(X);
EscriuI2C(1, X);
}
} else{
D=A%10+1;
X=E*16+D;
EnviaBCD2(X);
EscriuI2C(1, X);
}
}
void Bit1(void){
Posicio = 64; // La primera columna de la segona fila és 64
Posicio = Posicio + 128; // Posa el bit de posicionat a 1
EnviaL(254);
EnviaL(Posicio);
}
void Bit2(void){
Posicio = 0; // La primera columna de la primera fila és 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 TocaNota(char ValPR2, char ValCCPR1L, char ValDC1B) {
TRISC = 0b00100000; // Definim com volem les E/S del port C
// RC5 (sortida del PWM), de moment, com a entrada
PR2 = ValPR2; // Carrega PR2
CCP1CON = CCP1CON & 0b11001111; // Posa a zero els bits que corresponen a DC1B
ValDC1B = ValDC1B % 4; // DC1B va de 0 a 3
ValDC1B = ValDC1B * 16; // Desplaça els bits a la posició que els correspon a CCP1CON
CCP1CON = CCP1CON + ValDC1B; // Coloca DC1B al seu lloc
CCPR1L = ValCCPR1L; // Carrega CCPR1L, registre que ens dona l'amplada de tON
PIR1bits.TMR2IF = 0; // Desactiva el bit d'interrupció del Timer 2
T2CON = 0b00000111; // Configura el Timer 2
// bits T2KCPS (bits 1-0) a 11 prescalat de 16
// bit 2 (TMR2ON) a 1, Timer activat
// Postscaler TOUTPS (bits 6-3) no afecten al PWM
while (PIR1bits.TMR2IF == 0) // Espera l'activació del bit d'interrupció del Timer 2
; // Esperem
TRISC = 0b00000000; // Posem RC5 (sortida del PWM) com a sortida
__delay_ms(200); // Retard de 0,2 s
TRISC = 0b00100000; // Posem RC5 (sortida del PWM) com a entrada
// O sigui, silenci
__delay_ms(200); // Retard de 0,2 s
}
void Cucaracha(void){
DO();
DO();
DO();
FA();
LA();
DO();
DO();
DO();
FA();
LA();
FA();
FA();
MI();
MI();
RE();
RE();
DO();
DO();
DO();
DO();
MI();
SOL();
DO();
DO();
DO();
MI();
SOL();
DO();
RE();
DO();
SI();
LA();
SOL();
FA();
c=0;
z=1;
}
void Relax(){
MI();
MI();
SOL();
MI();
MI();
SOL();
MI();
SOL();
DO();
SI();
LA();
LA();
SOL();
RE();
MI();
FA();
RE();
RE();
MI();
FA();
RE();
FA();
SI();
LA();
SOL();
SI();
DOO();
DO();
DO();
r=0;
z=1;
}
void Cumple(void){
DO();
DO();
RE();
DO();
FA();
MI();
DO();
DO();
RE();
DO();
SOL();
FA();
DO();
DO();
DOO();
LA();
FA();
FA();
MI();
RE();
SI();
SI();
LA();
FA();
SOL();
FA();
cumple=0;
z=1;
}
void DO(void){
TocaNota(238,119,2);
__delay_ms(100);
}
void RE(void){
TocaNota(212,106,2);
__delay_ms(100);
}
void MI(void){
TocaNota(189,95,0);
__delay_ms(100);
}
void FA(void){
TocaNota(178,89,2);
__delay_ms(100);
}
void SOL(void){
TocaNota(158,79,2);
__delay_ms(100);
}
void LA(void){
TocaNota(141,71,0);
__delay_ms(100);
}
void SI(void){
TocaNota(126,63,2);
__delay_ms(100);
}
void DOO(void){
TocaNota(118,59,2);
__delay_ms(100);
}

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