Programació en C del PIC 16F690

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

Joc d'enfonsar vaixells electrònic

Programa del grup 4

En aquest cas hi ha un jugador que intenta enfonsar els vaixells que ha situat la màquina. El programa situa sis vaixells triats, de manera aleatòria, entre vuit opcions possibles:

Mida Nombre de vaixells
4 caselles 1
3 caselles 1
2 caselles 2
1 casella 2

Els colors dels LED de la matriu representen:

Color Significat
Apagat Casella sobre la que no s'ha disparat
Blau Aigua
Vermell Tocat
Groc Posició del cursor

Els polsadors de la part inferior serveixen per moure el cursor i per disparar sobre la casella actual, segons el següent ordre:

Polsador Funció
1 Esquerra
2 Amunt
3 Disparar
4 Avall
5 Dreta

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 <stdlib.h>  // Carrega el fitxer on hi ha la funció rand()
#define _XTAL_FREQ  4000000  // La freqüència del rellotge és 4 MHz
#define Polsador0   RA3  // Li assigna un nom a l'adreça del polsador
char Sortida[6];  // Valors a enviar al MAX7221 (16 bits)
char Actiu;  // Variable que diu quin color està actiu
char Me[8][8]= {{0,0,0,0,0,0,0,0},
                {0,0,0,0,0,0,0,0},
                {0,0,0,0,0,0,0,0},
                {0,0,0,0,0,0,0,0},
                {0,0,0,0,0,0,0,0},
                {0,0,0,0,0,0,0,0},
                {0,0,0,0,0,0,0,0},
                {0,0,0,0,0,0,0,0}};
char numeros[40][1] = {'0','1','2','3','4','5','6','7','8','9',
                       '0','1','2','3','4','5','6','7','8','9',
                       '0','1','2','3','4','5','6','7','8','9',
                       '0','1','2','3','4','5','6','7','8','9'};
