Programació en C del PIC 16F690

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

Bàscula electrònica

Programa del grup 3

En aquest cas van considerar que la bàscula tenia un límit màxim de 8 kg. L'usuari pot indicar el número de persones i la bàscula li indicarà el pes mesurat i també el pes per persona.

El polsador BTN1 serveix per indicar que volem la lectura en grams, el BTN2 si desitgem kg, el BTN3 en lb i el BTN4 en oz. El polsador BTN0 guardar el pes actual com a tara.

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 Polsador   RA3		// Li assigna un nom a l'adreça del polsador
unsigned short long Lectura;			// Valor llegit del sensor
unsigned short long Tara;
unsigned short long Error;
unsigned short long Total;
char Port;					// Bits del port C
						// RC0 a RC3 són els LED
						// RC4 és DAT (DOUT del sensor)
						// RC6 és CLK (PD_SCK del sensor)
						// RC5 és on hi ha el brunzidor
						// Definició de les funcions que farem servir 
char Polsad;					// Polsador que s'ha premut
char Porb;
int r;
int inici = 1;
unsigned short long LlegirHX(void);		// Lectura del sensor
char Polsadors(void);				// Funció de lectura dels polsadors
void Escriu(unsigned short long Valor);		// Escriu un valor de 24 bits a la pantalla
void EnviaL(char Caracter);			// Envia un caràcter ASCII
void Esborra(void);				// Esborra la pantalla i posa el cursor a l'inici
void Cursor(char Filera, char Columna);
void main (void) {
	ANSEL = 0b00000101;			// Configura AN0 i AN2 com entrada analògica
	ANSELH = 0;				// Desactiva les altres entrades analògiques
	TRISC = 0b00010000;			// Posa RC4 com a entrada, la resta és de sortida
	TRISB = 0b00000000;			// Tot el port B és de sortida
	TRISA = 0b11111111;			// 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
	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;				// Desactiva tots els bits del port B
	PORTC = 0;				// Desactiva tots els bits del port C
	Port = 0;				// Desactiva tots els bits de Port
	while (1) {				// Inici del bucle de programa
		Lectura = LlegirHX();		// Llegeix el valor del sensor HX711
		Esborra();			// Esborra la pantalla
		Escriu(Lectura);		// Escriu la lectura a la pantalla
		__delay_ms(1000);		// Retard d'1 s
	}
}
unsigned short long LlegirHX(void) {
	unsigned short long Buffer;		// Valor rebut
	Port = Port & 0b10111111;		// Desactiva PD_SCK
	PORTC = Port;
	for (int j = 1; j <= 24; j++){		// 24 bits
		Port = Port | 0b01000000;	// Activa PD_SCK
		PORTC = Port;
		Buffer = Buffer << 1;		// Rodem els bits per situar el següent
						// a la dreta hi quedarà un zero
		if (RC4 == 1) {	// Si DOUT està activat, posem un 1
			Buffer = Buffer | 0b00000001;
		}
		Port = Port & 0b10111111;	// Desactiva PD_SCK
		PORTC = Port;
		__delay_us(3);	   	 	// Espera 3 us per fer els polsos de la mateixa amplada
	}
	Port = Port | 0b01000000;		// Activa PD_SCK per dir-li el guany
	PORTC = Port;
	__delay_us(6);	   	 		// Espera 6 us per fer els polsos de la mateixa amplada
	Port = Port & 0b10111111;		// Desactiva PD_SCK
	PORTC = Port;
	return Buffer;				// Retorna el valor
}
void Escriu(unsigned short long Valor) {
	char Digits[5];	// Aquí guardarem els 5 dígits
	Port = 0;
	Porb = 0;
	unsigned short long Result;		// Variable de treball
	Valor = Valor + 1000000;
	Valor = Valor * 0.046106;   
	// polsador:
	if (inici <= 4){
		Error = Valor;
		inici += 1;
	}
	Valor = Valor - Error;
	Total = Valor;
	if (Polsador == 0){			// Polsador premut
		Tara = Valor;			// variable Tara
		__delay_ms(100);
	}
	while(Polsador == 0){
		;
	}
	Valor = Valor - Tara;
	char i = 0;
	if (Valor > 600000) {			// Si el valor és negatiu
		Valor = 0;		
	}
	if ((Total > 80000)&&(Total < 600000)){	// Si ens passem de 8 kg
		i = 1;
		Valor = 80000;
		Port = Port | 0b00001000;
		PORTC=Port;
	}
	Polsad = Polsadors();			// Llegim els polsadors
	if ((Polsad == 4)||(r==4)) {		// Si s'ha premut el polsador 4
		r = 4;
		Valor = Valor / 2.834952;	// Passem a oz americanes
	}
	if ((Polsad == 3)||(r==3)) {		// Si s'ha premut el polsador 3
		r = 3;
		Valor = Valor / 4.535923;	// Passem a lb americanes
	}
	if ((Polsad == 2)||(r==2)) {		// Si s'ha premut el polsador 2
		r = 2;
		;				// Passem a kg
	}
	if ((Polsad == 1)||(r==1)) {		// Si s'ha premut el polsador 1
		r = 1;	// Deixem en grams
	}
	if (Polsad == 0) {			// Si no s'ha premut cap polsador (o dos a la vegada)
		;
	}
	_delay(200);	    			// Retard per permetre la visualització
	Valor = Valor / 10;
	Result = Valor % 10;
	Digits[0] = (char) Result;		// Unitats
	Valor = Valor / 10;
	Result = Valor % 10;
	Digits[1] = (char) Result;		// Desenes
	Valor = Valor / 10;
	Result = Valor % 10;
	Digits[2] = (char) Result;		// Centenes
	Valor = Valor / 10;
	Result = Valor % 10;
	Digits[3] = (char) Result;		// Milers
	Valor = Valor / 10;
	Result = Valor % 10;
	Digits[4] = (char) Result;		// Desenes de miler
	if ((r!=2)&&(r!=3)&&(r!=4)){
		for (int j = 4; j >= 0; j--){	// 5 dígits
			if ((j==4)&&(Digits[j]==0)){
				Digits[j]=' ';
			} else if ((j==3)&&(Digits[j]==0)&&(Digits[4]==' ')){
				Digits[j]=' ';
			} else if ((j==2)&&(Digits[j]==0)&&(Digits[4]==' ')&&(Digits[3]==' ')){
				Digits[j]=' ';
				EnviaL(' ');
			} else if ((j==1)&&(Digits[j]==0)&&(Digits[4]==' ')&&(Digits[3]==' ')&&(Digits[2]==' ')){
				Digits[j]=' ';
			} else {
				Digits[j] = Digits[j] + '0';	// Li sumem el codi ASCII de 0
				if ((j == 2) && ((Digits[4]!=' ') || (Digits[3]!=' '))) {
					EnviaL(' ');		// Posem el punt
				} else if ((j==2) && ((Digits[4]==' ') && (Digits[3]==' '))){
					EnviaL(' ');
				}
			}
			EnviaL(Digits[j]);	// Número  
		}
		Cursor(1, 8);
		EnviaL('g');
	}
	if (r==2){
		for (int p = 4; p >= 0; p--){	// 8 dígits
			if ((p==4)&&(Digits[p]==0)){
				Digits[p]=' ';
			} else {
				Digits[p] = Digits[p] + '0';	// Li sumem el codi ASCII de 0
			}
			if (p == 2) {		// Posem espais per separar
				EnviaL(',');	// Espai
			}
			EnviaL(Digits[p]);	// Número
		}
		Cursor(1, 8);
		EnviaL('k');
		Cursor(1, 9);
		EnviaL('g');
	}
	if (r==3){
		for (int j = 4; j >= 0; j--){	// 5 dígits
			if ((j==4)&&(Digits[j]==0)){
				Digits[j]=' ';
				EnviaL(Digits[j]);
			} else if ((j==3)&&(Digits[j]==0)&&(Digits[4]==' ')){
				Digits[j]=' ';
				EnviaL(Digits[j]);
			} else {
				Digits[j] = Digits[j] + '0';	// Li sumem el codi ASCII de 0
				if (j == 2){
					EnviaL(Digits[j]);
					EnviaL(',');		// Coma
				} else {
					EnviaL(Digits[j]);
				}
			}      
		}
		Cursor(1, 8);
		EnviaL('l');
		Cursor(1, 9);
		EnviaL('b');
	}
	if (r==4){
		for (int j = 4; j >= 0; j--){	// 5 dígits
			if ((j==4)&&(Digits[j]==0)){
				Digits[j]=' ';
				EnviaL(Digits[j]);
			} else if ((j==3)&&(Digits[j]==0)&&(Digits[4]==' ')){
				Digits[j]=' ';
				EnviaL(Digits[j]);
			} else if ((j==2)&&(Digits[j]==0)&&(Digits[4]==' ')&&(Digits[3]==' ')){
				Digits[j]=' ';
				EnviaL(Digits[j]);
			} else {
				Digits[j] = Digits[j] + '0';	// Li sumem el codi ASCII de 0
				if (j == 1){	// Posem el punt
					EnviaL(Digits[j]);
					EnviaL(',');		// Coma
				} else {
					EnviaL(Digits[j]);
				}
			}      
		}
		Cursor(1, 8);
		EnviaL('o');
		Cursor(1, 9);
		EnviaL('z');
	}
	if (i==1) {
		Cursor(2, 1);
		EnviaL('M');
		Cursor(2, 2);
		EnviaL('A');
		Cursor(2, 3);
		EnviaL('X');
		Cursor(1,1);
		EnviaL('>');
	}
}
void EnviaL(char Caracter) {
	TXREG = Caracter;			// Agafa el caràcter i l'envia
	_delay(5);				// 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
}
char Polsadors(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;
}

 

 

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