Programació en C del PIC 16F690 amb PICkit 2

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

Generació de valors aleatoris

Per a la generació de números aleatoris podem fer servir la funció rand (que està a la llibreria stdlib.h) que dóna 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, 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()
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, 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()
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 dóna 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, 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 Polsador   PORTAbits.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ó
	}
}

 

 

Licencia de Creative Commons
Esta obra de Oriol Boix está licenciada bajo una licencia no importada Creative Commons Reconocimiento-NoComercial-SinObraDerivada 3.0.