Bueno veo algunos errores. Y otras cosas que te va a servir.
Errores:
1- La muestra de cada digito se hace MUY MUY MUY rapido, cada numero, es decir 00 -> 01 -> 02 se debe estar realizando cada unos 71ms, solucion simple pero no muy linda es agregarle un for
2- Estas multiplexando mal, no estas apagando los displays
3- Aunque no es un error, si vas a mostrar en el puerto la misma representacion binaria de lo que esta, no es necesario el conversor BCD7Seg que tenes, ya que un 9 en binario es 1001 y es lo que va a salir del puerto, distinto es si tenes que convertir el binario ese en los 7 segmentos, es decir que por ejemplo el 8 ( 0x08 o 0000 1000) sea representado por ( 0111 1111 ) en el que cada bit es un segmento pero vos estas sacando un 1000 asi que no es necesario.
4- Tenes un error en tu logica, si necesitas contar hasta 63 lo mismo ocupas solo 4bits, ya que ese 63 se pasa a "decimal" y queda 6 y 3, es decir solo necesitas representar de 0 a 9 y por lo tanto solo basta 4 bits
Consejos:
1- Utiliza un identado, es decir utiliza el boton TAB (el que esta arriba del bloq mayuscula) para ubicar el codigo, se vuelve mas legible de esa forma. Ya vas a ver el ejemplo abajo
Y con respecto a que te cambia los bits eso es por que estas cambiando TODO el port.
Para cambiar solo un pedacito del port deberias leerlo y luego cambiar lo que quieras, ejemplo
valorport = input_c();
valorport &= 0b11110000); // aca hago valorport AND 0xF0 , lo que me deja los bits 7,6,5,4 sin modificarse, por que no se usan, luego le tengo que agregar lo del BCD7seg
output_c(valorport | BCD7seg[dec]);
Otra cosa que por ahi molesta del CCS es que por ejemplo vos queres que el bit 6 y 7 sean entradas y no salidas. Si vos haces
output_c(0x0F);
CCS las va a poner a TODAS como salida.
Esto es un tema que no me gusta de CCS pero que se puede arreglar. Si se usa la directiva:
#use fast_io(c)
Y luego en el main hacemos:
set_tris_c(0xF0); // 1111 0000 , es decir de 0 a 3 como salidas y de 4 a 7 como entradas.
La proxima ves que hagas:
output_c(0xFF);
Vas a modificar UNICAMENTE las salidas (es decir bits 0 a 3), esto es por que CCS comienza con todos los puerto donde lo define como standard_io , eso hace que CADA ves que vos pongas algo en el puerto (lectura o escritura), ya sea que le digas a un bit o a todo el puerto, se agregue codigo para cambiar la direccion del pin
input_pin(PIN_A0); // Aca lo pone como entrada
output_pin(PIN_A0); // Aca lo pone como salida , a pesar que antes lo use como entrada antes. Y podria hacer un hermoso cortocircuito al pasar de una alta impedancia a GND cuando tal ves en la entrada tengo VCC, Y requiere atencion.
Como dije esto NO ocurre si usas fast_io, ya que ahi no modifica mas los TRISx , tris que definiste al comienzo de tu programa. Ademas el fast_io al no agregar codigo y solo modificar el registro que necesita se termina ejecutando mas rapido.
Aca tenes un ejemplo y tal ves el codigo que necesitas, no se que tan bien ande, y a esto me refiero con "identado"Código: C
#include <16f877.h> #fuses XT,NOWDT,NOPROTECT,PUT,NOBROWNOUT,NOLVP #use fast_io(c) #USE delay(clock=4m) void main(){ set_tris_C(0b11000000); //Ejemplo de como es el TRIS de un puerto, deje unicamente como entrada bit 6 y 7 int8 j; // Por lo tanto no va a cambiar cuando uses output_c , aunque solo usas los bits de 0 a 3, por lo que podria haber puesto 0xF0 en el TRIS int unit=0, dec=0, unidaz=0, valor; while(TRUE) { valor=input_b(); if (valor<100) { valor++; for (unit=0;valor>unit;unit++) { dec=valor/10; //Como dec es un entero, se va a guardar unicamente el entero unidaz= valor%10; //El resto de la division de 10 for(j=0;j<10;j++) // For para que tarde un poco mas de tiempo { output_low(PIN_d0); // Apago ANTES del cambio del puerto, asi se cambia cuando esta apagado output_low(PIN_d1); output_c(dec); // Como valor esta limitado a 99 , si divido por 10 solo me queda un maximo de 9, es decir va de 0 a 9 (0x00 a 0x09) output_high(PIN_d1); delay_ms(50); output_low(PIN_d1); // Apago ANTES del cambio del puerto output_c(unidaz); // El modulo de 10, me deja con el resto de la division, es decir las unidades, por lo tanto va de 0 a 9 output_high(PIN_d0); delay_ms(49); } } } else { output_high(PIN_d0); // Mayor a 100, por lo tanto pones 00 en ambos, como ambos son iguales no es necesario la multiplexacion output_high(PIN_d1); output_c(0b0000); delay_ms(5); } } }
Otra cosa porque los displays parpadean primero se enciende uno y luego otro, me gustaria que mostrasen el valor al unisono.
Hay algo que falla tengo que resetear el micro para obtener un nuevo valor (No son los { } valor=input_b(); esta dentro de WHILE).
Se entiende mejor como se puede pasar de 15 con solo 4bits. Lo demas hay cosas que tengo que leer mas detenidamente. Me an enseñado a ahorrar el PORTD solo tengo que hacer una suma u or 16=pin 4 32=pin 5.
Vamos por parteCitarOtra cosa porque los displays parpadean primero se enciende uno y luego otro, me gustaria que mostrasen el valor al unisono.
Esto es por que se esta multiplexando y es la idea, si es MUY notable entonces tenes que disminuir el tiempo que esta prendido, para mantener masomenos el mismo tiempo, supone que le aumentamos velocidad entre que un display enciende y el otro apaga a unos 50 veces por segundo, ya que teniamos 20, asi que modificamos esta parte:Código: C
for(j=0;j<25;j++) // For para que tarde un poco mas de tiempo { output_low(PIN_d0); // Apago ANTES del cambio del puerto, asi se cambia cuando esta apagado output_low(PIN_d1); output_c(dec); // Como valor esta limitado a 99 , si divido por 10 solo me queda un maximo de 9, es decir va de 0 a 9 (0x00 a 0x09) output_high(PIN_d1); delay_ms(20); output_low(PIN_d1); // Apago ANTES del cambio del puerto output_c(unidaz); // El modulo de 10, me deja con el resto de la division, es decir las unidades, por lo tanto va de 0 a 9 output_high(PIN_d0); delay_ms(20); }
Ahora el for es de 25, pero el delay es de 20ms, entonces en ves de estar 50ms uno y luego 50ms el otro, lo hacemos 20ms uno y 20ms el otro. El tiempo total entre digito y digito es de 40ms * 25 = 1000ms = 1s, es decir cada 1 segundo va a aumentar
De esa forma al ser mas rapido, se quita esa sensacion de que estan parpadeando. Si aun asi se nota que parpadea se puede disminuir mas el tiempoCitarHay algo que falla tengo que resetear el micro para obtener un nuevo valor (No son los { } valor=input_b(); esta dentro de WHILE).
No creo, ahora que aumentamos mucho mas el tiempo en que se muestran los numeros hace que hasta que vaya desde 0 a 50 por ejemplo, le tome 50 segundos, y recien ahi va a leer el puerto. Si quieres hacerlo mas rapido como para probar entonces cambia el valor del for de arriba por otro menor. elegimos 25, si usaramos 10 por ejemplo el numero cambiaria cada 10 * 40ms = 400ms. Si lo haces por 5, cada 200ms se sumaria 1. Entonces la maxima pasada (es decir 99, tomo 100 para ahorrar calculos) puede tardar
Para dos delays de 20ms, con for:
1(sin for) -> 4s
2 -> 8s
5 -> 20s
10 -> 40s
25 -> 100s
Recordar que esto es lo que va a tardar aproximadamente a contar hasta el numero 99, si tenes un numero mas chico obviamente va a contar va a completarse mas rapido. Cuando se termine de mostrar todos los numeros recien ahi va a tomar de nuevo el valor del puerto. Si no es asi como deseas que funcione entonces explicalo con el mayor detalle y vemos como hacerlo.CitarSe entiende mejor como se puede pasar de 15 con solo 4bits. Lo demas hay cosas que tengo que leer mas detenidamente. Me an enseñado a ahorrar el PORTD solo tengo que hacer una suma u or 16=pin 4 32=pin 5.
Ojo que no es lo mismo una suma que una OR, si antes tenias un 0 ahi el resultado de ambas operaciones va a ser igual
0000 1001 + 0001 0000 = 0001 1001
0000 1001 | 0001 0000 = 0001 1001
Pero si es era un 1, se vuelve distinto.
0001 1001 + 0001 0000 = 0010 1001
0001 1001 | 0001 0000 = 0001 1001
Esto ya me lo an dicho antes.
Utilizo el simulador Proteus pero aunque vaje el delay(5) unicamente ocurre que el parpadeo es mas rapido.
Yo llevo directamente del pin del micro al terminal del display (cosa que se. No se debe hacer en la practica) ¿podria ser por esto?(un simulador permite saltarte estas cosas)
el OR yo lo vi similar pero en el programa que me ofrecieron tambien funciona la SUMA (valor no parece afectar pin de 4 a 7)
Que le pasa al operando "%" ¿hace mas operaciones internas, ocupa mas ciclos de reloj?
Target halted. Stopwatch cycle count = 625 (125 µs)
Target halted. Stopwatch cycle count = 625 (125 µs)
Target halted. Stopwatch cycle count = 632 (126,4 µs)
Target halted. Stopwatch cycle count = 625 (125 µs)
Target halted. Stopwatch cycle count = 625 (125 µs)
Target halted. Stopwatch cycle count = 618 (123,6 µs)
Target halted. Stopwatch cycle count = 611 (122,2 µs)
Target halted. Stopwatch cycle count = 325 (65 µs)
Target halted. Stopwatch cycle count = 280 (56 µs)
Target halted. Stopwatch cycle count = 377 (75,4 µs)
Target halted. Stopwatch cycle count = 377 (75,4 µs)
Target halted. Stopwatch cycle count = 381 (76,2 µs)
Target halted. Stopwatch cycle count = 377 (75,4 µs)
Target halted. Stopwatch cycle count = 377 (75,4 µs)
Target halted. Stopwatch cycle count = 373 (74,6 µs)
Target halted. Stopwatch cycle count = 371 (74,2 µs)
Target halted. Stopwatch cycle count = 325 (65 µs)
Target halted. Stopwatch cycle count = 32 (6,4 µs)
Acabo de ver varios compiladores XC, tambien e leido algo sobre Hi-Tech este ultimo dicen (en ingles) que es mas avanzado aunque CCS es mas sencillo y empiezo a estar agusto con el. Cuando instale CCS me pidio si queria MPLAB (solo ahora e visto lo que es) por defecto estaba anulado y no la instale ¿hice mal?.