En aquest cas el marcador anava destinat al futbol americà. La funció dels LED és:
| 1 | 2 | 3 | 4 | Significat |
| X | X | X | X | Escalfament |
| X | Primer quart | |||
| X | Segon quart | |||
| X | Tercer quart | |||
| X | Darrer quart |
La funció dels polsadors és la següent:
| Polsador | Funció |
| 0 | Canvi de part |
| 1 | Fa sonar l'himne |
| 2 | Selecciona l'equip |
| 3 | Suma un punt |
| 4 | Suma dos punts |
| 5 | Suma sis punts |
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 Polsador6 RA3 // Li assigna un nom a l'adreça del polsador de dalt #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
char Polsad; // Polsador que s'ha premut
unsigned char Valor; // Variable de 8 bits sense signe (0 a 255), pels LED
char Sortida[6]; // Valors a enviar al MAX7221 (48 bits)
char Actiu; // Variable que diu quin color està actiu
// Actiu = 0 Apagat
// Actiu = 1 Vermell
// Actiu = 2 Verd
// Actiu = 3 Blau
unsigned char Compta; // Variable de 8 bits sense signe (0 a 255)
unsigned char Compta2; // Variable de 8 bits sense signe (0 a 255)
char nom[10] = {'0','1','2','3','4','5','6','7','8','9'};
// Imatge logotip NFL
char verms1[8] = {0b11110000, 0b11110110, 0b11110110, 0b11111100,
0b00011100, 0b01111111, 0b01111111, 0b0000111};
char verds1[8] = {0b01100000, 0b00100110, 0b01000110, 0b01100000,
0b00000100, 0b01101011, 0b01101011, 0b00000000};
char blaus1[8] = {0b01101111, 0b00101111, 0b01001111, 0b01100011,
0b11100111, 0b11101011, 0b11101011, 0b11111000};
// Imatge del número 1
char verms2[8] = {0b00000000, 0b00000000, 0b00000000, 0b00000000,
0b00000000, 0b00000000, 0b00000000, 0b00000000};
char verds2[8] = {0b00011000, 0b00111000, 0b01111000, 0b11111000,
0b00011000, 0b00011000, 0b00011000, 0b00011000};
char blaus2[8] = {0b00000000, 0b00000000, 0b00000000, 0b00000000,
0b00000000, 0b00000000, 0b00000000, 0b00000000};
// Imatge del número 2
char verms3[8] = {0b00000000, 0b00000000, 0b00000000, 0b00000000,
0b00000000, 0b00000000, 0b00000000, 0b00000000};
char verds3[8] = {0b00000000, 0b01111000, 0b00000100, 0b00000100,
0b00111000, 0b01000000, 0b01111100, 0b00000000};
char blaus3[8] = {0b00000000, 0b00000000, 0b00000000, 0b00000000,
0b00000000, 0b00000000, 0b00000000, 0b00000000};
// Imatge del número 6
char verms4[8] = {0b00000000, 0b00000000, 0b00000000, 0b00000000,
0b00000000, 0b00000000, 0b00000000, 0b00000000};
char verds4[8] = {0b00000000, 0b00111100, 0b01000000, 0b01000000,
0b01111100, 0b01000100, 0b01111100, 0b00000000};
char blaus4[8] = {0b00000000, 0b00000000, 0b00000000, 0b00000000,
0b00000000, 0b00000000, 0b00000000, 0b00000000};
// Definició de les funcions que farem servir 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) char Polsador(void); // Funció de lectura dels polsadors void Envia3max(char Val[]); // Envia un joc de valors als tres MAX7221 desactivant interrupcions void Envia_max(char Valor2[]); // Envia un joc de valors als tres MAX7221 void Ini3max(void); // Inicialitza els tres MAX7221 void Apaga(void); // Apaga tots els LED void TocaNota(char ValPR2, char ValCCPR1L, char ValDC1B);
void main (void) {
// PANTALLA
ANSEL = 0b00000101; // Configura AN0 i AN2 com entrada analògica
ANSELH = 0; // Desactiva les altres entrades analògiques
TRISC = 0b00100000; // Configuració del port C
TRISB = 0; // Tot el port B és de sortida
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
// POLSADORS DE BAIX
TRISA = 0xFF; // Tot el port A és d'entrada
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
// MATRIU LED
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)
PORTC = 0; // Inicialitza a 0 el port C
PORTB = 0; // Inicialitza a 0 el port B
Ini3max(); // Inicialitza els tres MAX7221
Actiu = 1; // Activa el color vermell
TMR0 = 139; // Presselecció de 139, que són 117 iteracions
// Correspon a una interrupció cada 7,5 ms
INTCON = 0b01100000; // Activem PEIE, T0IE
// TEMPS
Compta = 0; // Inicialitzem a 0 el nombre de cops que ha acabat el Timer 1
Compta2 = 0; // Inicialitzem a 0 el nombre de cops que ha acabat el Timer 1
// Configuració d'entrades i sortides
// Configuració del Timer 1
FiTimer1 = 0; // Aquest bit es posarà a 1 quan el temporitzador acabi
// cal desactivar-lo des del programa
T1CON = 0b00110001; // Configuració de Timer1
// Com a temporitzador basat en rellotge
// 11 - Factor d'escala de 8
// I resistències de pull-up desactivades (valor per defecte)
TMR1 = 3036; // Inicialitza el Timer1
PIE1 = 0b00000001; // Habilitem la interrupció per Timer1
INTCONbits.GIE = 1; // Habilitem les interrupcions a nivell general
// BRUNZIDOR
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
// PANTALLA
Esborra(); // Esborra la pantalla i posa el cursor a l'inici
EnviaL('K');
EnviaL('C');
Cursor(2,1);
EnviaL('S');
EnviaL('F');
Cursor(1, 4);
EnviaL(nom[0]);
EnviaL(nom[0]);
Cursor(2,4);
EnviaL(nom[0]);
EnviaL(nom[0]);
Cursor(1,6);
EnviaL('*');
Cursor(1,12);
EnviaL(nom[0]);
EnviaL(nom[0]);
EnviaL(':');
EnviaL(nom[1]);
EnviaL(nom[0]);
// VARIABLES PANTALLA+POLSADOR
int a = 0; // Fa referència a les desenes de punts de la 2a fila
int b = 0; // Fa referència a les desenes de punts de la 1a fila
int x = 0; // Fa referència a les unitats de punts de la 2a fila
int y = 0; // Fa referència a les unitats de punts de la 1a fila
int c1 = 1; // Fa referència a quina fila es sumaran els punts.
// Val 1 per a la 1a fila i 2 per a la 2a
// VARIABLE POLSADOR DE DALT
Valor = 0; // Fa referència a quin/quins LED s'encenen.
// Inicialment el posem a 0 (cap LED encès)
// MATRIU LEDS
Apaga(); // Apaga tots els LED
// VARIABLES TEMPS
char r = 0; // Fa referència a les desenes de minut
char s = 0; // Fa referència a les unitats de minut
char t = 1; // Fa referència a les desenes de segon
char u = 0; // Fa referència a les unitats de minut
// VARIABLE LOGO NFL
char nfl = 1; // Fa referència a si es projecta el logotip
// de la NFL a la matriu LED o no.
// Quan val 1 apareix el logotip, quant val 0 apareix
// la imatge del número 1, 2 o 6,
// depenent de quin polsador s'ha premut
__delay_ms(100); // Delay per garantir un bon funcionament
while (1) { // Mentre el contingut del parèntesi sigui 1
// POLSADORS BAIX
Polsad = Polsador(); // Llegim els polsadors
if (Polsad == 5) { // Si s'ha premut el polsador 5
// Fem apareixer el número 6 a la matriu LED
nfl = 0; // No apareix el logotip a la matriu LED
Compta2 = 0; // Inicialitzem a 0 el nombre de cops que acabarà el Timer1
for (int k = 0; k < 8; k++){
Sortida[1] = k+1; // Filera 1
Sortida[3] = k+1;
Sortida[5] = k+1;
Sortida[0] = verms4[k]; // Vermells
Sortida[2] = verds4[k]; // Verds
Sortida[4] = blaus4[k]; // Blaus
Envia3max(Sortida); // Ho envia al MAX7221
__delay_ms(1);
}
// Control dels punts
if (c1 == 1) {
y = y+6;
if (y >= 10) {
y = y-10;
b = b+1;
if (b == 10) {
b = 0;
y = 0;
}
}
Cursor(c1,5);
EnviaL(nom[y]);
Cursor(c1,4);
EnviaL(nom[b]);
} else {
x = x+6;
if (x >= 10) {
x = x-10;
a = a+1;
if (a == 10) {
a = 0;
x = 0;
}
}
Cursor(c1,5);
EnviaL(nom[x]);
Cursor(c1,4);
EnviaL(nom[a]);
}
_delay(100000);
}
if (Polsad == 4) { // Si s'ha premut el polsador 4
nfl = 0; // No apareix el logotip a la matriu LED
Compta2 = 0; // Inicialitzem a 0 el nombre de cops que acabarà el Timer1
// Fem apareixer un 2 a la matriu LED
for (int k = 0; k < 8; k++){
Sortida[1] = k+1; // Filera 1
Sortida[3] = k+1;
Sortida[5] = k+1;
Sortida[0] = verms3[k]; // Vermells
Sortida[2] = verds3[k]; // Verds
Sortida[4] = blaus3[k]; // Blaus
Envia3max(Sortida); // Ho envia al MAX7221
__delay_ms(1);
}
// Control dels punts
if (c1 == 1) {
y = y+2;
if (y >= 10) {
y = y-10;
b = b+1;
if (b == 10) {
b = 0;
y = 0;
}
}
Cursor(c1,5);
EnviaL(nom[y]);
Cursor(c1,4);
EnviaL(nom[b]);
} else {
x = x+2;
if (x >= 10) {
x = x-10;
a = a+1;
if (a == 10) {
a = 0;
x = 0;
}
}
Cursor(c1,5);
EnviaL(nom[x]);
Cursor(c1,4);
EnviaL(nom[a]);
}
_delay(100000);
}
if (Polsad == 3) { // Si s'ha premut el polsador 3
nfl = 0; // No apareix el logotip a la matriu LED
Compta2 = 0; // Inicialitzem a 0 el nombre de cops que acabarà el Timer1
// Fem apareixer un 1 a la matriu LED
for (int k = 0; k < 8; k++){
Sortida[1] = k+1; // Filera 1
Sortida[3] = k+1;
Sortida[5] = k+1;
Sortida[0] = verms2[k]; // Vermells
Sortida[2] = verds2[k]; // Verds
Sortida[4] = blaus2[k]; // Blaus
Envia3max(Sortida); // Ho envia al MAX7221
__delay_ms(1);
}
// Control dels punts
if (c1 == 1) {
y = y+1;
if (y >= 10) {
y = y-10;
b = b+1;
if (b == 10) {
b = 0;
y = 0;
}
}
Cursor(c1,5);
EnviaL(nom[y]);
Cursor(c1,4);
EnviaL(nom[b]);
} else {
x = x+1;
if (x >= 10) {
x = x-10;
a = a+1;
if (a == 10) {
a = 0;
x = 0;
}
}
Cursor(c1,5);
EnviaL(nom[x]);
Cursor(c1,4);
EnviaL(nom[a]);
}
_delay(100000);
}
if (Polsad == 2) { // Si s'ha premut el polsador 2
// Control de la fila on apareix l'asterisc
// que marca a quin equip es sumaran els punts
if (c1 == 1){
c1 = 2;
Cursor(1,6);
EnviaL(' ');
Cursor(2,6);
EnviaL('*');
} else {
c1 = 1;
Cursor(2,6);
EnviaL(' ');
Cursor(1,6);
EnviaL('*');
}
_delay(100000);
}
if (Polsad == 1) { // Si s'ha premut el polsador 1
}
if (Polsad == 0) { // Si no s'ha premut cap polsador (o dos a la vegada)
}
if (Compta2 == 4) { // Quan han passat 2 segons, deixa d'aparèixer
// la imatge del número 1, 2 o 6
// i torna a aparèixer el logotip
nfl = 1;
}
// POLSADOR DE DALT
if (Polsador6 == 0) {
if (Valor == 1 || Valor == 15) // Si ja estem al LED 1, no podem rodar més
Valor = 8; // tornem al LED 4
else // Si no estem al LED 1
Valor = Valor/2; // Dividim per 2 i passem al LED següent
PORTC = Valor;
// Reinciem el temps a 15 minuts
r = 1;
s = 5;
t = 0;
u = 1;
}
while (Polsador6 == 0) // Mentre el polsador estigui premut
; // No fa res
// MATRIU LED
// Logotip NFL
if (nfl == 1) {
for (int k = 0; k < 8; k++){
Sortida[1] = k+1; // Filera 1
Sortida[3] = k+1;
Sortida[5] = k+1;
Sortida[0] = verms1[k]; // Vermells
Sortida[2] = verds1[k]; // Verds
Sortida[4] = blaus1[k]; // Blaus
Envia3max(Sortida); // Ho envia al MAX7221
__delay_ms(1);
}
}
// TEMPS
// Control de les desenes i unitats de minut i de segon
if (Compta == 2) { // Si ha acabat vint vegades
if (u == 0) {
if (t == 0) {
if (s == 0) {
if (r == 0) {
r = 0;
u = 0;
t = 0;
s = 0;
} else {
u = 9;
t = 5;
s = 9;
r = r-1;
}
} else {
s = s-1;
u = 9;
t = 5;
}
} else {
t = t-1;
u = 9;
}
} else {
u = u-1;
}
Cursor(1,16);
EnviaL(nom[u]);
Cursor(1,15);
EnviaL(nom[t]);
Cursor(1,13);
EnviaL(nom[s]);
Cursor(1,12);
EnviaL(nom[r]);
Compta = 0; // Reinicialitza Compta
}
// HIMNE
if (Valor == 0 && r == 0 && s == 0 && t == 0 && u == 0) {
// Si no hi ha cap LED encès i el temps està a 0
Valor = 15;
PORTC = Valor; // Encenem els quatre LED
TocaNota(158, 79, 2); // Valor que correspon aproximadament a mi3
TocaNota(189, 95, 0);
TocaNota(238, 119, 2);
TocaNota(189, 95, 0);
TocaNota(158, 79, 2);
TocaNota(118, 59, 2);
}
}
}
void __interrupt() temporit(void){ // INTERRUPCIONS PEL TIMER0 I TIMER1
INTCONbits.T0IE = 0; // Desactiva les interrupcions momentàniament (del Timer0)
if (PIR1bits.TMR1IF) { // Comprovem que hi ha interrupció per Timer1
FiTimer1 = 0; // Tornem a posar el bit a zero
TMR1 = 3036; // Inicialitza el Timer1
Compta++; // Incrementa Compta
Compta2++; // Incrementa Compta2
}
INTCONbits.T0IE = 1; // Reactiva les interrupcions a l'acabar (del Timer0)
if (INTCONbits.T0IF) { // Comprovem que hi ha interrupció per Timer 0
TMR0 = 139; // 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(Sortida); // Ho envia al MAX7221
}
}
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
}
// FUNCIÓ POLSADORS BAIX
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 Envia3max(char Val[]) { // Envia un joc de valors als tres MAX7221
INTCONbits.T0IE = 0; // Desactiva les interrupcions momentàniament (del Timer 0)
Envia_max(Val);
INTCONbits.T0IE = 1; // Reactiva les interrupcions a l'acabar (del Timer 0)
}
void Envia_max(char Valor2[]) { // Envia un joc de valors als tres MAX7221
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 = Valor2[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)
}
Valor2[j] = Valor2[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
}
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;
Envia_max(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;
Envia_max(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;
Envia_max(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
}
}
// FUNCIÓ BRUNZIDOR
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(102); // Retard de 0,102 s
TRISC = 0b00100000; // Posem RC5 (sortida del PWM) com a entrada
// O sigui, silenci
__delay_ms(10); // Retard de 0,01 s
}

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