Que FUSES estas usando ? Ese PIN unicamente se vuelve RA6 en caso de estar usando cualquiera de estos 3 tipos de oscilador: ECIO, ECPIO and INTIO. El cual INTIO seria el oscilador interno
Por otro lado no entiendo a que te referis con "paso a paso", ¿Podrias hacer una explicacion mas detallada? Por ejemplo:
Los numeros los tomas desde el puerto B en formato binario, al presionar A6 tomas ese dato, y luego cuando presionas de vuelta A6 tenes el otro dato. Algo asi... que se explique el paso a paso.
Perfecto. Respecto al pulsador, seguramente tengas algo mal, Ejemplo FAST_IO se usan los puertos y no los nombres de los pines, ademas tenes siempre la OBLIGACION de setear los FUSES correctos, vos pusiste que tenes un clock de 10Mhz, pero si posees un clock de 10Mhz significa que tenes un cristal puesto. Un cristal te estaria usando el pin de RA6 ya que comparte el mismo pin que para los cristales, por eso mismo si uno quiere usar RA6 debe seleccionar el oscilador interno INTIO, y la frecuencia seguramente sea de 8Mhz.
Te voy a corregir un poco la forma de realizar el programa, para que no exista tanto codigo repetido y se vuelva mas facil de realizarlo/leerlo.
Primero... vamos al Main, estamos intentando resumir todo.. El main propuesto es este:Código: C
void main(void) { int1 verif; int1 valoranteriorverif = 1; int8 estado = 0; int8 valorAmostrar = APAGADO; setup_adc_ports(NO_ANALOGS); set_tris_a(0xFF); set_tris_b(0x00); set_tris_d(0x00); while(true) { verif=input(PIN_A6); if(verif != valoranteriorverif) // Distinto de la ultima ves que paso, y tiene que ser igual a 0 { if(verif == 0) { switch(estado) { case 0: dsw2=input_A()&0b00000111; valorAmostrar = dsw2; estado++; break; case 1: valorAmostrar = SUMA; estado++; break; case 2: dsw1 = (input_a()&0b00111000) >> 3; valorAmostrar = dsw1; estado++; break; case 3: valorAmostrar = IGUAL; estado++; break; case 4: valorAmostrar = dsw1+dsw2; estado++; break; case 5: valorAmostrar = APAGADO; estado = 0; break; } } valoranteriorverif = verif; // Proteccion para que no entre 2 veces } Mostrar(valorAmostrar); } }
Observaras que esto reduce MUCHO la complejidad del codigo, tanto dsw1 como dsw2 van a ser numeros de 0x0 a 0x7, ya que le hicimos una rotacion, y siempre le pasamos el valor que queremos mostrar a la funcion "Mostrar"
Ahora.. ¿como es que seleccionamos de esa funcion cual es nuestro valor?, bueno aca necesitamos de declarar mejor el array, no tenerlos en array independientes. Voy a hacerlo de esta forma:Código: C
#DEFINE MATMOV 16 #DEFINE SUMA 17 #DEFINE IGUAL 18 #DEFINE APAGADO 19 const int NumerosMatriz[20][8]= { {0b00000000,0b00111100,0b01111110,0b11000011,0b11000011,0b01111110,0b00111100,0b00000000}, // Numero 0 {0b00000000,0b11000000,0b11000000,0b11111111,0b11111111,0b11001110,0b11001000,0b00000000}, // Numero 1 {0b00000000,0b00000000,0b11111110,0b11111110,0b11110110,0b11110110,0b00000000,0b00000000}, // Numero 2 {0b00000000,0b11111111,0b11111111,0b11011011,0b11011011,0b11011011,0b11011011,0b00000000}, // Numero 3 {}, // Numero 4 {}, // Numero 5 {}, // Numero 6 {}, // Numero 7 {}, // Numero 8 {}, // Numero 9 {}, // Numero A {}, // Numero B {}, // Numero C {}, // Numero D {}, // Numero E {}, // Numero F {0b00000001,0b00000010,0b00000100,0b00001000,0b00010000,0b00100000,0b01000000,0b10000000}, // Matriz Movimiento {0b00011000,0b00011000,0b00011000,0b11111111,0b11111111,0b00011000,0b00011000,0b00011000}, // Signo Suma {0b01100110,0b01100110,0b01100110,0b01100110,0b01100110,0b01100110,0b01100110,0b01100110}, // Signo igual {0b00000000,0b00000000,0b00000000,0b00000000,0b00000000,0b00000000,0b00000000,0b00000000} // APAGADO };
Observaras que si yo le paso un 0 para mostrar, deberia utilizar el array NumerosMatriz[0][8], si le paso una 0xA, deberia usar: NumerosMatriz[0xA][8], el problema esta tambien en los signos.
Puede que CCS te de error el "identado" que propuse, pero deberia esta bien el array. No puse los valores de los demas numeros, eso te lo dejo a vos... Observa que arriba use unos DEFINE con el numero de indice de cada signo especial. Mientras que cualquier numero que se pase, va a ser el indice correcto. Ahora la funcion va a ser MUCHO mas simple que antes:Código: C
void Mostrar(int8 valor) { for(k=0;k<8;k++) { output_B(NumeroMatriz[valor][k]); output_D(NumeroMatriz[MATMOV][k]); delay_ms(5); } set_tris_D(0); }
Solo modifique tu funcion, asi que puede tener sus defectos. Personalmente lo haria con un Timer/interrupción para actualizar el estado. Y entonces tu programa solo se preocupa en actualizar un solo valor. Es decir la interrupcion que ocurra cada 5ms por ejemplo, y que active un comun, y ponga el dato que corresponde solo. Eso va a estar marchando automaticamente y siempre. Nosotros unicamente vamos a actualizar el valor a mostrar y luego la interrupcion se va a encargar de todo lo demas.
En fin... Ese es todo tu programa... falta agregarle los FUSES correctos, como te decia necesitas ponerlo como INTIO para usar RA6.Código: C
#include <C:\Program Files\PICC\Devices\18F4550.h> #use delay (clock=1000000) #use fast_io(A) #use fast_io(B) #use fast_io(D) int dsw2=0,dsw1=0, resulta; // j es el contador global, k es la variable que controlara el movimiento de las matriz //------------------------------------------------------------------------------------------ // combinacion de numeros y letras de matriz #DEFINE MATMOV 16 #DEFINE SUMA 17 #DEFINE IGUAL 18 #DEFINE APAGADO 19 const int NumerosMatriz[20][8]= { {0b00000000,0b00111100,0b01111110,0b11000011,0b11000011,0b01111110,0b00111100,0b00000000}, // Numero 0 {0b00000000,0b11000000,0b11000000,0b11111111,0b11111111,0b11001110,0b11001000,0b00000000}, // Numero 1 {0b00000000,0b00000000,0b11111110,0b11111110,0b11110110,0b11110110,0b00000000,0b00000000}, // Numero 2 {0b00000000,0b11111111,0b11111111,0b11011011,0b11011011,0b11011011,0b11011011,0b00000000}, // Numero 3 {}, // Numero 4 {}, // Numero 5 {}, // Numero 6 {}, // Numero 7 {}, // Numero 8 {}, // Numero 9 {}, // Numero A {}, // Numero B {}, // Numero C {}, // Numero D {}, // Numero E {}, // Numero F {0b00000001,0b00000010,0b00000100,0b00001000,0b00010000,0b00100000,0b01000000,0b10000000}, // Matriz Movimiento {0b00011000,0b00011000,0b00011000,0b11111111,0b11111111,0b00011000,0b00011000,0b00011000}, // Signo Suma {0b01100110,0b01100110,0b01100110,0b01100110,0b01100110,0b01100110,0b01100110,0b01100110}, // Signo igual {0b00000000,0b00000000,0b00000000,0b00000000,0b00000000,0b00000000,0b00000000,0b00000000} // APAGADO }; void Mostrar(int8 valor) { for(k=0;k<8;k++) { output_B(NumeroMatriz[valor][k]); output_D(NumeroMatriz[MATMOV][k]); delay_ms(5); } set_tris_D(0); } void main(void) { int1 verif; int1 valoranteriorverif = 1; int8 estado = 0; int8 valorAmostrar = APAGADO; setup_adc_ports(NO_ANALOGS); set_tris_a(0xFF); set_tris_b(0x00); set_tris_d(0x00); while(true) { verif=input(PIN_A6); if(verif != valoranteriorverif) // Distinto de la ultima ves que paso, y tiene que ser igual a 0 { if(verif == 0) { switch(estado) { case 0: dsw2=input_A()&0b00000111; valorAmostrar = dsw2; estado++; break; case 1: valorAmostrar = SUMA; estado++; break; case 2: dsw1 = (input_a()&0b00111000) >> 3; valorAmostrar = dsw1; estado++; break; case 3: valorAmostrar = IGUAL; estado++; break; case 4: valorAmostrar = dsw1+dsw2; estado++; break; case 5: valorAmostrar = APAGADO; estado = 0; break; } } valoranteriorverif = verif; // Proteccion para que no entre 2 veces } Mostrar(valorAmostrar); } }
PD: los delays estan fuera de escala por eso quite bastante. Especialmente cuando mostrabas, ya que eran 2 segundos!!! 50 * 8 * 5ms, en que tu programa NO respondia a nada, debido a que estaba mostrando en el display
A pesar de que optimizaste al máximo el código tome solo estos detalles y los otros los guardare para posibles ideas, ya que, se nota que mi nivel de programación es algo(por no decir muy muy :oops: ) bajo y se que para ser el primer proyecto en pic, se tengas errores de esta clase.
Tengo una duda en esta lectura input_A()&0b00111000) >> 3; No entiendo muy bien el porque ">>3" Se debe a la posición de la lectura ya que los puertos van del RA0 al RA6, y como estoy entrando un dato binario y usando mascara para leer justamente eso el dato no se lee bien, es como por decir una corrección de la lectura, pero hasta hay se.
Otra duda es saber si existe un forma de hacer que el delay sea el exacto para poder visualizar el numero/letra, ya que, si los quito me la muestra apresuradamente y colocando un delay(500...100....2..1) no logro sino en los 2 ultimo ver parte del numero/letra mas no completo. Muchas Gracias.
CitarA pesar de que optimizaste al máximo el código tome solo estos detalles y los otros los guardare para posibles ideas, ya que, se nota que mi nivel de programación es algo(por no decir muy muy :oops: ) bajo y se que para ser el primer proyecto en pic, se tengas errores de esta clase.
Nadie nacio sabiendo, todo se gana con la practica, si ves que en tu codigo tenes muchas veces repetido un mismo pedazo de codigo (la misma forma) pero distintas variables, quiere decir que existe alguna forma de mejorarlo.
Una cosa que no nombre es que al array con los numeros, le agregue el "const" en su definicion, esto es para que el compilador sepa que como es constante y no se va a modificar, lo ponga en la FLASH, sino debe ponerlo en la RAM, y para eso necesita tener los valores en la FLASH para luego pasarlos a la RAM, en resumen, terminas ocupando RAM y sin querer espacio de FLASH, con el "const" le digo que lo ponga en la FLASH y que tome de alli los valores.CitarTengo una duda en esta lectura input_A()&0b00111000) >> 3; No entiendo muy bien el porque ">>3" Se debe a la posición de la lectura ya que los puertos van del RA0 al RA6, y como estoy entrando un dato binario y usando mascara para leer justamente eso el dato no se lee bien, es como por decir una corrección de la lectura, pero hasta hay se.
Mas que una correccion, lo que busco obtener yo es un numero de 0 a 7 de esos 3 bits. El problema que se encuentran desde el bit 3 al 5, Cuando hago la AND siguen quedando en esas posiciones. es decir:
PORTA = xxaa axxx (x los valores que quiero quitar, y a los valores que me interesan)
Hago la AND con 0011 1000
El resultado es: 00aa a000
Haciendo un desplazamiento a la derecha 3 veces " >> 3 " hago que esos bits queden asi: 0000 0aaa
Ahora si ambos valores son numeros de 0 a 7, y sumarlos es viable y facilmente como podes ver.CitarOtra duda es saber si existe un forma de hacer que el delay sea el exacto para poder visualizar el numero/letra, ya que, si los quito me la muestra apresuradamente y colocando un delay(500...100....2..1) no logro sino en los 2 ultimo ver parte del numero/letra mas no completo. Muchas Gracias.
Los delays son un gran problema, la idea siempre es minimizar su uso, asi como esta realizado el programa, implica que cualquier cosa que pongas en tu loop principal va a afectar en el tiempo que se muestra. Antes vos lo tenias para que muestre por 2 segundos en los cuales mientras muestra NO se puede ejecutar nada, terminado eso lee los botones y se encierra nuevamente al mostrar y eso es un problema. Que pasaria si en tu codigo de los botones tenes un delay de 1s, eso significa que tendrias 2s mostrandose y 1s sin mostrar, y vuelve a repetirse, se ve ahora el problema?
¿Cual es la mejor solucion para esto?
Independizar los tiempos. Usar un Timer, este Timer lo configuras para que cada 5ms por ejemplo llame a una funcion (que es la de interrupcion) entonces, cuando es el momento de actualizar el display lo hace por mas que estaba ejecutando cualquier cosa dentro del loop infinito. En realidad deja en pausa el loop infinito y atiende la interrupcion. Pero como la rutina de interrupcion es rapida parece como si estuviera ejecutandose simultaneamente.
El codigo quedaria algo asi:Código: C
#INT_TMR1 void interrupcion_tmr1(void) { set_timer_1(0); // Valor a determinar, por ahora ponemos 0 output_B(NumeroMatriz[valorAmostrar][k]); output_D(NumeroMatriz[MATMOV][k]); k++; if(k==8) { k=0;} // Si se paso que vuelva a comenzar }
Y en tu main, unicamente le tendrias que dar inicio al Timer y luego nada mas, la funcion "mostrar" estaria ahi en la interrupcion. Entonces...
Ese codigo se ejecuta cada 5ms (si es que configuramos el Timer para 5ms), por lo tanto no necesitas ningun delay, de querer cambiar el valor a mostrar, en tu loop principal le asignas el valor a la variable "valorAmostrar", obviamente a esa variable hay que hacerla global (declararla fuera del main) y ponerle el volatile (asi obligamos al compilador que siempre lo lea, usalo cuando tengas variables que se usan tanto en la interrupcion como en el main).
Y listo, ahora en tu main no tenes mas la funcion "mostrar", podes poner delays y siempre se va a ver correctamente. Lo unico "complejo" que tiene esto es que tenes que configurar el Timer al comienzo del main ( despues de los set_tris por ejemplo ).