char Port;
char Compta;
char f1;
char f2;
char conta;
char xc;
char yc;
char ym;
char R;
char B;
char V;
char Polsador(void);// Funció de lectura dels polsadors
char Polsad;
char tocats;
char alea;
// Definició de les funcions que farem servir
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 Apaga(void);  // Apaga tots els LED
void EnviaL(char Caracter);  // Envia un caràcter
void Esborra(void);  // Esborra la pantalla i posa el cursor a l'inici
void TocaNota(char valPre, char valPos, char valPR2);  
void main (void) {
  _delay(2000000);
  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)
  TRISC = 0; // Tot el port C és de sortida
  TRISB = 0; // Tot el port B és de sortida
  TRISA = 0xFF; // Tot el port A és d'entrada
  ANSEL = 0b00000101; // Configura AN0 i AN2 com entrada analògica
  ANSELH = 0; // Desactiva les altres entrades analògiques
  PORTC = 0; // Inicialitza a 0 el port C
  PORTB = 0; // Inicialitza a 0 el port B
  Ini3max(); // Inicialitza els tres MAX7221
  Actiu = 1;
  CCP1CON = 0b00001100;
  TMR0 = 100; // Presselecció de 100, que són 156 iteracions
  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
  INTCON = 0b10100000; // Activem GIE i T0IE
  ADCON1 = 0b00010000; // Posa el conversor a 1/8 de la freqüència
  ADCON0 = 0b00001001; // Activa el conversor A/D connectat a AN2
  Esborra();
  EnviaL('<');  //la pantalla indica que premem el pulsador
  EnviaL('-');
  EnviaL('-');
  EnviaL('-');
  EnviaL('-');
  EnviaL('P');
  EnviaL('R');
  EnviaL('E');
  EnviaL('S');    
  EnviaL('S');   
  while (Polsador0 == 1)  // Mentre el polsador no estigui premut
    ;  // No fa res
  while (Polsador0 == 0)  // Mentre el polsador estigui premut
    ;  
  srand(TMR0);  //Utilitzo Tmr0 com a variable per conseguir l'aleatori ja que amb el polsador anterior sempre sera diferent
  alea=rand();  //creo el valor aleatori
  Apaga(); 
  xc=8;
  yc=8;
  R=0;
  B=0;
  V=0;
  TocaNota(238, 119, 2);  //Melodia inicial
  TocaNota(200, 100, 2);
  TocaNota(212, 106, 2);
  TocaNota(212, 106, 2);
  TocaNota(238, 119, 2);
  TocaNota(212, 106, 2);
  Esborra();
  EnviaL('--');  //la pantalla ens indica nova partida
  EnviaL('--');           
  EnviaL('N');
  EnviaL('E');
  EnviaL('W');
  EnviaL(' ');
  EnviaL('G');
  EnviaL('A');
  EnviaL('M');
  EnviaL('E');
  EnviaL('--');
  conta=35;
  tocats=0;
  if ((0<=alea)&&(alea<=31)){ //Segons el valor aleatori agafo una configuració inicial 
    Me[1][1]=1;
    Me[1][2]=1;
    Me[1][6]=1;
    Me[3][2]=1;
    Me[3][3]=1;
    Me[3][4]=1;
    Me[5][2]=1;
    Me[6][2]=1;
    Me[4][6]=1;
    Me[5][6]=1;
    Me[6][6]=1;
    Me[7][6]=1;
    Me[7][0]=1;
  }
  if ((32<=alea)&&(alea<=63)){
    Me[0][0]=1;
    Me[1][0]=1;
    Me[2][0]=1;
    Me[3][0]=1;
    Me[1][4]=1;
    Me[3][2]=1;
    Me[3][3]=1;
    Me[6][1]=1;
    Me[5][4]=1;
    Me[6][4]=1;
    Me[4][7]=1;
    Me[5][7]=1;
    Me[6][7]=1;
  }
  if ((64<=alea)&&(alea<=95)){
    Me[2][2]=1;
    Me[3][2]=1;
    Me[1][5]=1;
    Me[5][1]=1;
    Me[4][4]=1;
    Me[5][4]=1;
    Me[3][6]=1;
    Me[4][6]=1;
    Me[5][6]=1;
    Me[7][1]=1;
    Me[7][2]=1;
    Me[7][3]=1;
    Me[7][4]=1;
  }
  if ((96<=alea)&&(alea<=127)){
    Me[1][0]=1;
    Me[1][1]=1;
    Me[0][3]=1;
    Me[1][3]=1;
    Me[2][3]=1;
    Me[3][3]=1;
    Me[1][6]=1;
    Me[4][1]=1;
    Me[5][1]=1;
    Me[3][5]=1;
    Me[3][6]=1;
    Me[3][7]=1;
    Me[5][5]=1;
  }
  if ((128<=alea)&&(alea<=159)){
    Me[0][7]=1;
    Me[7][7]=1;
    Me[2][1]=1;
    Me[3][1]=1;
    Me[2][3]=1;
    Me[2][4]=1;
    Me[2][5]=1;
    Me[4][5]=1;
    Me[5][5]=1;
    Me[6][5]=1;
    Me[7][5]=1;
    Me[5][2]=1;
    Me[5][3]=1;
  }
  if ((160<=alea)&&(alea<=191)){
    Me[1][1]=1;
    Me[3][1]=1;
    Me[4][1]=1;
    Me[5][1]=1;
    Me[6][1]=1;
    Me[1][4]=1;
    Me[2][4]=1;
    Me[2][6]=1;
    Me[4][3]=1;
    Me[4][4]=1;
    Me[4][5]=1;
    Me[6][6]=1;
    Me[7][6]=1;
  }
  if ((192<=alea)&&(alea<=223)){
    Me[0][7]=1;
    Me[1][1]=1;
    Me[1][2]=1;
    Me[1][3]=1;
    Me[1][4]=1;
    Me[3][1]=1;
    Me[3][2]=1;
    Me[3][5]=1;
    Me[4][5]=1;
    Me[6][1]=1;
    Me[6][4]=1;
    Me[6][5]=1;
    Me[6][6]=1;
  }
  if ((224<=alea)&&(alea<=256)){
    Me[7][7]=1;
    Me[7][6]=1;
    Me[7][5]=1;
    Me[7][4]=1;
    Me[7][2]=1;
    Me[6][2]=1;
    Me[5][2]=1;
    Me[5][4]=1;
    Me[5][5]=1;
    Me[5][7]=1;
    Me[3][7]=1;
    Me[3][6]=1;
    Me[3][4]=1;
  }
  while (1)  {    
    Polsad = Polsador();
    if ((Polsad ==5) && (xc>1)) {
      Apaga();
      xc--;
    }
    if ((Polsad ==4) && (yc<8)) {
      Apaga();
      yc++;
    }
    if ((Polsad ==2) && (yc>1)) {
      Apaga();
      yc--;
    }
    if ((Polsad ==1) && (xc<8)) {
      Apaga();
      xc++;
    }
    if ((Polsad ==3) && (Me[yc-1][8-xc]==0)) { //DISPAR AIGUA
      conta-=1;
      TocaNota(238, 119, 2);
      TocaNota(212, 106, 2);
      Esborra();
      EnviaL('-');
      EnviaL('W');
      EnviaL('A');
      EnviaL('T');
      EnviaL('E');
      EnviaL('R');
      EnviaL('-');
      EnviaL(' ');
      EnviaL(' ');
      EnviaL(' ');
      EnviaL(' ');
      EnviaL(' ');
      EnviaL(' ');
      EnviaL(' ');
      EnviaL(' ');
      EnviaL(' ');
      EnviaL('S');
      EnviaL('H');
      EnviaL('O');
      EnviaL('T');
      EnviaL('S');
      EnviaL(':');
      if (conta<10) {
        EnviaL(numeros[conta-1][1]);
      }
      if ((9<conta) && (conta<20)) {
        EnviaL('1');
        EnviaL(numeros[conta-1][1]);
      }
      if ((19<conta) && (conta<30)) {
        EnviaL('2');
        EnviaL(numeros[conta-1][1]);
      }
      if (30<=conta) {
        EnviaL('3');
        EnviaL(numeros[conta-1][1]);
      }
      Apaga();
      Me[yc-1][8-xc]=2; 
    }
    if ((Polsad==3) && (Me[yc-1][8-xc]==1)) { //DISPAR VAIXELL
      conta-=1;
      tocats+=1;
      TocaNota(141, 71, 0);
      TocaNota(126, 63, 2);
      TocaNota(141, 71, 0);
      Esborra();
      EnviaL('-');
      EnviaL('T');
      EnviaL('O');
      EnviaL('U');
      EnviaL('C');
      EnviaL('H');
      EnviaL('E');
      EnviaL('D');
      EnviaL('-');
      EnviaL(' ');
      EnviaL(' ');
      EnviaL(' ');
      EnviaL(' ');
      EnviaL(' ');
      EnviaL(' ');
      EnviaL(' ');
      EnviaL('S');
      EnviaL('H');
      EnviaL('O');
      EnviaL('T');
      EnviaL('S');
      EnviaL(':');
      if (conta<10) {
        EnviaL(numeros[conta-1][1]);
      }
      if ((9<conta) && (conta<20)) {
        EnviaL('1');
        EnviaL(numeros[conta-1][1]);
      }
      if ((19<conta) && (conta<30)) {
        EnviaL('2');
        EnviaL(numeros[conta-1][1]);
      }
      if (30<=conta) {
        EnviaL('3');
        EnviaL(numeros[conta-1][1]);
      }
      Apaga();
      Me[yc-1][8-xc]=3;    
    } 
    if (tocats>=13) {  //soroll de partida guanyada
      TocaNota(118, 58, 2);
    }
    if (conta==-1) {  //soroll de partida perduda
      TocaNota(238, 119, 2);
    }
    for (char e=1; e<9; e++){
      f1=0; 
      R=0;
      V=0;
      B=0;
      for (char i=0; i<8; i++){
        if (Me[e-1][i]==2){
          f2=1<<(7-i);
          f1=f1|f2;
        }
      }
      B=f1;
      f1=0;
      for (char i=0; i<8; i++){
        if (Me[e-1][i]==3){
          f2=1<<(7-i);
          f1=f1|f2;
        }
      }
      R=f1;
      if (e==yc) {
        if (Me[yc-1][8-xc]==3) {
          V=1<<(xc-1);               
        }
        if (Me[yc-1][8-xc]==2) {
          R+=1<<(xc-1);
          V=1<<(xc-1);
          B=B-(1<<(xc-1));
        }
        if ((Me[yc-1][8-xc]!=3)&&(Me[yc-1][8-xc]!=2)) {
          R+=1<<(xc-1);
          V=1<<(xc-1);
        }
      }
      if (tocats>=13) {  //misatge de victoria i matriu verda per victoria
        Esborra();
        EnviaL('V');
        EnviaL('I');
        EnviaL('C');
        EnviaL('T');
        EnviaL('O');
        EnviaL('R');
        EnviaL('Y');
        EnviaL(' ');
        EnviaL(' ');
        EnviaL(' ');
        EnviaL(' ');
        EnviaL(' ');
        EnviaL(' ');
        EnviaL(' ');
        EnviaL(' ');
        EnviaL(' ');
        EnviaL('P');
        EnviaL('L');
        EnviaL('E');
        EnviaL('A');
        EnviaL('S');
        EnviaL('E');
        EnviaL(' ');
        EnviaL('D');
        EnviaL('E');
        EnviaL('S');
        EnviaL('C');
        EnviaL('O');
        EnviaL('N');
        EnviaL('E');
        EnviaL('C');
        EnviaL('T');
        B=0;
        V=0b11111111;
        R=0;               
      }
      if (conta==-1) {  //misatge de derrota i matriu vermella per derrota
        Esborra();
        EnviaL('G');
        EnviaL('a');
        EnviaL('m');
        EnviaL('e');
        EnviaL(' ');
        EnviaL('o');
        EnviaL('v');
        EnviaL('e');
        EnviaL('r');
        EnviaL(' ');
        EnviaL(' ');
        EnviaL(' ');
        EnviaL(' ');
        EnviaL(' ');
        EnviaL(' ');
        EnviaL(' ');               
        EnviaL('P');
        EnviaL('L');
        EnviaL('E');
        EnviaL('A');
        EnviaL('S');
        EnviaL('E');
        EnviaL(' ');
        EnviaL('D');
        EnviaL('E');
        EnviaL('S');
        EnviaL('C');
        EnviaL('O');
        EnviaL('N');
        EnviaL('E');
        EnviaL('C');
        EnviaL('T');
        B=0;
        V=0;
        R=0b11111111;
      }
      Sortida[1]=e;
      Sortida[3]=e;
      Sortida[5]=e;
      Sortida[0]=R;
      Sortida[2]=V;
      Sortida[4]=B;
      Envia3max(Sortida);
    }
    __delay_ms(10);
  } 
}
void __interrupt() temporit(void){
// void interrupt temporit(void) {  // Línia alternativa
  if (INTCONbits.T0IF) {  // Comprovem que hi ha interrupció per Timer 0
    TMR0 = 140;  // 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
    Envia_max();  // Ho envia al MAX7221
  }
}   
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,5"); // S'assegura que Clock està desactivat
  asm("bcf _Port,6"); // S'assegura que Latch està desactivat
  asm("movf _Port,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"); // Variable per comptar els bits
  asm("Bucle:");
  asm("banksel _Port");
  asm("bcf _Port,4"); // Desactiva Data. Si toca activar-ho, ja ho farem
  asm("banksel _Sortida");
  asm("rlf _Sortida,f"); // Fa sortir el bit de més a l'esquerra cap a C
  asm("rlf _Sortida+1,f"); // i roda els altres a l'esquerra
  asm("rlf _Sortida+2,f");
  asm("rlf _Sortida+3,f");
  asm("rlf _Sortida+4,f");
  asm("rlf _Sortida+5,f");
  asm("banksel _Port");
  asm("btfsc STATUS,0"); // Mira si el bit de l'esquerra era un 1
  asm("bsf _Port,4"); // Si era 1, activa Data
  asm("movf _Port,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,5"); // Activa Clock, forçant a llegir el bit
  asm("movf _Port,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,5"); // Desactiva Clock
  asm("movf _Port,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,f"); // Decrementa Compta
  asm("goto Bucle"); // Si Compta no és zero, repeteix el bucle
  asm("banksel _Port");
  asm("bsf _Port,6"); // Torna a activar Latch
  // Els valors es copiaran a la sortida del registre
  asm("movf _Port,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 Apaga(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
  }
}
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 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
}
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.