Programació en C del PIC 16F690

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

Sonòmetre digital

Programa del grup 4

En aquest cas, el programa mostra a la pantalla la mitjana de 32 lectures del valor eficaç. També hi ha una escala gràfica, de 0 a 80, que mostra el nivell de so aprofitant que la pantalla té setze caràcters formats per cinc punts d'ample. Addicionalment, a la matriu de LED es mostra el nivell de so en una escala de vuit nivells.

Matriu de LED

Pantalla

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
#include <math.h>  // Per calcular arrels quadrades
#define _XTAL_FREQ  4000000  	// La freq??ncia del rellotge ?s 4 MHz
#define btn0 RA3
unsigned int Read;  // Valor que llegirà el sensor
unsigned int sumQuad;  // Suma de quadrats dels valors per l'RMS
unsigned int RMS;  // Valor de l'RMS
unsigned long X;  // Mitjana d'RMS
char Port;  // Gestió del port a la funció Envia_max
char Compta;  // Comptador de bits a la funció Envia_max
char Sortida[6];  // Valors a enviar al MAX7221 (48 bits)
char Sorti[6];  // Valors a enviar al MAX7221 des de la interrupció
static char Actiu;  // Variable que diu quin color està actiu
unsigned int Lvl;  // Valors dels nivells gràfics de la LCD i la matriu LED
char Adder;  // Bit que rotarem per encendre els LED que ens interessen
unsigned int min;  // Mínim de l'escalat
unsigned int max;  // Màxim de l'escalat
unsigned long iter;  // Iteracions per a calcular la mitjana
// Definici? de les funcions que farem servir
void write_val(unsigned int Valor);  // Escriu un valor a la pantalla
void write_slong(unsigned long Valor);  // Escriu un valor a la pantalla
void write_bar(unsigned int Lvl);  // Dibuixa una barra de certa longitud
                                   // de caràcters a la pantalla
void send_char(char Caracter);  // Envia un car?cter
void clear_lcd(void);  // Esborra la pantalla i posa el cursor a l'inici
void cursor(char Filera, char Columna); // Posiciona el cursor
void Envia3max(char Valor[]);  // Envia un joc de valors als tres MAX7221
                               // desactivant interrupcions
