Programació en C del PIC 16F690

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

Rellotge digital

Programa del grup 4

En aquest cas es tracta d'un rellotge despertador.

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 Polpi   RA3			// Li assigna un nom a l'adreça del polsador
char AdreI2C = 0b11010000;			// Adreça del dispositiu I2C (1101000)
						// Rodada cap a l'esquerra (preparada per afegir el bit RW)
char Polsad;
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
						// Definició de les funcions que farem servir
char n = 0;					// Cops apretat polsador polpi
char a = 0;					// Cops apretat pols=3
char d = 0;					// Cops apretat pols=4
char b = 0;
char LlegirI2C(char AdreMem);			// Llegeix un byte I2C
char Polsador(void);				// Funció de lectura dels polsadors    
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 Increment(char AdreMem, char Dades);
void Decrementa(char AdreMem, char Dades);
void Canvi (void);
void Canvi_alarm(void);
void Canvi_minuts(void);
void Apaga_alarma(void);
void SetAlarm (void);
void Esborra(void);				// Esborra la pantalla i posa el cursor a l'inici
void TocaNota(char ValPR2, char ValCCPR1L, char ValDC1B);
void Compara(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
	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
	ADCON1 = 0b00010000;			// Posa el conversor a 1/8 de la freqüència
	ADCON0 = 0b00001001;			// Activa el conversor A/D connectat a AN2
						// RC5 (sortida del PWM), de moment, com a entrada
	CCP1CON = 0b00001100;			// Configura el PWM, bits P1M (bits 7-6) a 00 mode senzill
						// DC1B = 11 (bits 5-4) els dos bits de menys pes són 0
						// CCP1M = 11xx en mode senzill els bit 0 i 1 no afecten
						// Ho posa com a configuració del PWM
	CCPR1L = 49;				// Valor que correspon a un cicle del 35 % a 440 Hz
						// Registre que ens dona l'amplada de tON
	PIR1bits.TMR2IF = 0;			// Desactiva el bit d'interrupció del Timer 2
	T2CON = 0b00000011;			// Configura el Timer 2
						// bits T2KCPS (bits 1-0) a 11 prescalat de 16
						// bit 2 (TMR2ON) a 0, Timer aturat
						// Postscaler TOUTPS (bits 6-3) no afecten al PWM
						// 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, 0x55);			// Segons
	EscriuI2C(1, 0x59);			// Minuts
	EscriuI2C(2, 0x23);			// Hores
	EscriuI2C(3, 0x07);			// Dia setmana (dijous)
	EscriuI2C(4, 0x18);			// Dia mes
	EscriuI2C(5, 0x03);			// Mes (març)
	EscriuI2C(6, 0x18);			// Any (2016)
	EscriuI2C(7, 0x00);			// Polsos desactivats
	EscriuI2C(8, 0x00);			// Minuts alarma
	EscriuI2C(9, 0x00);			// Hores alarma
	while (1) {
		Polsad=Polsador();
		__delay_ms(350);		// Retard d'1 s
		Posicio = 64;			// La primera columna de la segona fila és 64
		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
		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
		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
		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
		EnviaBCD2(Lectura);		// Mostrem a la pantalla el valor
		EnviaL(' ');			// Espai
		EnviaL(' ');			// Espai
		Lectura = LlegirI2C(3);		// Dia
		EnviaBCD1(Lectura);		// Mostrem a la pantalla el valor
		Canvi();
		Canvi_alarm();
		Apaga_alarma();
		if (b == 0){
			Posicio = 75;				// La primera columna de la segona fila és 64
			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
			EnviaL('0');
			EnviaL('F');
			EnviaL('F');
		}
		if (b == 1){
			Posicio = 75;				// La primera columna de la segona fila és 64
			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
			EnviaL('0');
			EnviaL('N');
			EnviaL(' ');
			Compara();
		}
		if (a == 1){
			SetAlarm();
			Canvi_minuts();
			Polsad = Polsador();
			if (d == 1){
				Posicio = 12;
				Posicio = Posicio + 128;
				EnviaL(254);
				EnviaL(Posicio);
				EnviaL('H');
				if (Polsad == 1){
					Increment(9,LlegirI2C(9));
				}
				if (Polsad ==2){
					Decrementa(9,LlegirI2C(9));
				}
			}
			if (d == 2){
				Posicio = 12;
				Posicio = Posicio + 128;
				EnviaL(254);
				EnviaL(Posicio);
				EnviaL('M');
				if (Polsad == 1){
					Increment(8,LlegirI2C(8));
				}
				if (Polsad ==2){
					Decrementa(8,LlegirI2C(8));
				}
			}
		}
		while (n!=0){
			Polsad = Polsador();
			Canvi();
			if (n == 1) {
				Posicio = 64;			// La primera columna de la segona fila és 64
				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
				EnviaBCD2(LlegirI2C(2));	// Mostrem a la pantalla el valor
				__delay_ms(500);
				Posicio = 64;			// La primera columna de la segona fila és 64
				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
				EnviaL(' ');
				EnviaL(' ');
				__delay_ms(500);
				if (Polsad == 1){
					Increment(2,LlegirI2C(2));
				}
				if (Polsad ==2){
					Decrementa(2,LlegirI2C(2));
				}
				Posicio = 64;			// La primera columna de la segona fila és 64
				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
				EnviaBCD2(LlegirI2C(2));	// Mostrem a la pantalla el valor
			}
			if (n == 2) {
				Posicio = 67;			// La primera columna de la segona fila és 64
				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
				EnviaBCD2(LlegirI2C(1));	// Mostrem a la pantalla el valor
				__delay_ms(500);
				Posicio = 67;			// La primera columna de la segona fila és 64
				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
				EnviaL(' ');
				EnviaL(' ');
				__delay_ms(500);
				if (Polsad == 1){
					Increment(1,LlegirI2C(1));
				}
				if (Polsad ==2){
					Decrementa(1,LlegirI2C(1));
				}
				Posicio = 67;			// La primera columna de la segona fila és 64
				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
				EnviaBCD2(LlegirI2C(1));	// Mostrem a la pantalla el valor
			}
			if (n == 3) {
				Posicio = 0;			// La primera columna de la segona fila és 64
				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
				EnviaBCD2(LlegirI2C(4));	// Mostrem a la pantalla el valor
				__delay_ms(500);
				Posicio = 0;			// La primera columna de la segona fila és 64
				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
				EnviaL(' ');
				EnviaL(' ');
				__delay_ms(500);
				if (Polsad == 1){
					Increment(4,LlegirI2C(4));
				}
				if (Polsad ==2){
					Decrementa(4,LlegirI2C(4));
				}
				Posicio = 0;			// La primera columna de la segona fila és 64
				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
				EnviaBCD2(LlegirI2C(4));	// Mostrem a la pantalla el valor
			}
			if (n == 4) {
				Posicio = 3;			// La primera columna de la segona fila és 64
				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
				EnviaBCD2(LlegirI2C(5));	// Mostrem a la pantalla el valor
				__delay_ms(500);
				Posicio = 3;			// La primera columna de la segona fila és 64
				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
				EnviaL(' ');
				EnviaL(' ');
				__delay_ms(500);
				if (Polsad == 1){
					Increment(5,LlegirI2C(5));
				}
				if (Polsad ==2){
					Decrementa(5,LlegirI2C(5));
				}
				Posicio = 3;			// La primera columna de la segona fila és 64
				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
				EnviaBCD2(LlegirI2C(5));	// Mostrem a la pantalla el valor
			}
			if (n == 5) {
				Posicio = 8;			// La primera columna de la segona fila és 64
				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
				EnviaBCD2(LlegirI2C(6));	// Mostrem a la pantalla el valor
				__delay_ms(500);
				Posicio = 8;			// La primera columna de la segona fila és 64
				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
				EnviaL(' ');
				EnviaL(' ');
				__delay_ms(500);
				if (Polsad == 1){
					Increment(6,LlegirI2C(6));
				}
				if (Polsad ==2){
					Decrementa(6,LlegirI2C(6));
				}
				Posicio = 8;			// La primera columna de la segona fila és 64
				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
				EnviaBCD2(LlegirI2C(6));	// Mostrem a la pantalla el valor
			}
			if (n == 6) {
				Posicio = 12;			// La primera columna de la segona fila és 64
				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
				EnviaBCD1(LlegirI2C(3));	// Mostrem a la pantalla el valor
				__delay_ms(500);
				Posicio = 12;			// La primera columna de la segona fila és 64
				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
				EnviaL(' ');
				__delay_ms(500);
				if (Polsad == 1){
					Increment(3,LlegirI2C(3));
				}
				if (Polsad ==2){
					Decrementa(3,LlegirI2C(3));
				}
				Posicio = 12;			// La primera columna de la segona fila és 64
				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
				EnviaBCD1(LlegirI2C(3));	// Mostrem a la pantalla el valor
			}
		}
	}    
}
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 Increment (char AdreMem, char Dades) {
	char E = Dades / 16;			// separació valors BCD
	char D = Dades%16;
	char ValDec = E * 10 + D;		// conversió a decimal
	++ValDec;
	if (AdreMem == 2){      		// Si el rellotge ha de marcar les 24 automatiament marca les 00
    	if (ValDec == 24)
        	ValDec = 00;
	}
	else if (AdreMem == 1){ 		// En arribar al minut 60, automaticament passa a 00
    	if (ValDec == 60)
        	ValDec = 00;
	}
	else if (AdreMem == 3){			// Quan hagués de ser el 8 dia de la setmana tornaria a possar 1
    	if (ValDec == 8)
        	ValDec = 1;
	}
	else if (AdreMem == 4){
    	if (ValDec == 32)
        	ValDec = 01;
	}
	else if(AdreMem == 5){			// Un cop passat el mes 12 torna a començar
    	if (ValDec == 13)
        	ValDec = 01;
	}
	else if (AdreMem == 6){			// Al arribar a l'any 99 torna a 00
    	if (ValDec == 100)
        	ValDec = 00;
	}
	else if (AdreMem == 8){			// Al arribar a l'any 99 torna a 00
    	if (ValDec == 60)
        	ValDec = 00;
	}
	else if (AdreMem == 9){			// Al arribar a l'any 99 torna a 00
    	if (ValDec == 24)
        	ValDec = 00;
	}
	E=ValDec/10;
	D=ValDec%10;
	Dades=E*16+D;				// conversió a BCD
	EscriuI2C(AdreMem, Dades);
}

