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 BTN0 serveix per activar la bàscula i el BTN1 per desactivar-la. Els polsador BTN2 serveix per indicar que volem la lectura en lb i el BTN3 si desitgem kg, El polsador BTN4 guarda el pes actual com a tara i el BTN5 mostra a la pantalla les funcions dels botons.
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 Polsador RA3 #define _XTAL_FREQ 4000000 // La freqüència del rellotge és 4 MHz
unsigned short long pes; // Valor llegit del sensor unsigned short long tara; unsigned short long pesreal; unsigned short long unitat; char Polsad; // Polsador que s'ha premut 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 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 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 TocaNota(char ValPR2, char ValCCPR1L, char ValDC1B);
void main (void) {
ANSEL = 0b00000101; // Configura AN0 i AN2 com entrada analògica
ANSELH = 0; // Desactiva les altres entrades analògiques
TRISC = 0b00110000; // Posa RC4 com a entrada, la resta és de sortida
TRISB = 0; // Tot el port B és de sortida
TRISA = 0xFF; // Posa RA3 com a entrada 0b00001000
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
ADCON1 = 0b00010000; // Posa el conversor a 1/8 de la freqüència
ADCON0 = 0b00001001; // Activa el conversor A/D connectat a AN2
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
_delay(500000);
while (Polsador == 1) { // Si el polsador no està premut
;
}
tara = LlegirHX()*0.00472;
Esborra(); // Esborra la pantalla i posa el cursor a l'inici
Cursor(1, 7);
EnviaL('O'); // Lletra
EnviaL('N'); // Lletra
TocaNota(189, 95, 0); // Valor que correspon aproximadament a mi3
TocaNota(189, 95, 0); // Valor que correspon aproximadament a mi3
_delay(20000);
TocaNota(189, 95, 0); // Valor que correspon aproximadament a mi3
_delay(20000);
TocaNota(238, 119, 2);
TocaNota(189, 95, 0); // Valor que correspon aproximadament a mi3
_delay(20000);
TocaNota(158, 79, 2);
_delay(200000);
TocaNota(249, 122, 2);
_delay(200000);
Esborra();
unitat=3;
EnviaL('P');
EnviaL('R');
EnviaL('E');
EnviaL('S');
EnviaL('S');
EnviaL(' ');
EnviaL('5');
EnviaL(' ');
EnviaL('F');
EnviaL('O');
EnviaL('R');
EnviaL(' ');
EnviaL('I');
EnviaL('N');
EnviaL('F');
EnviaL('O');
_delay(2000000);
Esborra();
while (1){
pes = LlegirHX()*0.00472; // Llegeix el valor del sensor HX711
if (Polsad == 2){
unitat=2;
}
if (Polsad ==3){
unitat =3;
}
if (unitat == 3){
pesreal = (pes-tara);
Esborra(); // Esborra la pantalla
Escriu(pesreal); // Escriu la lectura a la pantalla
Cursor(1, 7);
EnviaL('k'); // Lletra
EnviaL('g');
if ((pesreal) == 0) {
Esborra();
Cursor(1,5);
EnviaL('0');
Cursor(1,7);
EnviaL('k');
EnviaL('g');
}
}
if (unitat == 2){
Esborra();
pesreal = (pes-tara)*2.20462262;
Escriu(pesreal);
Cursor(1, 7);
EnviaL('l'); // Lletra
EnviaL('b');
if ((pesreal) == 0) {
Esborra();
Cursor(1,5);
EnviaL('0');
Cursor(1,7);
EnviaL('l');
EnviaL('b');
}
}
if ((pes-tara)>3000) {
Esborra();
Cursor(1,6);
EnviaL('E');
EnviaL('r');
EnviaL('r');
EnviaL('o');
EnviaL('r');
TocaNota(189, 95, 0); // Valor que correspon aproximadament a mi3
RC0 = 1; // Activa el bit 0 del port C i, per tant, encén el LED
}
Polsad = Polsadors(); // Llegim els polsadors
if (Polsad == 4) { // Si s'ha premut el polsador 5
tara = pes;
Esborra();
}
if (Polsad == 1){
Esborra();
Cursor(1, 7);
EnviaL('O'); // Lletra
EnviaL('F');
EnviaL('F');
TocaNota(189, 95, 0);
TocaNota(212, 106, 2);
TocaNota(238, 119, 2);
Esborra();
break;
}
if (Polsad == 5) {
Esborra();
EnviaL('1');
EnviaL(':');
EnviaL('O');
EnviaL('F');
EnviaL('F');
Cursor(1, 9);
EnviaL('2');
EnviaL(':');
EnviaL('l');
EnviaL('b');
Cursor(2, 1);
EnviaL('3');
EnviaL(':');
EnviaL('k');
EnviaL('g');
Cursor(2, 9);
EnviaL('4');
EnviaL(':');
EnviaL('T');
EnviaL('a');
EnviaL('r');
EnviaL('a');
_delay(2000000);
}
__delay_ms(1000); // Retard d'1 s
}
}
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
}
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+200000; // Retorna el valor
}
void Escriu(unsigned short long Valor) {
char Digits[8]; // Aquí guardarem els 8 dígits
unsigned short long Result; // Variable de treball
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
//Valor = Valor / 10;
//Result = Valor % 10;
//Digits[5] = (char) Result; // Centenes de miler
//Valor = Valor / 10;
//Result = Valor % 10;
//Digits[6] = (char) Result; // Unitats de milió
//Result = Valor / 10;
//Digits[7] = (char) Result; // Centenes de milió
for (int j = 3; j >= 0; j--){ // 8 dígits
if (Digits[j]!=' '){
Digits[j] = Digits[j] + '0'; // Li sumem el codi ASCII de 0
}
if ( j == 2) { // Posem espais per separar
EnviaL(','); // Espai
}
EnviaL(Digits[j]); // Número
}
}
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;
}
void TocaNota(char ValPR2, char ValCCPR1L, char ValDC1B) {
TRISC = 0b00110000; // 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 = 0b00010000; // Posem RC5 (sortida del PWM) com a sortida
__delay_ms(120); // Retard de 0,2 s
TRISC = 0b00110000; // Posem RC5 (sortida del PWM) com a entrada
// O sigui, silenci
__delay_ms(120); // Retard de 0,2 s
}

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