Programació en C del PIC 16F690

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

Sensor de temperatura i humitat

Programa del grup 3

El grup 3 va fer un programa que mostrava la humitat i la temperatura, aquesta en kelvin, graus Celsius i graus Fahrenheit. El sistema incorpora també alarmes per temperatures extremes, en aquests casos la matriu mostra un floc de neu o un signe d'advertència.

El programa d'aquest grup é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 Sens   RA5			// Li assigna un nom a l'adreça del sensor
unsigned int Valorrr;				// Variable de treball K 
unsigned int Valorr;				// °F
unsigned int Valor;
unsigned int Error;				// Error de lectura
unsigned int T;
unsigned int H;
unsigned int K = 1;				// Alarma activada   K=0 alarma desactivada
unsigned int C = 0;				// Polsador NO premut   C=1 polsador premut
unsigned int Lectura[3];			// Valor llegit
						// Lectura[0] és la suma de comprovació
						// Lectura[1] és la temperatura
						// Lectura[2] és la humitat
char Digits[5];					// Vector amb el número dígit a dígit
						// Digits[0] és el decimal
char Sortida[6];				// Valors a enviar al MAX7221 (48 bits)
const char Llista[8] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08};
const char alerta[];
const char fred[];
const char calor[];
const char humbaix[];
const char humalt[];
char Polsad;
char Actiu; 					// Variable que diu quin color està actiu
						// Actiu = 0		Apagat
						// Actiu = 1		Vermell
						// Actiu = 2		Verd
						// Actiu = 3		Blau
bit Negatiu;					// Guarda si el valor de la temperatura és negatiu o positiu
						// Definició de les funcions que farem servir 
