En aquest exemple comptarem cada cop que es prem el polsador però el valor que mostrarem als LED no serà el de la variable Posicio (que seria en binari natural) sinó binari Gray. El codi binari Gray es caracteritza pel fet que entre dos nombres consecutius sempre només canvia un bit i els altres romanen igual. En canvi en binari natural (el que hem vist a format de les dades) hi ha posicions en les que només en canvia un i altres en les que canvien tots. La següent taula ens mostra els dos codis per a nombres de quatre bits:
| Valor decimal |
Binari natural |
Binari Gray |
Valor decimal |
Binari natural |
Binari Gray |
|
| 0 | 0000 | 0000 | 8 | 1000 | 1100 | |
| 1 | 0001 | 0001 | 9 | 1001 | 1101 | |
| 2 | 0010 | 0011 | 10 | 1010 | 1111 | |
| 3 | 0011 | 0010 | 11 | 1011 | 1110 | |
| 4 | 0100 | 0110 | 12 | 1100 | 1010 | |
| 5 | 0101 | 0111 | 13 | 1101 | 1011 | |
| 6 | 0110 | 0101 | 14 | 1110 | 1001 | |
| 7 | 0111 | 0100 | 15 | 1111 | 1000 |
En aquest cas, a diferència de l'exemple EP, guardarem els 16 codis Gray a la memòria EEPROM des del propi programa. El programa esperarà que premem el polsador. Quan el premem llegirà un valor de l'EEPROM i el copiarà sobre els LED. Si tornem a prémer el polsador en llegirà un altre i així fins que hagi copiat els 16 valors sobre els LED. Després tornarà a començar.
#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 necessari per al compilador XC8 #define Polsador RA3 // Li assigna un nom a l'adreça del polsador
unsigned char Posicio; // Variable de 8 bits per a l'adreça
// Definició de les funcions que farem servir unsigned char llegir_EEPROM(unsigned char adre); // Llegeix el contingut de l'EEPROM // a la posició indicada per l'adreça void escriu_EEPROM(unsigned char adre, unsigned char dada); // Escriu el valor donat a l'adreça EEPROM indicada
void main (void){
TRISC = 0b00000000; // Posa el port C com a sortida
TRISA = 0b00001000; // Posa RA3 com a entrada
escriu_EEPROM(0, 0b00000000); // Escriu el primer valor
escriu_EEPROM(1, 0b00000001); // i el segon...
escriu_EEPROM(2, 0b00000011);
escriu_EEPROM(3, 0b00000010);
escriu_EEPROM(4, 0b00000110);
escriu_EEPROM(5, 0b00000111);
escriu_EEPROM(6, 0b00000101);
escriu_EEPROM(7, 0b00000100);
escriu_EEPROM(8, 0b00001100);
escriu_EEPROM(9, 0b00001101);
escriu_EEPROM(10, 0b00001111);
escriu_EEPROM(11, 0b00001110);
escriu_EEPROM(12, 0b00001010);
escriu_EEPROM(13, 0b00001011);
escriu_EEPROM(14, 0b00001001);
escriu_EEPROM(15, 0b00001000); // Escriu el 16è valor
Posicio = 0; // Comencem a la posició 0
while (1) { // Bucle infinit
while(Polsador == 1) // Esperem a que el polsador es premi
; // No fem res
PORTC = llegir_EEPROM(Posicio++); // llegeix EEPROM, ho posa als LED i incrementa
if (Posicio == 16)
Posicio = 0; // Quan haguem fet els 16, tornem a començar
while(Polsador == 0) // Esperem a que el polsador es deixi anar
; // No fem res
_delay(20000); // Retard per evitar rebots
}
}
unsigned char llegir_EEPROM(unsigned char adre) {
// Llegeix el contingut de l'EEPROM
// a la posició indicada per l'adreça
EECON1bits.EEPGD = 0; // Seleccionem EEPROM i no memòria de programa
EEADR = adre; // Adreça que volem llegir
EECON1bits.RD = 1; // Activa la lectura
return EEDATA; // Llegeix i retorna el resultat
}
void escriu_EEPROM(unsigned char adre, unsigned char dada) {
// Escriu el valor donat a l'adreça EEPROM indicada
EECON1bits.EEPGD = 0; // Seleccionem EEPROM i no memòria de programa
EEDATA = dada; // Valor que volem escriure
EEADR = adre; // Adreça que volem escriure
EECON1bits.WREN = 1; // Habilita l'escriptura
INTCONbits.GIE = 0; // Desactiva interrupcions
EECON2 = 0x55; // Cal escriure uns valors predeterminats (55h i AAh)
EECON2 = 0xAA; // a EECON2 per activar el procés d'escriptura
EECON1bits.WR = 1; // Activa l'escriptura
while (EECON1bits.WR == 1) // Esperem a que l'escriptura acabi
;
EECON1bits.WREN = 0; // Deshabilitem l'escriptura
INTCONbits.GIE = 1; // Reactivem interrupcions
}

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