En aquest cas, el programa contempla tres modes de funcionament predefinits (bar, passadís i biblioteca) i un de personalitzat que es poden triar amb els polsadors. En el mode personalitzat es pot definir el rang esperat de so i en els altres es poden configurar els llindars. A més, el polsador 0 deixa l'aparell en mode repòs (sembla que l'aparell estigui apagat) i permet sortir-ne; aquest mode és el que està definit per al moment d'engegar.
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 #include <math.h> #define _XTAL_FREQ 4000000 // La freqüència del rellotge és 4 MHz #define FiTimer1 PIR1bits.TMR1IF // Li assigna un nom al bit que indica el final del Timer 1 #define Inicia RA3 // Li assigna un nom a l'adreça del polsador
unsigned int Lectura[32]; // Per guardar els valors llegits
char pos = 0; // Punter del vector
char n; // Elegir si sona brunzidor
int brun; // Variable per l?escala del brunzidor
char p = 0; // Elegir si s'encén i s?apaga
char esc[8] = {20,18,16,14,12,10,8,6}; // Constant escala de so
char mod = 0; // Mode en el que ens trobem
char lind = 50; // Valor llindar
char pas[3]= {1,5,10}; // Pas
char r=1; // Rang
char k=0; // Canvi estat entre elegir Pas o Rang
char j = 0; // Index del pas
char m = 0; // Elegir si registre o no so
unsigned long SO=0;
unsigned int SOmitj=0;
float SOef=0; // Valor de so enregistrat
unsigned int SOint; // Valor en nombre enter del so enregistrat
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ó
char Actiu; // Variable que diu quin color està actiu
char fig[6][8] = { {0b00000000, 0b00100100, 0b00100100, 0b00000000, // Figura 1
0b01000010, 0b00100100, 0b00011000, 0b00000000},
{0b00111100, 0b01111110, 0b11111111, 0b11111111,
0b10111101, 0b11111111, 0b01111110, 0b00111100},
{0b00000000, 0b00100100, 0b00100100, 0b00000000,
0b00000000, 0b00100100, 0b00011000, 0b00000000},
{0b00111100, 0b01111110, 0b11111111, 0b11111111, // Figura 2
0b11111111, 0b11111111, 0b01111110, 0b00111100},
{0b00000000, 0b00100100, 0b00100100, 0b00000000,
0b00000000, 0b00011000, 0b00100100, 0b00000000},
{0b00000000, 0b00100100, 0b00100100, 0b00000000,
0b00000000, 0b00011000, 0b00100100, 0b00000000}};
char Polsad; // Polsador que s'ha premut
// Definició de les funcions que farem servir
void Linia(void); // Escriu una línia de resultats
void escriuValor(unsigned int Valor); // Escriu un valor 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 Envia3max(char Valor[]); // Envia un joc de valors als tres MAX7221
// desactivant interrupcions
void led(void); // Envia figures a la matriu LED
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
char Polsador(void); // Funció de lectura dels polsadors
void Cursor(char Filera, char Columna); // Posiciona el cursor
void TocaNota(char ValPR2, char ValCCPR1L, char ValDC1B); // Sona el brunzidor
int Sqrt(unsigned long x) ; // Funció per calcular l?arrel
void llindar(char Pols); // Funció canviar de llindar
void main (void) {
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 C
FiTimer1 = 0; // Aquest bit es posarà a 1 quan el temporitzador acabi
TMR1H = 248; // Inicialitza el Timer1
TMR1L = 94;
T1CON = 0b00110001; // Configuració de Timer1
OPTION_REG = 0b10000101; // Configuració de Timer0
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
INTCON = 0b10100000; // Activem GIE i T0IE
Apaga(); // Apaga tots els LED
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
while (1) { // Bucle infinit
if (Inicia == 0){
Esborra();
p = p+1;
p=p%2;
if (p==1){ // Apagat
EnviaL('E'); // Lletra
EnviaL('n'); // Lletra
EnviaL('c'); // Lletra
EnviaL('e'); // Lletra
EnviaL('n'); // Lletra
}
if (p==0){ // Encés
EnviaL('A'); // Lletra
EnviaL('p'); // Lletra
EnviaL('a'); // Lletra
EnviaL('g'); // Lletra
EnviaL('a'); // Lletra
PORTC = 0b00000000; // Inicialització variables
m=0;
mod=0;
j=0;
lind = 50;
k = 0;
}
__delay_ms(500); // Retard de 0,5 s
Esborra(); // Esborra LCD
}
if (p == 1) {
SOmitj=0; // Inicialització variables
SO=0;
SOef=0;
Polsad = Polsador(); // Llegim els polsadors
if (Polsad == 2){ // Si s'ha premut el pulsador 2
m = m+1;
m = m%2;
Esborra(); // Esborra LCD
Apaga(); // Apaga LED
__delay_ms(300); // Retard 0,3 s
}
FiTimer1 = 0; // Desactivem el bit de final de temporització
// Per assegurar la desconnexió del programador
if (m==0){ // Enregistre So
if (Polsad == 1){ // Si s'ha premut el pulsador 1
mod = mod + 1;
mod = mod%4;
}
if (mod == 0) { // Mode 1
Esborra(); // Esborra LCD
Cursor(1,1); // Posa el cursor
EnviaL('B'); // Lletra
EnviaL('a'); // Lletra
EnviaL('r'); // Lletra
r = 5; // Rang
Cursor(1,11); // Posa cursor
escriuValor(r); // Escriu una línia de resultats
Cursor(2,11); // Posa el cursor
escriuValor(lind); // Escriu una línia de resultats
}
if (mod == 1) { // Mode 2
Esborra(); // Esborra LCD
Cursor(1,1); // Posa el cursor
EnviaL('P'); // Lletra
EnviaL('a'); // Lletra
EnviaL('s'); // Lletra
EnviaL('s'); // Lletra
EnviaL('a'); // Lletra
EnviaL('d'); // Lletra
EnviaL('i'); // Lletra
EnviaL('s'); // Lletra
r=3; // Rang
Cursor(1,11); // Posa el cursor
escriuValor(r); // Escriu una línia de resultats
Cursor(2,11); // Posa el cursor
escriuValor(lind); // Escriu una línia de resultats
}
if (mod == 2) { // Mode 3
Esborra(); // Esborra LCD
Cursor(1,1); // Posa el cursor
EnviaL('B'); // Lletra
EnviaL('i'); // Lletra
EnviaL('b'); // Lletra
EnviaL('l'); // Lletra
EnviaL('i'); // Lletra
EnviaL('o'); // Incrementa y però la manté entre 0 i 7
r=2; // Rang
Cursor(1,11); // Posa el cursor
escriuValor(r); // Escriu una línia de resultats
Cursor(2,11); // Posar cursor
escriuValor(lind); // Escriu una línia de resultats
}
if (mod == 3) { // Mode 4
Esborra(); // Esborra LCD
Cursor(1,1); // Posa el cursor
EnviaL('P'); // Lletra
EnviaL('e'); // Lletra
EnviaL('r'); // Lletra
EnviaL('s'); // Lletra
EnviaL('o'); // Lletra
EnviaL('n'); // Lletra
Cursor(1,11); // Posa el cursor
escriuValor(r); // Escriu una línia de resultats
Cursor(2,11); // Posa el cursor
escriuValor(lind); // Escriu una línia de resultats
}
for (char k = 0; k < 32; k++){ // Llegim 32 valors
while (FiTimer1 == 0) // Mira si Timer1 ha arribat a zero
; // Si no hi ha arribat, espera
T1CONbits.TMR1ON = 0; // Atura momentàniament el Timer1
TMR1H = 248; // Inicialitza el Timer1
TMR1L = 94;
ADCON0 = 0b10100001; // Activa el conversor connectat a AN8
T1CONbits.TMR1ON = 1; // Torna a engegar el Timer1
FiTimer1 = 0; // Tornem a posar el bit a zero
ADCON0bits.GO = 1;
while (ADCON0bits.GO == 1) // Mentre no acabi
; // ens esperem
Lectura[k] = ADRESH * 256 + ADRESL; // Guardem el resultat
SOmitj+=(Lectura[k]); // Suma dels resultats per fer la mitjana
}
SOmitj=SOmitj/32; // Mitjana de So
for (int k=0; k<32; k++){ // Per fer la mitjana
SO+=((Lectura[k]-SOmitj)*(Lectura[k]-SOmitj));
}
SOef=Sqrt((SO)/32)*esc[r-1]; // so eficaç
SOint=SOef; // El so en format unsigned int
SOint = SOint/10;
__delay_ms(10); // Retard 0,1 s
Cursor(2,1); // Posa el cursor
if (SOint > 100){
SOint = 100;
PORTC = 0b00001111; // Activem els LED
} else {
PORTC = 0b00000000; // Desectivem els LED
}
escriuValor(SOint); // Escriu una valor
led(); // Enviem figures a la matriu LED
if (n==1){
brun = 10*(SOint-lind)/(100-lind);
TocaNota(238-12*brun, 119-6*brun, 2); // Funció brunzidor
__delay_ms(200); // Retard 0,2 s
}
__delay_ms(500); // Retard 0,5 s
}
if (m==1 && mod!=3){
Esborra(); // Esborra LCD
llindar(Polsad); // Funció llindar
__delay_ms(100); // Retard 0,1 s
}
if (m==1 && mod==3){
Esborra(); // Esborra LCD
Apaga(); // Apaga matriu LED
if (Polsad == 1){ // Si s'ha premut pulsador 1
k +=1;
k = k%2;
__delay_ms(10); // Retard 0,01 s
}
if (k == 0) {
Esborra(); // Esborra LCD
Cursor(1,1); // Posa el cursor
EnviaL('R'); // Lletra
EnviaL('a'); // Lletra
EnviaL('n'); // Lletra
EnviaL('g'); // Lletra
EnviaL(':'); // Lletra
escriuValor(r); // Escriu un valor
Cursor(2,1); // Lletra
EnviaL('P'); // Lletra
EnviaL('a'); // Lletra
EnviaL('s'); // Lletra
EnviaL(':'); // Lletra
escriuValor(1); // Escriu un valor
__delay_ms(100); // Retard 0,1 s
if (Polsad == 3){ // Si s'ha premut pulsador 3
j +=1;
j = j%3;
__delay_ms(10); // Retard 0,01 s
}
if (Polsad == 4){ // Si s'ha premut pulsador 4
if (r>1){
r -=1;
__delay_ms(10); // Retard 0,01 s
}
}
if (Polsad == 5){ // Si s'ha premut pulsador 5
if (r<8){
r +=1;
__delay_ms(10); // Retard 0,01 s
}
}
}
if (k == 1){
Esborra(); // Esborra LCD
llindar(Polsad); // Funció elegir llindar
__delay_ms(100); // Retard 0,1 s
}
}
} else {
Apaga(); // Apaga matriu LED
Esborra(); // Esborra LCD
}
}
}
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 escriuValor(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 (char 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
if (Digits[1] == '0') { // I mirem si ho és el quart
Digits[1] = ' '; // Si ho és, hi posem un espai
} // El 0 de les unitats el mostrarem sempre
}
}
}
for (signed char k = 3; k >= 0; k--){ // Només escrivim quatre valors
EnviaL(Digits[k]); // Escriu un dígit a la pantalla
}
}
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 led(void){
Apaga();
for (char k = 0; k < 8; k++){
Sortida[1] = k+1; // Filera
Sortida[3] = k+1;
Sortida[5] = k+1;
if (SOint < lind){
n=0;
Sortida[0] = fig[0][k]; // Vermells
Sortida[2] = fig[1][k]; // Verds
Sortida[4] = fig[2][k]; // Blaus
Envia3max(Sortida); // Ho envia al MAX7221
__delay_ms(1); // Retard 1 ms
}
if (SOint >= lind){
n=1;
Sortida[0] = fig[3][k]; // Vermells
Sortida[2] = fig[4][k]; // Verds
Sortida[4] = fig[5][k]; // Blaus
Envia3max(Sortida); // Ho envia al MAX7221
__delay_ms(1); // Retard 1 ms
}
}
}
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 (signed char j = 5; j >= 0; j--){ // Hem d'enviar 6 bytes
for (char 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 Apaga(void) { // Apaga tots els LED
char Bytes[6]; // Els sis bytes que cal enviar
for (char 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) {
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
ANSEL = 0b00000101; // Configura AN0 i AN2 com entrada analògica
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 = 0b01100000; // 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 = 0b01000000; // Posem RC5 (sortida del PWM) com a sortida
__delay_ms(200); // Retard de 0,2 s
TRISC = 0b01100000; // Posem RC5 (sortida del PWM) com a entrada
// O sigui, silenci
__delay_ms(200); // Retard de 0,2 s
}
int Sqrt(unsigned long x){ // Funció calcular sqrt
if (x == 0 || x == 1) // Cas base
return x;
int start = 1, ans; // Do Binary Search for floor(sqrt(x))
unsigned long end = x;
while (start <= end){
unsigned long mid = (start + end) / 2;
if (mid*mid == x) // If x is a perfect square
return mid;
if (mid*mid < x){ // Since we need floor, we update answer when mid*mid is
// smaller than x, and move closer to sqrt(x)
start = mid + 1;
ans = mid;
} else // If mid*mid is greater than x
end = mid-1;
}
return ans;
}
void llindar(char Pols){ // Funció canviar llindar
if (Pols == 3){
j = j+1;
j = j%3;
__delay_ms(50);
}
if (Pols == 4){
lind-=pas[j];
__delay_ms(50);
}
if (Pols == 5){
lind+=pas[j];
__delay_ms(50);
}
Cursor(1,1); // Posa cursor
EnviaL('L'); // Lletra
EnviaL('i'); // Lletra
EnviaL('n'); // Lletra
EnviaL('d'); // Lletra
EnviaL('a'); // Lletra
EnviaL('r'); // Lletra
EnviaL(':'); // Lletra
escriuValor(lind); // Escriu linia de resultats
Cursor(2,1); // Posa cursor
EnviaL('P'); // Lletra
EnviaL('a'); // Lletra
EnviaL('s'); // Lletra
EnviaL(':'); // Lletra
escriuValor(pas[j]); // Escriu linia de resultats
}

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