void Envia3max(char Valor[6]);			// Envia un joc de valors als tres MAX7221
void Ini3max(void);				// Inicialitza els tres MAX7221
void Apaga(void);				// Apaga tots els LED
char Sensor(void);				// Lectura del sensor. dona 0 si la suma de control és correcta
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 (filera 1 a 2 i columna 1 a 32, segons pantalla)
void EnviaSens(int X);				// Mostra per pantalla la T i la HR
void Matriu(int M);				// Envia la matriu
char Polsador(void);				// Funció de lectura dels polsadors
void TocaNota(char ValPR2, char ValCCPR1L, char ValDC1B);
void main (void) {
	OPTION_REG = 0b10000101;       		// Configuració de Timer0
						// Com a temporitzador basat en rellotge
						// 101 - Factor d'escala de 64
	ANSEL = 0b00000001;			// Configura AN0 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
	PORTA = 0b00100000;			// RA5 a 1
	PORTC = 0;				// Inicialitza a 0 el 
	PORTB = 0;				// Inicialitza a 0 el 
	T1CON = 0b00100001;			// Configuració de Timer1
						// Com a temporitzador basat en rellotge
						// 10 - Factor d'escala de 4
						// TMR1L s'incrementarà cada 2 us
	Ini3max();				// Inicialitza els tres MAX7221
	Apaga();				// Apaga tots els LED
	Actiu = 1;				// Activa el color vermell
	TMR0 = 139;				// Presselecció de 139, que són 117 iteracions
						// Correspon a una interrupció cada 7,5 ms
	INTCON = 0b10100000;			// Activem GIE i T0IE
	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ó
	TRISA = 0xFF;				// Tot el port A és d'entrada
	ADCON1 = 0b00010000;			// Posa el conversor a 1/8 de la freqüència
	ADCON0 = 0b00001001;			// Activa el conversor A/D connectat a AN2
						// amb el resultat justificat per l'esquerra
	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 
	__delay_ms(1000);			// Retard d'1 s
	Esborra();				// Esborra la pantalla i posa el cursor a l'inici
	while (1) {				// Inici del bucle de programa
		INTCONbits.GIE = 0;              
		OSCCON = 0b01111000;		// IRCF = 111, rellotge a 8 MHz
		Error = Sensor();
		OSCCON = 0b01101000;		// IRCF = 110, rellotge a 4 MHz
		INTCONbits.GIE = 1;
		Polsad = Polsador();		// Llegim els polsadors
		if (Error == 0) {		// Llegeix el sensor i si és correcte segueix
			Esborra();
						// MOSTRA T I HR per pantalla
			EnviaSens(0);
			EnviaSens(1);
						// FUNCIÓ MATRIU LED TEMP
			if (T <= 1 && C == 0 ) {		// Si la Temperatura és inferior a X 
				Esborra();			// Esborra la pantalla i posa el cursor a l'inici
				Matriu(0);   
				TocaNota(238, 119, 2);		// Valor que correspon aproximadament a do3
				Esborra();
				Apaga();
				K = 0;
			}
			if (T >= 3 && C == 0) {			// Si la Temperatura és superior a X 
				Esborra();			// Esborra la pantalla i posa el cursor a l'inici
				Matriu(1);
				TocaNota(158, 79, 2);		// Valor que correspon aproximadament a sol3
				Esborra();
				Apaga();
				K = 0;
			}
			// FUNCIONS HUM
			if (H < 4 && C == 0) {
				Esborra();
				Matriu(2);
				TocaNota(189, 95, 0);		// Valor que correspon aproximadament a mi3
				Esborra();
				Apaga();
				K = 0;
			}
			if (H >= 6 && C == 0) {
				Esborra();
				Matriu(3);
				TocaNota(189, 95, 0);		// Valor que correspon aproximadament a mi3
				Esborra();
				Apaga();
				K = 0;
			}
			if ( 1 <= T  && T < 3 && 4 <= H  && H < 6 && K == 0) {
				K = 1;
				C = 0;
			}
						// FUNCIONS POLSADORS           
			if (Polsad == 2) {	// Si s'ha premut el polsador 5
				Esborra();	// Esborra la pantalla i posa el cursor a l'inici
				EnviaSens(2);
				EnviaSens(3);
				__delay_ms(2000);		// 2 segons
			}
		} else {
			Cursor(1, 1);		// Posició
			EnviaL('E');
			EnviaL('r');
			EnviaL('r');
			EnviaL('o');
			EnviaL('r');
			EnviaL(' ');
			Error = Error + '0';	// Passa el valor a ASCII
			EnviaL(Error);		// Número
		}
		__delay_ms(500);		// Retard de mig s
		if (Polsad == 1) {
			C = 1;
			K = 0;
		}
	}
	
}
void interrupt temporit(void) {
	INTCONbits.GIE = 0;			// Desactiva les interrupcions momentàniament
	if (INTCONbits.T0IF) {			// Comprovem que hi ha interrupció per Timer 0
		TMR0 = 139;			// Preselecció de Timer0
		INTCONbits.T0IF = 0;		// Desactiva el bit que indica interrupció pel Timer0
		if (Actiu != 0) {		// Si la matriu no està apagada
			Actiu--;		// Passem a activar un altre color
			if (Actiu == 0) {	// Si hem arribat a zero
				Actiu = 3;	// Torna a posar el 3
			}
		}
						// D'entrada els desactivem els tres
		Sortida[0] = 0x00;		// Vermell
		Sortida[2] = 0x00;		// Verd
		Sortida[4] = 0x00;		// Blau
		if (Actiu == 1) {		// Si és vermell
			Sortida[0] = 0x01;	// Vermell activat
		}
		if (Actiu == 2) {		// Si és verd
			Sortida[2] = 0x01;	// Verd activat
		}
		if (Actiu == 3) {		// Si és blau
			Sortida[4] = 0x01;	// Blau activat
		}
		Sortida[1] = 0x0C;		// Shutdown mode
		Sortida[3] = 0x0C;		// Shutdown mode
		Sortida[5] = 0x0C;		// Shutdown mode
		Envia3max(Sortida);		// Ho envia al MAX7221
	}
	INTCONbits.GIE = 1;			// Reactiva les interrupcions a l'acabar
}
char Sensor(void) {
	char Bytes[5];				// Vector per a guardar els cinc bytes que envia el sensor
	char Temps;				// Guarda el valor de TMR1L
	for (int j = 0; j < 5; j++){		// 5 bytes
		Bytes[j] = 0;			// Posem el vector a zero
	}
	TRISA = 0b11011111;			// Tot el port A és d'entrada excepte, de moment, RA5
	PORTA = 0b00000000;			// RA5 a 0
	__delay_ms(2);				// Retard de 2 ms
	PORTA = 0b00100000;			// RA5 a 1
	__delay_us(15);				// Retard de 15 us
						// Un cop activat, esperem la resposta
	TRISA = 0b11111111;			// Tot el port A és d'entrada, inclosa RA5
						// Esperem a rebre el pols d'inici
						// Primer un L d'uns 80 us
						// Per començar, s'ha de desactivar l'entrada
						// i s'ha de reactivar al cap d'entre 70 i 90 us
	while (Sens)				// S'ha desactivat l'entrada?
		;				// No, doncs esperem
	TMR1H = 0;
	TMR1L = 0;				// Sí, doncs comencem a comptar el temps
	while ((!Sens) && (TMR1L < 45))		// Esperem que s'activi l'entrada
		;				// O passin més de 90 us
	Temps = TMR1L;				// Agafa el valor de TMR1L
	TMR1H = 0;
	TMR1L = 0;				// Torna a començar a comptar el temps
	if (Temps > 45) {			// És més gran
		return 1;			// Error 1 - L inicial massa llarg
	}
	if (Temps < 35) {			// Mirem que no sigui menor que 70 us
		return 2;			// Error 2 - L inicial massa curt
	}
						// L inicial ja està
	while (Sens && (TMR1L < 45))		// Esperem a que es desactivi l'entrada
		;				// O passin més de 90 us
	Temps = TMR1L;				// Agafa el valor de TMR1L
	TMR1H = 0;
	TMR1L = 0;				// Torna a començar a comptar el temps
	if (Temps > 45) {			// És més gran
		return 3;			// Error 3 - H inicial massa llarg
	}
	if (Temps < 35) {			// Mirem que no sigui menor que 70 us
		return 4;			// Error 4 - H inicial massa curt
	}
						// H inicial ja està
						// Ara hem de rebre els bits
	TMR1H = 0;
	TMR1L = 0;				// Torna a començar a comptar el temps
	for (int j = 0; j < 5; j++){		// 5 bytes
		for (int k = 0; k < 8; k++){	// 8 bits a cada byte
			Bytes[j] = 2 * Bytes[j];		// Rodem a l'esquerra el bit anterior
								// per deixar lloc al nou
								// Si no n'hi havia cap no canvia res
								// ja que estava a zero
						// Esperem a rebre un bit
						// Primer un L d'uns 80 us
						// Ara l'entrada està a zero
						// S'ha d'activar al cap d'entre 10 i 90 us
			while ((!Sens) && (TMR1L < 45))		// Esperem que s'activi l'entrada
				;		// O passin més de 90 us
			Temps = TMR1L;		// Agafa el valor de TMR1L
			TMR1H = 0;
			TMR1L = 0;		// Torna a començar a comptar el temps
			if (Temps > 45) {	// És més gran
				return 5;	// Error 5 - Valor L del bit massa llarg
			}
			if (Temps < 5) {	// Mirem que no sigui menor que 10 us
				return 6;	// Error 6 - Valor L del bit massa curt
			}
						// Ja tenim el valor L del bit. Ara esperem un H
			while (Sens && (TMR1L < 40))		// Esperem a que es desactivi l'entrada
				;		// O passin més de 80 us
			Temps = TMR1L;		// Agafa el valor de TMR1L
			TMR1H = 0;
			TMR1L = 0;		// Torna a començar a comptar el temps
			if (Temps > 40) {	// És més gran
				return 7;	// Error 7 - Valor H del bit massa llarg
			}
			if (Temps < 6) {	// Mirem que no sigui menor que 12 us
				return 8;	// Error 8 - Valor H del bit massa curt
			}
						// Ja hem comprovat que no sigui massa curt ni massa llarg
						// Si és més petit que 38 us és un pols curt, o sigui un 0
						// Si és curt no cal fer res, el 0 ja hi és
						// Si és més gran que 60 us és un pols llarg, o sigui un 1
			if (Temps > 19) {	// És més gran que 38 us
						// Sí, doncs no és un pols curt
				if (Temps > 30) {		// És més gran que 60 us
						// És un pols llarg
					Bytes[j] = Bytes[j] + 1;			// Entrem un 1
				} else {
					return 9;		// Error 9 - Valor H del bit incorrecte
				}
			}
		}
	}
						// Ja tenim els 5 bytes. Fem la suma de comprovació
						// Cal sumar els quatre primers bytea
						// Però sense portar-ne
	Valor = 0;				// Primer la posem a zero
	for (int j = 0; j < 4; j++){		// 4 bytes
		Valor = Valor + Bytes[j];	// Sumem un dels quatre elements
		if (Valor > 255) {		// Mirem si és més gran del que cap a un byte
						// Si és més gran, només pot haver activat un bit del segon byte
						// el que correspon a 256
			Valor = Valor -256;	// Restem les que en portàvem
		}
	}
	if (Valor != Bytes[4]) {		// No coincideixen
		return 10;			// Error 10 - Falla la suma de comprovació
	}
	Lectura[0] = Bytes[4];			// Suma de comprovació
	Lectura[1] = 256 * Bytes[2] + Bytes[3];			// Temperatura
	Lectura[2] = 256 * Bytes[0] + Bytes[1];			// Humitat
	return 0;				// Recepció correcta
}
void Envia3max(char Valor[6]) {			// Envia un joc de valors als tres MAX7221
	INTCONbits.GIE = 0;			// Desactiva les interrupcions momentàniament
	char Port = 0;				// Variable on guardem l'estat del port B
	char Temp;				// Variable temporal
	for (int j = 5; j >= 0; j--){		// Hem d'enviar 6 bytes
		for (int k = 1; k < 9; k++){			// De 8 bits
			Temp = Valor[j] & 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 & 0b11101111;	// Desactiva Data (bit 4)
			} else {				// Si val 128
				Port = Port | 0b00010000;	// Activa Data (bit 4)
			}
			Valor[j] = Valor[j] << 1;		// Rodem els bits per situar el següent
			PORTB = Port;				// Ho posa al port B
			Port = Port | 0b00100000;		// Activa Clock (bit 5) i força lectura
			PORTB = Port;				// Ho posa al port B
			Port = Port & 0b11011111;		// Desactiva Clock (bit 5)
			PORTB = Port;				// Ho posa al port B
		}
	}
	Port = Port | 0b01000000;		// Activa Latch (bit 6) per copiar a les sortides
	PORTB = Port;				// Ho posa al port B
	INTCONbits.GIE = 1;			// Reactiva les interrupcions a l'acabar
}
void Ini3max(void) {				// Inicialitza els tres MAX7221
	char Bytes[6];				// Els sis bytes que cal enviar
	Bytes[0] = 0x00;			// Desactivat
	Bytes[1] = 0x0C;			// Shutdown mode
	Bytes[2] = 0x00;
	Bytes[3] = 0x0C;
	Bytes[4] = 0x00;
	Bytes[5] = 0x0C;
	Envia3max(Bytes);			// Els envia
	Bytes[0] = 0x00;			// No decode
	Bytes[1] = 0x09;			// Decode mode
	Bytes[2] = 0x00;
	Bytes[3] = 0x09;
	Bytes[4] = 0x00;
	Bytes[5] = 0x09;
	Envia3max(Bytes);			// Els envia
	Bytes[0] = 0x07;			// Vuit fileres
	Bytes[1] = 0x0B;			// Scan limit
	Bytes[2] = 0x07;
	Bytes[3] = 0x0B;
	Bytes[4] = 0x07;
	Bytes[5] = 0x0B;
	Envia3max(Bytes);			// Els envia
}
void Apaga(void) {				// Apaga tots els LED
	char Bytes[6];				// Els sis bytes que cal enviar
	for (int j = 0; j <= 8; j++){		// Hem d'enviar 8 fileres
		Bytes[1] = j;			// Filera
		Bytes[3] = j;
		Bytes[5] = j;
		Bytes[0] = 0x00;		// Vermells
		Bytes[2] = 0x00;		// Verds
		Bytes[4] = 0x00;		// Blaus
		Envia3max(Bytes);		// Els envia
	}
}
void EnviaL(char Caracter) {
	INTCONbits.GIE = 0;			// Desactiva les interrupcions momentàniament
	RCSTAbits.SPEN = 1;			// Activa comunicació sèrie
	TXSTAbits.TXEN = 1;			// Activa comunicació
	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
	RCSTAbits.SPEN = 0;			// Desactiva comunicació sèrie
	TXSTAbits.TXEN = 0;			// Desactiva comunicació
	INTCONbits.GIE = 1;			// Activa les interrupcions
}
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
}
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 EnviaSens (int X) {
						// X=0 correspon a HR; X=1 correspon a T en °C;
						// X=2 correspon a T en °F i X=3 correspon a T en K
	char Digits[5];
	if (X > 0) {
		Valor = Lectura[1];		// Temperatura
		if (Valor >= 32768) {		// Si el bit més significatiu està activat és negatiu
			Negatiu = 1;		// És negatiu
			Valor = Valor -32768;	// Agafem el valor absolut
		} else {
			Negatiu = 0;		// És positiu
		}		
	} else {
		Valor = Lectura[2];		// Humitat
	}
	Digits[0] = Valor % 10;			// Unitats
	Valor = Valor / 10;
	Digits[1] = Valor % 10;			// Desenes
	Valor = Valor / 10;
	Digits[2] = Valor % 10;			// Centenes
	Valor = Valor / 10;
	Digits[3] = Valor % 10;			// Milers
	Digits[4] = Valor / 10;			// Desenes de milers
	if (X==1) {
		T = Digits[2];
		for (int j = 0; j < 5; j++){	// 5 dígits
			Digits[j] = Digits[j] + '0';		// Li sumem el codi ASCII de 0
		}				// Això és la temperatura multiplicada per 10
		if (Digits[4] == '0') {		// Mirem si el primer dígit és 0
			Digits[4] = ' ';	// Si ho és, hi posem un espai
			if (Digits[3] == '0') {			// I mirem si ho és el segon
				Digits[3] = ' ';		// Si ho és, hi posem un espai
				if (Digits[2] == '0') {		// I mirem si ho és el tercer
					Digits[2] = ' ';	// Si ho és, hi posem un espai
				}		// Els dos darrers zeros els mostrarem sempre
			}
		}
		if (Negatiu) {
			Digits[4] = '-';	// Si és negatiu, posem el -
		}
		Cursor(1, 1);			// Posició
		EnviaL('T');			// envia lletra T
		EnviaL(' ');			// envia espai
		EnviaL('=');			// envia =
		EnviaL(' ');			// envia espai
		for (int j = 2; j > 0; j--){	// 2 dígits (el 5è és el decimal)
			EnviaL(Digits[j]);	// Número
		}
		EnviaL(',');			// Coma
		EnviaL(Digits[0]);		// Número
		EnviaL(' ');			// Espai
		EnviaL(0b11011111);		// Graus
		EnviaL('C');			// Lletra
	} else if (X==0) {
		H = Digits[2];
		for (int j = 0; j < 5; j++){	// 5 dígits
			Digits[j] = Digits[j] + '0';		// Li sumem el codi ASCII de 0
		}				// Això és la humitat multiplicada per 10
		if (Digits[4] == '0') {		// Mirem si el primer dígit és 0
			Digits[4] = ' ';	// Si ho és, hi posem un espai
			if (Digits[3] == '0') {			// I mirem si ho és el segon
				Digits[3] = ' ';		// Si ho és, hi posem un espai
				if (Digits[2] == '0') {		// I mirem si ho és el tercer
					Digits[2] = ' ';	// Si ho és, hi posem un espai
				}		// Els dos darrers zeros els mostrarem sempre
			}
		}
		Cursor(2, 1);			// Posició
		EnviaL('H');
		EnviaL('R');
		EnviaL(' ');			// Espai
		EnviaL('=');
		EnviaL(' ');			// Espai
		for (int j = 2; j > 0; j--){	// 2 dígits (el 5è és el decimal)
			EnviaL(Digits[j]);	// Número
		}
		EnviaL(',');			// Coma
		EnviaL(Digits[0]);		// Número
		EnviaL(' ');			// Espai
		EnviaL('%');			// Tant per cent
	}
	Valorr = Lectura[1];
	Valorr = Valorr * 18 + 3200;
	Valorr = Valorr / 10;
	Digits[0] = Valorr % 10;		// Unitats
	Valorr = Valorr / 10;
	Digits[1] = Valorr % 10;		// Desenes
	Valorr = Valorr / 10;
	Digits[2] = Valorr % 10;		// Centenes
	Valorr = Valorr / 10;
	Digits[3] = Valorr % 10;		// Milers
	Digits[4] = Valorr / 10;		// Desenes de milers
	if (X==2) {
		for (int j = 0; j < 5; j++){	// 5 dígits
			Digits[j] = Digits[j] + '0';		// Li sumem el codi ASCII de 0
		}				// Això és la temperatura multiplicada per 10
		if (Digits[4] == '0') {		// Mirem si el primer dígit és 0
			Digits[4] = ' ';	// Si ho és, hi posem un espai
			if (Digits[3] == '0') {	// I mirem si ho és el segon
				Digits[3] = ' ';		// Si ho és, hi posem un espai
				if (Digits[2] == '0') {		// I mirem si ho és el tercer
					Digits[2] = ' ';	// Si ho és, hi posem un espai
				}		// Els dos darrers zeros els mostrarem sempre
			}
		}
		if (Negatiu) {
			Digits[4] = '-';	// Si és negatiu, posem el -
		}
		Cursor(2, 3);			// Posició
		EnviaL('T');			// envia lletra T
		EnviaL(' ');			// Espai
		EnviaL('=');			// envia =
		EnviaL(' ');			// Espai
		for (int j = 3; j > 0; j--){	// 2 dígits (el 5è és el decimal))
			EnviaL(Digits[j]);	// Número
		}
		EnviaL(',');			// Coma
		EnviaL(Digits[0]);		// Número
		EnviaL(' ');			// Espai
		EnviaL(0b11011111);		// Graus
		EnviaL('F');			// Lletra
	}
	Valorrr = Lectura[1];			// Temperatura
	Valorrr = Valorrr + 2732;
	Digits[0] = Valorrr % 10;		// Unitats
	Valorrr = Valorrr / 10;
	Digits[1] = Valorrr % 10;		// Desenes
	Valorrr = Valorrr / 10;
	Digits[2] = Valorrr % 10;		// Centenes
	Valorrr = Valorrr / 10;
	Digits[3] = Valorrr % 10;		// Milers
	Digits[4] = Valorrr / 10;		// Desenes de milers
	if (X==3) {
		for (int j = 0; j < 5; j++){	// 5 dígits
			Digits[j] = Digits[j] + '0';		// Li sumem el codi ASCII de 0
		}				// Això és la temperatura multiplicada per 10
		if (Digits[4] == '0') {		// Mirem si el primer dígit és 0
			Digits[4] = ' ';	// Si ho és, hi posem un espai
			if (Digits[3] == '0') {	// I mirem si ho és el segon
				Digits[3] = ' ';		// Si ho és, hi posem un espai
				if (Digits[2] == '0') {		// I mirem si ho és el tercer
					Digits[2] = ' ';	// Si ho és, hi posem un espai
				}		// Els dos darrers zeros els mostrarem sempre
			}
		}
		if (Negatiu) {
			Digits[4] = '-';	// Si és negatiu, posem el -
		}
		Cursor(1, 3);			// Posició
		EnviaL('T');			// envia lletra T
		EnviaL(' ');			// Espai
		EnviaL('=');			// envia =
		EnviaL(' ');			// Espai
		for (int j = 3; j > 0; j--){	// 2 dígits (el 5è és el decimal)
			EnviaL(Digits[j]);	// Número
		}
		EnviaL(',');			// Coma
		EnviaL(Digits[0]);		// Número
		EnviaL(' ');			// Espai
		EnviaL('K');			// Lletra
	}
}
void Matriu (int M) {
						// M=0 Fred; M=1 Calor ; M= 2 Hum baixa; M=3 Hum alta
	if (M==0) {
		Cursor(1,6);
		const char alerta[]={'A','l','e','r','t','a'};
		for (int j = 0;j < 6; j++){	// 2 dígits (el 5è és el decimal)
			EnviaL(alerta[j]);
		}
		Cursor(2,7);
		const char fred[]={'F','R','E','D'};
		for (int j = 0;j < 4; j++){	// 2 dígits (el 5è és el decimal)
			EnviaL(fred[j]);
		}
						// Matriu 1
		char Colors[8][3]={
			{0b00000000,0b00000000, 0b10100101},
			{0b00000000,0b00000000, 0b01100110},
			{0b00000000,0b00000000, 0b11100111},
			{0b00000000,0b00000000, 0b00011000},
			{0b00000000,0b00000000, 0b00011000},
			{0b00000000,0b00000000, 0b11100111},
			{0b00000000,0b00000000, 0b01100110},
			{0b00000000,0b00000000, 0b10100101}};
		for (int j = 0; j<=7; j++){
			Sortida[0]=Colors[j][0];
			Sortida[1]=Llista[j];
			Sortida[2]=Colors[j][1];
			Sortida[3]=Llista[j];
			Sortida[4]=Colors[j][2];
			Sortida[5]=Llista[j];
			Envia3max(Sortida);
		}
	} else if (M==1) {
		Cursor(1,6);
		const char alerta[]={'A','l','e','r','t','a'};
		for (int j = 0;j < 6; j++){	// 2 dígits (el 5è és el decimal)
			EnviaL(alerta[j]);
		}
		Cursor(2,6);
		const char calor[]={'C','A','L','O','R'};
		for (int j = 0;j <= 4; j++){	// 2 dígits (el 5è és el decimal)
			EnviaL(calor[j]);
		}
						// Matriu 2
		char Colors[8][3]={
			{0b00011000,0b00000000, 0b00000000},
			{0b00011000,0b00000000, 0b00000000},
			{0b00100100,0b00011000, 0b00011000},
			{0b00100100,0b00011000, 0b00011000},
			{0b01000010,0b00011000, 0b00011000},
			{0b01000010,0b00000000, 0b00000000},
			{0b10000001,0b00011000, 0b00011000},
			{0b11111111,0b00000000, 0b00000000}};
		for (int j = 0; j<=7; j++){
			Sortida[0]=Colors[j][0];
			Sortida[1]=Llista[j];
			Sortida[2]=Colors[j][1];
			Sortida[3]=Llista[j];
			Sortida[4]=Colors[j][2];
			Sortida[5]=Llista[j];
			Envia3max(Sortida);
		}
	} else if (M==2) {
		Cursor(1,6);
		const char alerta[]={'A','l','e','r','t','a'};
		for (int j = 0;j < 6; j++){	// 2 dígits (el 5è és el decimal)
			EnviaL(alerta[j]);
		}
		Cursor(2,5);
		const char humbaix[]={'H','R',' ','b','a','i','x','a'};
		for (int j = 0;j < 8; j++){	// 2 dígits (el 5è és el decimal)
			EnviaL(humbaix[j]);
		}
	} else if (M==3) {
		Cursor(1,6);
		const char alerta[]={'A','l','e','r','t','a'};
		for (int j = 0;j < 6; j++){	// 2 dígits (el 5è és el decimal)
			EnviaL(alerta[j]);
		}
		Cursor(2,5);
		const char humalt[]={'H','R',' ','a','l','t','a'};
		for (int j = 0;j < 8; j++){	// 2 dígits (el 5è és el decimal)
			EnviaL(humalt[j]);
		}
	}
}
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
}

 

 

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