void Envia_max(void);  // Envia un joc de valors als tres MAX7221
void Ini3max(void);  // Inicialitza els tres MAX7221
void clear_led(void);  // Apaga tots els LED
void disp_scale(int increment);  // Mostra min i max a la pantalla
void disp_iter(int increment);  // Mostra iter i mult a la pantalla
void settings_scale(void);  // Ajustaments de min i max
void settings_iter(void);  // Ajustaments d'iter
void def_char(char num, char val);  // Defineix els caràcters per a les barres parcials
void main (void) {
  OPTION_REG = 0b10000101;  // Configuració de Timer0
  // Com a temporitzador basat en rellotge
  // 101 - Factor d'escala de 64
  // I resistències de pull-up desactivades (valor per defecte)
  TRISA = 0xFF;  // Tot el port A ?s d'entrada
  TRISB = 0;  // Tot el port B ?s de sortida
  TRISC = 0b01000000;  // Posa RC6 (AN8) com a entrada
  // La resta del port C ?s de sortida
  ADCON1 = 0b00010000;  // Posa el conversor a 1/8 de la freq??ncia
  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
  ANSEL = 0b00000001;  // Configura AN0 com entrada anal?gica
  ANSELH = 0b00000001;  // Configura AN8 com entrada anal?gica
  PORTB = 0;  // Inicialitza a 0 el port B
  PORTC = 0;  // Inicialitza a 0 el port 
  min = 0;
  max = 100;
  iter = 32;
  Ini3max();  // Inicialitza els tres MAX7221
  Actiu = 1;  // Activa el color vermell
  TMR0 = 100;  // Presselecció de 100, que són 156 iteracions
  // Correspon a una interrupció cada 7,5 ms
  clear_led();  // Apaga tots els LED
  INTCONbits.GIE = 0;  // Desactiva les interrupcions momentàniament
  RCSTAbits.SPEN = 1;  // Activa comunicació sèrie
  TXSTAbits.TXEN = 1;  // Activa comunicació
  __delay_ms(1500);
  def_char(1, 0b00010000);
  def_char(2, 0b00011000);
  def_char(3, 0b00011100);  // Deifinim els caràcters per a les barres parcials
  def_char(4, 0b00011110);
  def_char(5, 0b00011111);
  clear_lcd();  // Esborra tota la pantalla
  RCSTAbits.SPEN = 0;  // Desactiva comunicació sèrie
  TXSTAbits.TXEN = 0;  // Desactiva comunicació
  INTCONbits.GIE = 1;  // Activa les interrupcions  
  ADCON0 = 0b10100001;  // Activa el conversor connectat a AN8
  // amb el resultat justificat per la dreta
  __delay_ms(400);  // Retard de 0,4 s
  while (1) {
    X = 0;  // Ho farem servir per calcular la mitjana
    // Calcularem 32 RMS i els anirem mostrant
    // a la primera filera de la matriu de LED
    for (int j = 0; j < iter; j++) {
      sumQuad = 0;  // Ho farem servir per calcular l'RMS
      for (int i = 0; i < 32; i++) {  // Calcularem 32 RMS
        ADCON0bits.GO = 1;  // Posa en marxa el conversor
        while (ADCON0bits.GO == 1)  // Mentre no acabi
          ;  // ens esperem
        Read = ADRESH * 256 + ADRESL;  // Guardem el resultat
        if (Read > 511) {
          sumQuad += (Read - 511)*(Read - 511);  // Restem 511 que és el valor nul
        } else {
          sumQuad += (511 - Read)*(511 - Read);  // Restem 511 que és el valor nul
        }
        // Anem sumant els seus quadrats per l'RMS
        // Al fer el quadrat quedarà positiu
        if (btn0 == 0) {
          clear_led();
          INTCONbits.GIE = 0;  // Desactiva les interrupcions momentàniament
          RCSTAbits.SPEN = 1;  // Activa comunicació sèrie
          TXSTAbits.TXEN = 1;  // Activa comunicació
          clear_lcd();
          __delay_ms(400);
          settings_scale();
          clear_lcd();
          RCSTAbits.SPEN = 0;  // Desactiva comunicació sèrie
          TXSTAbits.TXEN = 0;  // Desactiva comunicació
          INTCONbits.GIE = 1;  // Activa les interrupcions
        }
      }
      RMS = sqrt(sumQuad/32);  // Calculem l'RMS a partir de la suma de quadrats
      if (RMS < min) {  // Per evitar que min sigui negatiu
        RMS = 0;
      } else {
        RMS = (RMS-min)*100/(max-min);  // Apliquem l'escalat
      }
      X += RMS;  // Ho sumem a la variable que farem servir per
      // calcular la 'sub-mitjana'
      Sortida[0] = 0b00000000;  // Posem tots els vermells a 0
      Sortida[2] = 0b00000000;  // Posem tots els verds a 0
      Adder = 0b10000000;  // Anirem rotant aquesta variable per encendre
      // els LED segons el nivell
      Lvl = RMS*8/100;  // Ajustem el nivell als 8 LED de la matriu
      for (int i = 0; i < Lvl; i++) {  // Per cada LED mirem si l'encenem o no segons el color
        if (i < 7) {  // Si el nivell és inferior a 7, s'encén de color verd
          Sortida[2] = Sortida[2] + Adder;
        }
        if (i > 3) {  // Si el nivell és superior a 3, s'encén de color vermell
          Sortida[0] = Sortida[0] + Adder;
        }  // Del 4 al 6 quedaran de color groc per combinació
        Adder = Adder >> 1;  // Rotem per treballar amb el següent LED
      }
      Sortida[1] = 0x01;  // Filera 1
      Sortida[3] = 0x01;
      Sortida[5] = 0x01;
      Envia3max(Sortida);  // Ho envia al MAX7221
      __delay_ms(50);
    }
    X /= iter;  // Calcula la mitjana
    INTCONbits.GIE = 0;  // Desactiva les interrupcions momentàniament
    RCSTAbits.SPEN = 1;  // Activa comunicació sèrie
    TXSTAbits.TXEN = 1;  // Activa comunicació
    clear_lcd();  // Esborrem tot el que hi ha a la pantalla
    cursor(1,6);  // Movem el cursor per centrar el valor
    write_val(X);  // Escribim el valor
    cursor(2,1);  // Movem el cursor a la segona filera
    write_bar(X);  // Dibuixem la barra amb el nivell
    RCSTAbits.SPEN = 0;  // Desactiva comunicació sèrie
    TXSTAbits.TXEN = 0;  // Desactiva comunicació
    INTCONbits.GIE = 1;  // Activa les interrupcions
  }
}
void __interrupt() temporit(void){
  if (INTCONbits.T0IF) {  // Comprovem que hi ha interrupció per Timer 0
    TMR0 = 100;  // 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
    Sorti[0] = 0x00;  // Vermell
    Sorti[2] = 0x00;  // Verd
    Sorti[4] = 0x00;  // Blau
    if (Actiu == 1) {  // Si és vermell
      Sorti[0] = 0x01;  // Vermell activat
    }
    if (Actiu == 2) {  // Si és verd
      Sorti[2] = 0x01;  // Verd activat
    }
    if (Actiu == 3) {  // Si és blau
      Sorti[4] = 0x01;  // Blau activat
    }
    Sorti[1] = 0x0C;  // Shutdown mode
    Sorti[3] = 0x0C;  // Shutdown mode
    Sorti[5] = 0x0C;  // Shutdown mode
    Envia_max();  // Ho envia al MAX7221
  }
}
void settings_scale(void) {
  unsigned int increment = 1;  // L'increment per canviar alguna variable (serà 1 o 10)
  clear_lcd();  // Esborra la pantalla
  cursor(1,5);  // Mou el cursor
  send_char('S');
  send_char('E');
  send_char('T');  // Escriu "SETTINGS"
  send_char('T');
  send_char('I');
  send_char('N');
  send_char('G');
  send_char('S');
  __delay_ms(400);  // Retard de 400ms
  disp_scale(increment);  // Mostra min i max a la pantalla
  while (1){
    ADCON0 = 0b00001001;  // Activa el conversor A/D connectat a AN2
    ADCON0bits.GO = 1;  // Posa en marxa el conversor
    while (ADCON0bits.GO == 1)  // Mentre no acabi
      ;  // ens esperem
    if (ADRESH < 220 && ADRESH > 200) {  // Polsador 1
      if (max > min + increment) {  // max > min
        max -= increment;  // Redueix max
      }
    }
    if (ADRESH < 194 && ADRESH > 174) {  // Polsador 2
      if (max <= 511-increment) {  // max <= 511
        max += increment;  // Augmenta max
      }
    }
    if (ADRESH < 163 && ADRESH > 143) {  // Polsador 3
      if (increment == 1) {  //
        increment = 10;  //
      } else {  // Alterna l'increment entre 1 i 10
        increment = 1;  //
      }
    }
    if (ADRESH < 90 && ADRESH > 70) {  // Polsador 4
      if (min >= increment) {  // min >= 0
        min -= increment;  // Redueix min
      }
    }
    if (ADRESH < 55 && ADRESH > 35) {  // Polsador 5
      if (min < max-increment) {  // min < max
        min += increment;  // Augmenta min
      }
    }
    if (ADRESH > 35) {  // Si s'ha premut algun polsador
      disp_scale(increment);  // Mostra min i max a la pantalla
      __delay_ms(100);  // Retard
    }
    if (btn0 == 0) {  // Si es prem el polsador 0
      settings_iter();
      ADCON0 = 0b10100001;  // Activa el conversor connectat a AN8
      break;  // Acaba settings
    }
  }
}
void disp_scale(int increment) {
  clear_lcd();  // Esborra la pantalla
  cursor(1,0);  // Mou el cursor
  send_char('M');
  send_char('A');  // Escriu "MAX"
  send_char('X');
  cursor(2,0);  // Mou el cursor
  send_char('M');
  send_char('I');  // Escriu "MIN"
  send_char('N');
  cursor(1,7);  // Mou el cursor
  write_val(max);  // Escriu el valor de la variable min
  cursor(2,7);  // Mou el cursor
  write_val(min);  // Escriu el valor de la variable max
  cursor(1,13);  // Mou el cursor
  write_val(increment);  // Escriu quant val l'increment
}
void settings_iter(void) {
  unsigned int increment = 1;  // L'increment per canviar alguna variable (serà 1 o 10)
  clear_lcd();
  __delay_ms(400);  // Retard de 400ms
  disp_iter(increment);  // Mostra iter i mult a la pantalla
  while (1){
    ADCON0 = 0b00001001;  // Activa el conversor A/D connectat a AN2
    ADCON0bits.GO = 1;  // Posa en marxa el conversor
    while (ADCON0bits.GO == 1)  // Mentre no acabi
      ;  // ens esperem
      if (ADRESH < 220 && ADRESH > 200) {  // Polsador 1
        if (iter > increment) {  // iter > 0
          iter -= increment;  // Redueix iter
        }
      } else if (ADRESH < 194 && ADRESH > 174) {  // Polsador 2
        if (iter < 8388608-increment) {  // iter < 8388608
          iter += increment;  // Augmenta iter
        }
      } else if (ADRESH < 163 && ADRESH > 143) {  // Polsador 3
        if (increment == 10000) {  //
          increment = 1;  //
        } else {  // Alterna iter entre
          increment *= 10;  // 1, 10, 100, 1000 i 10000
        }
      }
      if (ADRESH > 143) {  // Si s'ha premut algun polsador
        disp_iter(increment);  // Mostra iter i mult a la pantalla
        __delay_ms(100);  // Retard
      }
      if (btn0 == 0) {  // Si es prem el polsador 0
        clear_lcd();  // Esborra la pantalla
        __delay_ms(400);  // Retard de 400ms
        break;  // Acaba settings
    }
  }
}
void disp_iter(int increment) {
  clear_lcd();  // Esborra la pantalla
  cursor(1,0);  // Mou el cursor
  send_char('I');
  send_char('T');  // Escriu "ITER"
  send_char('E');
  send_char('R');
  cursor(2,0);  // Mou el cursor
  write_slong(iter);  // Escriu el valor de la variable iter
  cursor(1,10);  // Mou el cursor
  write_slong(increment);  // Escriu quant val l'increment
}
void write_val(unsigned int Valor){
  char Digits[5];  // Variable amb el n?mero d?git a d?git
  // Digits[0] s?n les unitats
  // Convertim a BCD
  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
  // Passem els d?gits a ASCII
  for (int j = 0; j < 5; j++){  // 5 d?gits
    Digits[j] = Digits[j] + '0';  // Li sumem el codi ASCII de 0
  }
  // Suprimim zeros innecessaris
  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
      }
    }
  }
  for (int k = 3; k >= 0; k--){  // Nom?s escrivim quatre valors
    send_char(Digits[k]);  // Escriu un d?git a la pantalla
  }
}
void write_slong(unsigned long Valor){
  char Digits[7];  // Variable amb el n?mero d?git a d?git
  // Digits[0] s?n les unitats
  // Convertim a BCD
  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
  Valor = Valor / 10;
  Digits[4] = Valor % 10;  // Desenes de milers
  Valor = Valor / 10;
  Digits[5] = Valor % 10;  // Centenes de milers
  Digits[6] = Valor / 10;  // Mil·lions
  // Passem els d?gits a ASCII
  for (int j = 0; j < 7; j++){  // 7 d?gits
    Digits[j] = Digits[j] + '0';  // Li sumem el codi ASCII de 0
  }
  // Suprimim zeros innecessaris  // Si ho ?s, hi posem un espai
  if (Digits[6] == '0') {  // Mirem si el primer d?git ?s 0
    Digits[6] = ' ';  // Si ho ?s, hi posem un espai
    if (Digits[5] == '0') {  // Mirem si el segon d?git ?s 0
      Digits[5] = ' ';  // Si ho ?s, hi posem un espai
      if (Digits[4] == '0') {  // Mirem si el tercer d?git ?s 0
        Digits[4] = ' ';  // Si ho ?s, hi posem un espai
        if (Digits[3] == '0') {  // Mirem si el quart d?git ?s 0
          Digits[3] = ' ';  // Si ho ?s, hi posem un espai
          if (Digits[2] == '0') {  // Mirem si el cinquè d?git ?s 0
            Digits[2] = ' ';  // Si ho ?s, hi posem un espai
            if (Digits[1] == '0') {  // I mirem si ho ?s el sisè
              Digits[1] = ' ';  // Si ho ?s, hi posem un espai
            }
          }
        }
      }
    }
  }
  for (int k = 6; k >= 0; k--){  // Escrivim set valors
    send_char(Digits[k]);  // Escriu un d?git a la pantalla
  }
}
void write_bar(unsigned int Lvl) {
  if (Lvl >= 100) {
    Lvl = 80;  // Com a màxim 80
  } else {
    Lvl = Lvl*8/10;  // Disposem de 80 nivells en lloc de 100
  }
  while (Lvl >= 5) {  // Mentre haguem d'escriure barres senceres
    send_char(5);  // Dibuixem un rectangle de la barra
    Lvl -= 5;  // Descomptem el que hem dibuixat
  }
  if (Lvl != 0) {
    send_char(Lvl);  // Dibuixa l'últim rectangle (parcial)
  }
}
void send_char(char Caracter) {// Escriu un caràcter a la pantalla LCD
  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
}
void clear_lcd(void) {  // Esborra la pantalla LCD
  send_char(254);  // Caràcter de control
  send_char(1);  // Esborra la pantalla i posa el cursor a l'inici
}
void cursor(char row, char column) {
  char pos = 0;  // Variable per a calcular la posició
  if (row == 2) {
    pos = 64;  // La primera columna de la segona fila és 64
  }
  if (column > 0 && column < 33) {  // Comprovem que sigui un valor raonable
    pos = pos + column;  // Sumem les adreces
    pos = pos - 1;  // Restem 1 perquè numera des de 0
  }
  pos = pos + 128;  // Posa el bit de posicionat a 1
  send_char(254);  // Control de la posició del cursor
  send_char(pos);  // Canvia el cursor de lloc
}
void Envia3max(char Valor[]) {  // Envia un joc de valors als tres MAX7221
  INTCONbits.T0IE = 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.T0IE = 1;  // Reactiva les interrupcions a l'acabar
}
void Envia_max(void) {  // Envia un joc de valors als tres MAX7221
  asm("banksel _Port");
  asm("bcf (_Port&7fh),5");  // S'assegura que Clock està desactivat
  asm("bcf (_Port&7fh),6");  // S'assegura que Latch està desactivat
  asm("movf (_Port&7fh),w");  // Agafa el valor de Port
  asm("movwf PORTB");  // I el posa al port B
  asm("banksel _Compta");
  asm("movlw 48");  // Número de bits a enviar
  asm("movwf (_Compta&7fh)");  // Variable per comptar els bits
  asm("Bucle:");
  asm("banksel _Port");
  asm("bcf (_Port&7fh),4");  // Desactiva Data. Si toca activar-ho, ja ho farem
  asm("banksel _Sorti");
  asm("rlf (_Sorti&7fh),f");  // Fa sortir el bit de més a l'esquerra cap a C
  asm("rlf ((_Sorti+1)&7fh),f");  // i roda els altres a l'esquerra
  asm("rlf ((_Sorti+2)&7fh),f");
  asm("rlf ((_Sorti+3)&7fh),f");
  asm("rlf ((_Sorti+4)&7fh),f");
  asm("rlf ((_Sorti+5)&7fh),f");
  asm("banksel _Port");
  asm("btfsc STATUS,0");  // Mira si el bit de l'esquerra era un 1
  asm("bsf (_Port&7fh),4");  // Si era 1, activa Data
  asm("movf (_Port&7fh),w");  // Agafa el valor de Port. El valor que ha canviat és Data
  asm("movwf PORTB");  // I el posa al port B
  asm("bsf (_Port&7fh),5");  // Activa Clock, forçant a llegir el bit
  asm("movf (_Port&7fh),w");  // Agafa el valor de Port. El valor que ha canviat és Clock
  asm("movwf PORTB");  // I el posa al port B
  asm("bcf (_Port&7fh),5");  // Desactiva Clock
  asm("movf (_Port&7fh),w");  // Agafa el valor de Port. El valor que ha canviat és Clock
  asm("movwf PORTB");  // I el posa al port B
  asm("banksel _Compta");
  asm("decfsz (_Compta&7fh),f");  // Decrementa Compta
  asm("goto Bucle");  // Si Compta no és zero, repeteix el bucle
  asm("banksel (_Port&7fh)");
  asm("bsf (_Port&7fh),6");  // Torna a activar Latch
  // Els valors es copiaran a la sortida del registre
  asm("movf (_Port&7fh),w");  // Agafa el valor de Port. El valor que ha canviat és Latch
  asm("movwf PORTB");  // I el posa al port B
}
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 clear_led(void) {  // Apaga tots els LED
  char Bytes[6];  // Els sis bytes que cal enviar
  for (int j = 1; 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 def_char(char num, char val) {
  send_char(254);  // Caràcter de control
  send_char(num*8 +64);  // Posició
  for (signed char k = 0; k < 7; k++){
    send_char(val);  // Envia línies
  }
  send_char(0b00000000);  // L'última línia buida per evitar problemes
}

 

 

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