Bueno para que no sea todo preguntar y preguntar y pq este foro y su gente es de lo mejor que he encontrado,ahí va una aportación de cosecha propia para el 16f84,el famoso juego de los 4 colores para poner a prueba la memoria.
EEEEEEEEPAAA!!
Vaya,no me deja adjuntar el fichero.Bueno,pos a lo bestia...
/******************* SIMON *********************
* *
* By Yors *
* S.I.T.T.M *
* *
***********************************************/
/******************************** ESPECIFICACIONES *****************************
El dispositivo físico consta de cuatro leds (rojo,verde,amarillo y azul)
conectados a RA0,RA1,RA2 y RA3 (en ese orden),de un altavoz conectado a RB3
y de cinco pulsadores.
Un pulsador está conectado a RB0 (para generar el color aleatorio) y los otros
cuatro,que corresponden a cada uno de los leds,están conectados a RB4,RB5,RB6
y RB7.Tanto los leds como los pulsadores son activos a nivel alto.
*******************************************************************************/
/*******************
* PREPROCESADO *
********************/
#include <16F84.h>
#use delay(clock=4000000)
#use fast_io(A)
#use fast_io(B)
#fuses XT,NOWDT,NOPUT
/****************************************
* DEFINICIÓN DE ETIQUETAS Y VARIABLES *
*****************************************/
#byte PORTA = 0x05 // Puerto A
#byte PORTB = 0x06 // Puerto B y bits utilizados
#bit RB0 = 0x06.0
#bit RB3 = 0x06.3
#bit RB4 = 0x06.4
#bit RB5 = 0x06.5
#bit RB6 = 0x06.6
#bit RB7 = 0x06.7
#byte INTCON = 0x0B
int aleatorio,dir_lectura,dir_escritura,color_leido,leido,color_pulsado,nivel;
short fin_juego;
/***************
* SUBRUTINAS *
****************/
void retardo(int latencia)
{
switch(latencia)
{
case 1: delay_ms(200); // Correspondiente al nivel 1
break;
case 2: delay_ms(100); // Nivel 2
break;
case 3: delay_ms(50); // Nivel 3
break;
case 4: delay_ms(15); // Nivel 4
break;
default:
break;
}
}
void altavoz(int tono) // Para generar un sonido diferente para cada color
{
int i,j;
for(i=0; i<=40; i++)
{
for(j=0; j<=4; j++)
{
output_high(PIN_B3); // La distancia entre pulso y pulso viene determinada
delay_us(300*(6-tono)); // por el parámetro tono
output_low(PIN_B3);
delay_us(300*(6-tono));
}
}
}
void antirebote()
{
delay_ms(30);
while(PORTB != 0) {} // No progresamos hasta que ningún pulsador esté activo
delay_ms(30);
}
void comprueba()
{
leido = read_eeprom(dir_lectura); // Leemos la dirección eeprom correspondiente.
if(leido != color_pulsado) // Si la pulsación no ha sido correcta,acaba el
{ // juego y volvemos al principio del programa
fin_juego = true;
}
}
void enciende_led(int color) // Enciende el led correspondiente
{
switch(color)
{
case 1: output_high(PIN_A0); // Led rojo
break;
case 2: output_high(PIN_A1); // Led verde
break;
case 3: output_high(PIN_A2); // Led amarillo
break;
case 4: output_high(PIN_A3); // Led azul
break;
default: PORTA = 15; // Los 4 leds
break;
}
}
void escoge_nivel() // El led que se mantiene encendido corresponde al nivel elegido
{
nivel = 1;
PORTA = 0;
output_high(PIN_A0); // Por defecto,encendemos el led rojo (nivel 1).
while(!RB0) // El nivel por defecto es el 1.Hasta que pulsemos RB0
{ // podremos seleccionar cualquiera de los 4 niveles
if(RB4)
{
nivel = 1;
PORTA = 0;
output_high(PIN_A0); // Nivel 1 - > led rojo encendido
antirebote();
}else if(RB5) {
nivel = 2;
PORTA = 0;
output_high(PIN_A1); // Nivel 2 - > led verde encendido
antirebote();
}else if(RB6) {
nivel = 3;
PORTA = 0;
output_high(PIN_A2); // Nivel 3 - > led amarillo encendido
antirebote();
}else if(RB7) {
nivel = 4;
PORTA = 0;
output_high(PIN_A3); // Nivel 4 - > led azul encendido
antirebote();
}
}
antirebote();
PORTA = 15; // Una vez hemos escogido nivel,se encienden los 4 leds
delay_ms(1000); // para indicar que podemos empezar a jugar
PORTA = 0;
}
void genera_aleatorio() // Al pulsar RB0 genera un número entre 1 y 4 que se guardará
{ // tal cual en memoria...
aleatorio = 1; // 1 -> Rojo
while(!RB0) // 2 -> Verde
{ // 3 -> Amarillo
if(aleatorio == 4) // 4 -> Azul
{
aleatorio = 1;
}else {
aleatorio++;
}
}
antirebote();
}
void guarda_color()
{
write_eeprom(dir_escritura,aleatorio); // Guardamos el color generado y apuntamos a
dir_escritura++; // la siguiente dirección para una próxima
} // escritura
void has_fallado(int tono) // Si entramos aquí es que hemos pulsado incorrectamente
{
int i,j;
enciende_led(color_pulsado);
for(i=0; i<=100; i++) // Generamos tono de error (más grave)
{
for(j=0; j<=4; j++)
{
output_high(PIN_B3);
delay_ms(1*(6-tono));
output_low(PIN_B3);
delay_ms(1*(6-tono));
}
}
delay_ms(1000);
}
void muestra_colores()
{
// Desde el primero hasta el último que se ha guardado en memoria,los vamos mostrando
// con una rapidez que vendrá determinada por el nivel de dificultad elegido al principio.
for(dir_lectura = 0; dir_lectura < dir_escritura; dir_lectura++)
{
color_leido = read_eeprom(dir_lectura); // Lectura eeprom
enciende_led(color_leido); // Enciende led correspondiente
altavoz(color_leido); // Emite tono
retardo(nivel); // Retardo según nivel de dificultad
PORTA = 0; // Apaga led
retardo(nivel); // Retardo según nivel de dificultad
}
}
void pulsa_secuencia()
{
short sal;
dir_lectura = 0;
// Recogemos las pulsaciones y se va comprobando si son correctas hasta que
// alguna no lo sea o hasta que hayamos acertado todos los colores guardados
// hasta el momento.
// dir_escritura contiene la dirección eeprom siguiente al último color guardado
// y dir_lectura la usamos para ir consultando cada posición de memoria y comprobar
// si la pulsación ha sido correcta.En el momento en que fallemos alguna,fin_juego toma
// el valor TRUE.
while((dir_lectura < dir_escritura) && (!fin_juego))
{
sal = false;
while(!sal) // Mientras no haya pulsación nos mantenemos dentro del bucle
{
if(input(PIN_B4)) // Se ha pulsado el rojo,salimos del bucle
{
color_pulsado = 1;
sal = true;
}else if(input(PIN_B5)) { // Se ha pulsado el verde,salimos del bucle
color_pulsado = 2;
sal = true;
}else if(input(PIN_B6)) { // Se ha pulsado el amarillo,salimos del bucle
color_pulsado = 3;
sal = true;
}else if(input(PIN_B7)) { // Se ha pulsado el azul,salimos del bucle
color_pulsado = 4;
sal = true;
}else { // No se ha pulsado ninguno,continuamos
sal = false; // dentro del bucle
}
}
comprueba(); // Algoritmo que comprueba si la pulsación ha sido correcta
enciende_led(color_pulsado); // Enciende el led del color que hemos pulsado
altavoz(color_pulsado); // Genera el tono del color que hemos pulsado
antirebote(); // No comment
PORTA = 0; // Apagamos led
dir_lectura++; // Para comprobar la siguiente dirección eeprom
}
}
/*********************
* PROGRAMA PRINCIPAL *
**********************/
void main()
{
// Inicialización periféricos
set_tris_B(0b11110001); // RB0,RB4,RB5,RB6 y RB7 entradas --- RB1,RB2 Y RB3 salidas
set_tris_A(0b00000000); // Todo salidas
output_low(PIN_B1); // RB1 no la usamos
output_low(PIN_B2); // RB2 no la usamos
output_low(PIN_B3); // RB3 conectado al altavoz
INTCON=0;
enable_interrupts(INT_EEPROM); // Unica interrupción habilitada durante toda la ejecución
enable_interrupts(GLOBAL); // Habilitador general de interrupciones
// Bucle principal (Se ejecuta de forma indefinida)
for(;
{
dir_escritura = dir_lectura = color_leido = leido = color_pulsado = 0; // Inicializamos variables
fin_juego = false;
escoge_nivel(); // Para escoger entre 4 niveles de dificultad
while(!fin_juego)
{
genera_aleatorio(); // Generamos color
guarda_color(); // Guardamos color en memoria
muestra_colores(); // Mostramos colores guardados hasta el momento
pulsa_secuencia(); // Recogemos pulsaciones
if(!fin_juego) // Cada vez que acertamos una secuencia completa,encendemos
{ // los 4 leds y generamos tres tonos musicales
enciende_led(5); //
altavoz(1); //
altavoz(2); //
altavoz(4); //
PORTA = 0; //
} //
}
has_fallado(4); // Si hemos salido del bucle anterior es porque hemos fallado,de
} // aquí volvemos al principio del bucle principal.
}