Per a la generació de números aleatoris podem fer servir la funció rand (que està a la biblioteca stdlib.h) que dona resultats de 16 bits. En el programa següent generem, a cada cicle, un valor aleatori i en mostrem els quatre bits menys significatius als LED.
#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 #include <stdlib.h> // Carrega el fitxer on hi ha la funció rand()
unsigned char Leds; // Variable de 8 bits sense signe (0 a 255)
void main (void) {
TRISC = 0b00000000; // El port C és de sortida
PORTC = 0; // Apaga els LED
while (1) { // Bucle infinit
Leds = rand() & 0x000F; // Conservem només els quatre bits de menys pes
PORTC = Leds; // Copiem el valor al port (als LED)
_delay(2000000); // Retard per permetre la visualització
}
}
Si provem el programa, hauríem d'obtenir una seqüència que pot semblar aleatòria però que és la mateixa cada cop que tornem a posar en marxa el microcontrolador. Això passa perquè aquesta funció el que fa és generar nombres pseudoaleatoris. Per aconseguir millors resultats, cal definir una llavor que sigui diferent cada vegada, així la seqüència serà diferent cada cop. Per a definir la llavor, farem servir la funció srand a la qual li haurem de posar com a paràmetre un valor que sigui diferent cada cop. El següent programa agafa com a llavor el valor de TMR0 que sempre està variant.
#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 #include <stdlib.h> // Carrega el fitxer on hi ha la funció rand()
unsigned char Leds; // Variable de 8 bits sense signe (0 a 255)
void main (void) {
TRISC = 0b00000000; // El port C és de sortida
OPTION_REG = 0b10000000; // Configuració de Timer0
// Com a temporitzador basat en rellotge
// 000 - Factor d'escala de 2
// I resistències de pull-up desactivades (valor per defecte)
PORTC = 0; // Apaga els LED
srand(TMR0); // Agafa una llavor
while (1) { // Bucle infinit
Leds = rand() & 0x000F; // Conservem només els quatre bits de menys pes
PORTC = Leds; // Copiem el valor al port (als LED)
_delay(2000000); // Retard per permetre la visualització
}
}
Aquest programa va bé si reprogramem el microcontrolador sense desconnectar-lo. Però si desconnectem el microcontrolador i el tornem a connectar és probable que la seqüència es repeteixi. El motiu és que el temps que triga en fer les instruccions prèvies a srand és sempre el mateix o sigui que si l'apago i el torno a engegar, el valor de TMR0 que dóno a srand és sempre igual. En el programa següent afegim un detall que li dona una aleatorietat pràcticament total ja que no es llegirà el valor de TMR0 fins que l'usuari hagi premut el polsador i després l'hagi deixat anar. Hem afegit un retard abans de mirar el polsador ja que el programador (que comparteix pota amb el polsador) pot interferir amb la lectura del polsador durant els primers microsegons.
#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 #include <stdlib.h> // Carrega el fitxer on hi ha la funció rand() #define Polsador RA3 // Li assigna un nom a l'adreça del polsador
unsigned char Leds; // Variable de 8 bits sense signe (0 a 255)
void main (void) {
TRISA = 0b00001000; // Posa RA3 com a entrada
TRISC = 0b00000000; // El port C és de sortida
OPTION_REG = 0b10000000; // Configuració de Timer0
// Com a temporitzador basat en rellotge
// 000 - Factor d'escala de 2
// I resistències de pull-up desactivades (valor per defecte)
PORTC = 0; // Apaga els LED
_delay(2000000); // Retard per evitar problemes al polsador
while (Polsador == 1) // Mentre el polsador no estigui premut
; // No fa res
while (Polsador == 0) // Mentre el polsador estigui premut
; // No fa res
srand(TMR0); // Agafa una llavor
while (1) { // Bucle infinit
Leds = rand() & 0x000F; // Conservem només els quatre bits de menys pes
PORTC = Leds; // Copiem el valor al port (als LED)
_delay(2000000); // Retard per permetre la visualització
}
}

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