void Decrementa (char AdreMem, char Dades) {
	char E = Dades / 16;			// separaciÛ valors BCD
	char D = Dades%16;
	signed char ValDec = E * 10 + D;	// conversió a decimal
	--ValDec;
	if (AdreMem == 2){      		// Si el rellotge ha de marcar les 24 automatiament marca les 00
    	if (ValDec < 0)
        	ValDec = 23;
	}
	else if (AdreMem == 1){ 		// En arribar al minut 60, automaticament passa a 00
    	if (ValDec < 00)
        	ValDec = 59;
	}
	else if (AdreMem == 3){			// Quan hagués de ser el 8 dia de la setmana tornaria a possar 1
    	if (ValDec == 0)
        	ValDec = 7;
	}
	else if (AdreMem == 4){
    	if (ValDec == 00)
        	ValDec = 31;
	}
	else if(AdreMem == 5){			// Un cop passat el mes 12 torna a començar
    	if (ValDec == 00)
        	ValDec = 12;
	}
	else if (AdreMem == 6){			// Al arribar a l'any 99 torna a 00
    	if (ValDec < 00)
        	ValDec = 99;
	}
	else if (AdreMem == 8){			// Al arribar a l'any 99 torna a 00
    	if (ValDec < 00)
        	ValDec = 59;
	}
	else if (AdreMem == 9){			// Al arribar a l'any 99 torna a 00
    	if (ValDec < 00)
        	ValDec = 24;
	}
	E=ValDec/10;
	D=ValDec%10;
	Dades=E*16+D;				// conversió a BCD
	EscriuI2C(AdreMem, Dades);
}

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 Canvi(void){
	if (Polpi == 0)	{
		n++;
		if (n==7){
			n=0;
		}
		_delay(250);
		while (Polpi==0){
			;
		}
	}
}
void Canvi_alarm(void){
	char Pols = Polsador();
	if (Pols == 3)	{
		a++;
		if (a==2){
			a=0;
		}
	}
}
void Canvi_minuts(void){
	char Pols = Polsador();
	if (Pols == 4)	{
		d++;
		if (d==3){
			d=0;
		}
	}
}
void Apaga_alarma(void){
	char Pols = Polsador();
	if (Pols == 5)	{
		b++;
		if (b==2){
			b=0;
		}
	}
}
void SetAlarm(void) {
	Esborra();
	Posicio = 0;
	Posicio = Posicio + 128;
	EnviaL(254);
	EnviaL(Posicio);
	EnviaL('A');
	EnviaL('L');
	EnviaL('A');
	EnviaL('R');
	EnviaL('M');
	Posicio = 64;				// La primera columna de la segona fila és 64
	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
	EnviaBCD2(LlegirI2C(9));
	EnviaL(':');   	 
	EnviaBCD2(LlegirI2C(8));    
}
void Esborra(void) {
	EnviaL(254);				// Caràcter de control
	EnviaL(1);				// Esborra la pantalla i posa el cursor a l'inici
}
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 Compara(void){
	if ((LlegirI2C(2) == LlegirI2C(9)) && (LlegirI2C(1) == LlegirI2C(8))){
		TocaNota(141, 71, 0);		// la3
		__delay_ms(500);
		Apaga_alarma();
		if (b==1){			// Cada vegada que toca una nota, mira que no s'hagi premut el polsador, així permet
						// poder parar la melodia de alarma quan es desitgi
			TocaNota(158, 79, 2);	// sol3
			__delay_ms(500);
			Apaga_alarma();
			if (b==1){
				TocaNota(189, 95, 0);		// mi3
				__delay_ms(100);
				Apaga_alarma();
				if (b==1){
					TocaNota(178, 89, 2);	// fa3
					__delay_ms(100);
					Apaga_alarma();
					if (b==1){
						TocaNota(158, 79, 2);		// sol3
						__delay_ms(400);
						Apaga_alarma();
						if (b==1){
							TocaNota(189, 95, 0);	// mi3
							__delay_ms(100);
							Apaga_alarma();
							if (b==1){
								TocaNota(178, 89, 2);		// fa3
								__delay_ms(100);
								Apaga_alarma();
								if (b==1){
									TocaNota(158, 79, 2);	// sol3
									__delay_ms(300);
									Apaga_alarma();
		if (b==1){
			TocaNota(178, 89, 2);	// fa3
			__delay_ms(50);
			Apaga_alarma();
			if (b==1){
				TocaNota(189, 95, 0);		// mi3
				__delay_ms(50);
				Apaga_alarma();
				if (b==1){
					TocaNota(212, 106, 2);	// re3
					__delay_ms(400);
					Apaga_alarma();
					if (b==1){
						TocaNota(141, 71, 0);		// la3
						__delay_ms(250);
						Apaga_alarma();
						if (b==1){
							TocaNota(158, 79, 2);	// sol3
							__delay_ms(200);
							Apaga_alarma();
							if (b==1){
								TocaNota(189, 95, 0);		// mi3
								__delay_ms(50);
								Apaga_alarma();
								if (b==1){
									TocaNota(178, 89, 2);	// fa3
									__delay_ms(50);
									Apaga_alarma();
		if (b==1){
			TocaNota(158, 79, 2);	// sol3
			__delay_ms(200);
			Apaga_alarma();
			if (b==1){
				TocaNota(189, 95, 0);		// mi3
				__delay_ms(50);
				Apaga_alarma();
				if (b==1){
					TocaNota(178, 89, 2);	// fa3
					__delay_ms(50);
					Apaga_alarma();
					if (b==1){
						TocaNota(158, 79, 2);		// sol3
						__delay_ms(200);
						Apaga_alarma();
						if (b==1){
							TocaNota(178, 89, 2);	// fa3
							__delay_ms(50);
							Apaga_alarma();
							if (b==1){
								TocaNota(189, 95, 0);		// mi3
								__delay_ms(50);
								Apaga_alarma();
								if (b==1){
									TocaNota(212, 106, 2);	// re3
									__delay_ms(2000);

								}
							}
						}
					}
				}
			}
		}
								}
							}
						}
					}
				}
			}
		}
								}
							}
						}
					}
				}
			}
		}
	}
}

 

 

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