Programació en C del PIC 16F690

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

Mesurador de corrent elèctric

Programa del grup 2

En aquest cas el dispositiu mesura el corrent i mostra a la pantalla l'energia que s'ha consumit des de la posada en marxa de l'aparell. Aquest dispositiu està pensat per a un ús durant un espai de temps reduït, no per a una mesura contínua.

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 <xc.h> // Carrega el fitxer de funcions
#include <math.h>
#define _XTAL_FREQ 4000000 // La freqüència del rellotge és 4 MHz
#define numEsp 2
unsigned int refer, mesura;
unsigned int suma = 0;
float mitjana, RMS;
unsigned char segundos = 0;
char Digits[5]; // Variable amb el número dígit a dígit
                // Digits[0] són les unitats
// Definició de les funcions que farem servir
void Esborra(void); // Esborra la pantalla i posa el cursor a l'inici
void EnviaL(char Caracter); // Envia un caràcter
void main(void) {
  TRISC = 0b11110000; // Posa els bits 0 a 3 del port C com a sortida
                      // i els altres quatre com a entrada
  TRISA = 0xFF; // Tot el port A és d'entrada
  __delay_ms(2000); // Esperem que arrenqui la pantalla
  BRGH = 1; // Configuració de velocitat
  BRG16 = 0; // Paràmetre de velocitat de 8 bits
  SPBRG = 25; // Velocitat de 9600 baud
  SYNC = 0; // Comunicació asíncrona
  TX9 = 0; // Comunicació de 8 bits
  SPEN = 1; // Activa comunicació sèrie
  TXEN = 1; // Activa comunicació
  ANSEL = 0b00000000; // Desactiva totes les entrades analògiques
  ANSELH = 0b00000011; // I activa AN8 i AN9
  ADCON1 = 0b00010000; // Posa el conversor a 1/8 de la freqüència
  INTCON = 0b11000000; // Habilitem la interrupció per PIE
                       // i deshabilitem les altres
  PIE1 = 0b00000001; // Activa la interrupció per Timer 1
  TMR1IF = 0; // Aquest bit es posarà a 1 quan el temporitzador acabi
              // cal desactivar-lo des del programa
  TMR1H = 0x3C; // Part alta del compte de Timer 1
  TMR1L = 0xB0; // Part baixa del compte de Timer 1
  T1CON = 0b00110001; // Timer1 con prescaler de 8
  GIE = 1; // Habilitem les interrupcions a nivell general
  TMR1ON = 1; // Posem en marxa el Timer 1
  while (1) {
    if (segundos >= 20) { // Cada 20 segundos
      Esborra(); // Esborra la pantalla i posa el cursor a l'inici
      mitjana = (float)suma / 20; // Calculem la mitjana sobre 20 segons
      RMS = (30 / numEsp) * 5 * 100 * 1.1107 * mitjana / 1023.0; // Calculem el valor eficaç
      int Valor = (int)round(RMS) *230*0.001944; // Arrodonim la Intensitat i calculem l'energia en 20s
      for (signed char j = 0; j < 5; j++) { // Descomposició en dígits
        Digits[j] = Valor % 10;
        Valor /= 10;
      }
      for (signed char j = 0; j < 5; j++) { // Convertim a ASCII
        Digits[j] += '0'; // Li sumem el codi ASCII de 0
      }
      if (Digits[4] == '0') { // Eliminem zeros a l'esquerra
        Digits[4] = ' ';
        if (Digits[3] == '0') {
          Digits[3] = ' ';
        }
      }
      for (signed char j = 4; j >= 0; j--) { // Enviem a la pantalla
        if (j == 1) {
          EnviaL(','); // Afegim la coma decimal
        }
        EnviaL(Digits[j]);
      }
      EnviaL(' ');
      EnviaL('W');
      EnviaL('h');
      segundos = 0; // Reiniciem el compte de segons
    }
  }
}
void __interrupt() isr(void) {
  if (TMR1IF) {
    TMR1IF = 0;
    TMR1H = 0x3C;
    TMR1L = 0xB0;
    segundos++;
    if (ADCON0 == 0b10100001) {
      GO_DONE = 1;
      while (GO_DONE);
      refer = ((unsigned int)ADRESH << 8) | ADRESL;
      ADCON0 = 0b10100101;
    } else {
      GO_DONE = 1;
      while (GO_DONE);
      mesura = ((unsigned int)ADRESH << 8) | ADRESL;
      if (mesura < refer) {
        suma += refer - mesura;
      } else {
        suma += mesura - refer;
      }
      ADCON0 = 0b10100001;
    }
  }
}
void EnviaL(char Caracter) {
  TXREG = Caracter; // Envia el caràcter
  __delay_ms(1); // Espera breument
  while (!TXIF)
    ; // Espera a que s'envii completament
}
void Esborra(void) {
  EnviaL(254); // Caràcter de control
  EnviaL(1); // Esborra la pantalla i posa el cursor a l'inici
}

 

 

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