Codigo:
/******************* 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.
}
Codigo:
/******************* SIMON *********************
* *
* By Biot *
* 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 <16F84A.h>
#use delay(clock=4000000)
#fuses XT,NOWDT,NOPUT
#use fast_io(A)
#use fast_io(B)
/****************************************
* 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((RB4|RB5|RB6|RB7)== 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)
{
PORTA = 0;
nivel = 1;
antirebote();
output_high(PIN_A0); // Nivel 1 - > led rojo encendido
}else if(!RB5) {
PORTA = 0;
nivel = 2;
antirebote();
output_high(PIN_A1); // Nivel 2 - > led verde encendido
}else if(!RB6) {
PORTA = 0;
nivel = 3;
antirebote();
output_high(PIN_A2); // Nivel 3 - > led amarillo encendido
}else if(!RB7) {
PORTA = 0;
nivel = 4;
antirebote();
output_high(PIN_A3); // Nivel 4 - > led azul encendido
}
}
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(!RB4) // Se ha pulsado el rojo,salimos del bucle
{
color_pulsado = 1;
sal = true;
}else if(!RB5) { // Se ha pulsado el verde,salimos del bucle
color_pulsado = 2;
sal = true;
}else if(!RB6) { // Se ha pulsado el amarillo,salimos del bucle
color_pulsado = 3;
sal = true;
}else if(!RB7) { // 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
port_b_pullups(TRUE);
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.
}
Codigo:
// P4_2_2.C
#include <16f84a.h> // Se incluye el fichero 16f84a.h con definiciones
// de bits y registros del PIC 16f84a
#use delay(clock=4000000,RESTART_WDT)
#use fast_io(A)
#use fast_io(B)
#byte port_b = 6 // Variable port_b en dirección 0x06 (PORTB)
main()
{
port_b = 0; // Salida a cero
set_tris_a(0x1F); // Programación del PORTA como entradas
set_tris_b(0x00); // Programación del PORTB como salidas
while (1)
{
do
{
restart_wdt(); // Puesta a cero del temporizador watchdog
}
while (input(PIN_A0)); // Si p=1 no salir del bucle do-while
delay_ms(20); // Antirebotes
do
{
restart_wdt(); // Puesta a cero del temporizador watchdog
}
while (!input(PIN_A0)); // Si p=0 no salir del bucle do-while
delay_ms(20); // Antirebotes
output_bit (PIN_B0,!input(PIN_B0)); // B = !B
}
}
Codigo:
void desplazar_display(int posiciones, boolean sentido)
{
// Primer parámetro: Numero de desplazamientos
// Segundo parámetro: Sentido del desplazamiento (TRUE=Derecha, FALSE=Izquierda)
int i,aux;
if (sentido)
{
aux=0b00011000; // Desplazamiento a la derecha
}else {
aux=0b00011100;
}
for (i=1; i<=posiciones; i++)
{
lcd_send_byte(0,aux);
}
}
Aqui va el primer ejemplo de las rutinas, esta vez se trata de la rutina NumGran, que muestra un numero enviado al LCD en numeros que abarcan las dos lineas de un LCD de 2 x 16 caracteres, el mas utilizado de todos...
Envio mi agradecimiento por empujarme al C y especialmente a traducir este ejemplo a Ariel PIKMAN, quien me impulso fuertemente al ponerme el desafio de traducir esta rutina que habia puesto en el foro de PBP.<img border="0" width="31" height="31" src="http://pics.miarroba.com/caretos/bounce.gif"><img border="0" width="31" height="31" src="http://pics.miarroba.com/caretos/bounce.gif">
Puse dos ejemplos de su utilizacion <a href="http://miarroba.com/foros/ver.php?foroid=256746&temaid=1539858&msgid=12424363" target="_blank">AQUI [/url], una es un simple contador, igual al ejemplo en PBP, el otro ejemplo ya muestra como mostrar el resultado del conversor A/D en numeros grandes en el LCD.
Espero lo disfruten y les sirva, es de uso libre.<img border="0" width="15" height="15" src="http://pics.miarroba.com/caretos/biggrin.gif"><img border="0" width="15" height="15" src="http://pics.miarroba.com/caretos/biggrin.gif">