#include <16F877A.h>
#fuses XT,NOWDT,PUT,NOLVP
#use delay (clock=800) // declaro el cristal
#use STANDARD_IO(B)
VOID decimalBinario (int numero) ;
void main()
{
INT i;
SET_TRIS_A (0b11111111); //todas entradas
SET_TRIS_B (0b00000000); //todas salidas
SET_TRIS_C (0b00000000); //todas salidas
WHILE (1)
{
FOR (i = 0; i < 10; i++)
{
decimalBinario (i);
IF (!input (PIN_C0))
{output_high (PIN_C0);
output_low (PIN_C1);
}
ELSE
{output_high(PIN_C1);
output_low(PIN_C0);
}
delay_ms (2000);
}
}
}
void decimalBinario(INT numero)
{
SWITCH (numero)
{
CASE 0:
output_b (0b1000000);
BREAK;
CASE 1:
output_b (0b11111001);
BREAK;
CASE 2:
output_b (0b0100100);
BREAK;
CASE 3:
output_b (0b0110000);
BREAK;
CASE 4:
output_b (0b0011001);
BREAK;
CASE 5:
output_b (0b0010010);
BREAK;
CASE 6:
output_b (0b0000010);
BREAK;
CASE 7:
output_b (0b1111000);
BREAK;
CASE 8:
output_b (0b0000000);
BREAK;
CASE 9:
output_b (0b0011000);
BREAK;
}
}
saludos
Que tal artemis,hola elreypic que tal? como se setea el delay?? vi en algunos lados que ponian delay_ms pero no se si requiere de alguna libreria en especial o como es?
Por lo que veo no hay delay entre un display y el otro, lo que significa que enciendes uno e inmediatamente lo apagas y enciendes el otro, como es tan rápido, la sensasión que te dará es que ambos displays están encendidos. De hecho esa es la idea cuando se usa la técnica de multiplexación. En realidad se usa un delay de 1ms aprox entre cada display de esa manera al final te da la sensación de que muestras diferentes valores en los displays.
Si lo que quieres es ver cuando se enciende un display y cuando se apaga el otro, coloca un delay de 1 segundo o mayor, para que puedas ver el efecto.
elreypic.
Requiere usar el macromi compilador no me reconoce "#use", utilizo el hpdpic
#use delay (clock=8000000) “la cifra es la velocidad del oscilador de tu pic)
Luego la función la llamas:
delay_ms(10); // genera retardo de 10 milisegundos.
O bien
delay_us(10); // genera retardo de 10 microsegundos.
10,o 100, o 1000 , lo que quieras.
Para el ya obsoleto compilador C de Hitech, la forma de hacerlo es:Puse lo siguiente:
_XTAL_FREQ freq //freq es el valor en hertz del oscilador, Ejemplo (4MHz): 4000000
__delay_ms(x); //request a delay in miliseconds
__delay_us(x); //request a delay in microseconds
elreypic
¿Podrías especificar cuál compilador estas usando?utilizo el hi-tech pero en la carpeta "includes" no tengo el htc.h sino que tengo uno llamado hitech.h pero no se si es lo mismo
Parece que no es el compilador C de Hitech, ya que este ocupa que incluyas el archivo htc.h
#include <htc.h>
y no veo que lo tengas.
elreypic.
Parece ser que la versión que estás usando es muy antigua y la verdad no estoy seguro si ambos archivos sean lo mismo.adjunto el manual que tiene la carpeta donde está instalado el compilador, no encontré ninguna función delay yo
¿Tienes el manual de usuario de esa versión en particular?
¿Podrías indicar cuál es la versión del compilador que estás usando?
Usa un command promt de windows y ejecuta el comando:
PICC --VER
Este te mostrará la versión del compilador qeu estás usando. Pero lo mejor sería que tuvieras el manual. Para buscar el uso de los delays. Este pudiera estar en la carpeta de instalación del compilador.
elreypic.
¿Me puedes decir que version de compilador tienes, usando el comando que te mencioné?hola acá adjunto la captura del cmd
elreypic
Que tal artemis,hola reypic estuve haciendo modificaciones, instalé el ccs compiler que trabaja con mas librerias y probé el siguiente código:
Desafortunadamente esa versión de C no tiene las rutinas de delay. Como bien te dice KILLERJC, va a ser mejor que descargues una version actual del XC de Microchip (la versión gratuita) y uses esa para tu proyecto. De esa manera te quitarás de cualquier problema.
O bien si puedes conseguir una versión más actualizada (creo que la última fue la 9.83).
elreypic.
#include <16F877A.h>
#fuses XT,NOWDT,PUT,NOLVP
#use delay (clock=800) // declaro el cristal
#use STANDARD_IO(B)
VOID decimalBinario (int numero) ;
void main()
{
INT i;
WHILE (1)
{
SET_TRIS_A (0b11111111); //todas entradas
SET_TRIS_B (0b00000000); //todas salidas
SET_TRIS_C (0b00000000); //todas salidas
FOR (i = 0; i < 10; i++)
{
decimalBinario (i);
IF (input_state (PIN_C0) == 0)
{
output_c (0b11111101);
}
ELSE
{
output_c (0b11111110);
}
delay_ms (4000);
}
}
}
void decimalBinario(INT numero)
{
SWITCH (numero)
{
CASE 0:
output_b (0b1000000);
BREAK;
CASE 1:
output_b (0b11111001);
BREAK;
CASE 2:
output_b (0b0100100);
BREAK;
CASE 3:
output_b (0b0110000);
BREAK;
CASE 4:
output_b (0b0011001);
BREAK;
CASE 5:
output_b (0b0010010);
BREAK;
CASE 6:
output_b (0b0000010);
BREAK;
CASE 7:
output_b (0b1111000);
BREAK;
CASE 8:
output_b (0b0000000);
BREAK;
CASE 9:
output_b (0b0011000);
BREAK;
}
}
Dos cositas:hola probé con ese if pero me sigue manteniendo los leds encendidos a pesar de que las salidas de C van cambiando de 0 a 1 y viceversa
1- saca los tris del while. Ponlos encima del int i; por ejemplo. No es la causa del problema es absurdo meterlo en el bucle.
2- la función input_state(); no cambia la dirección del pin que lees. Ten en cuenta que los pines C son salidas, por ello input_state te va a devolver siempre cero.
Podrías hacer:Código: CSustituyendo tu actual if else.
if (!input(PIN_C0) {output_high(PIN_C0);output_low(PIN_C1);} else {output_high(PIN_C1);output_low(PIN_C0);}
Fíjate que a la entrada a la resistencia R9 hay un cero lógico y en la R8 hay un uno lógico. Sin embargo ambos transistores están en conducción.estoy utilizando ánodo común y por eso puse transistores PNP, para mi el problema está en que siempre tienen corriente por el lado del emisor, y los mantiene prendidos pero no se porque los ejemplos que vi con ese tipo de ánodo lo planteaban de esa forma
Revisa la conexión de la resistencia R8, no se por que tiene como dos uniones en los extremos de la resistencia mientras las demás no. Yo es que no uso simuladores.
y qué tipo de display estás usando , ¿Anodo común o cátodo común?
Que tal artemis,Hola elreypic te comento:
Vamos aponer algo de orden en tu simulación.
1) La entrada del R8 no sé a que puerto está conectado y pareciera que esta en corto con varios pines
2) De igual manera los pines 1 y 2 del display hacia los colectores del transistores PNP, hay que definirlos bien, pareciera que están cortocircuitados.
Los displays que se usan en PROTEUS en realidad no son analógicos, son algo como digitales, entonces las resistencias R1-R7 en realidad no pueden ser de 10K, ya que el voltaje que usas es de solo 5V, esas resistencias deberían ser de unos 220 ohms, pero a proteus no le importa eso.
No está indicado cual transistor PNP estás usando, lo que es importante, ya que posiblemente la resistencia de base no es suficiente para poner el transistor en corte o saturación. ¿Qué transistor estás usando? ¿BC557, 2N3906, 2N2907?
Algo que me ha pasado con este display es que necesitas apagar todos los dígitos antes de encender solamente un solo dígito.
elreypic.
Fíjate si el indicador del pin enciende y apaga según tenga que suceder. Si prenden los indicadores pero el dígito dice que nanai pues es problema de simulación con ese display.uno de los display se apaga recién cuando cuenta hasta 4 y no entiendo por qué, luego no vuelve a prenderse más.. sigue el contador con un display solo
artemis,acá adjunto el código y el archivo del proyecto en proteus, utilizo la version 8 profesional de proteus
¿Podrías subir tu código y compartirnos tu archivo de imulación de proteus?
¿Cuál versión de proteus estás usando?
elreypic.
#include <16F877A.h>
#fuses XT,NOWDT,PUT,NOLVP
#use delay (clock=800) // declaro el cristal
#use STANDARD_IO(B)
VOID decimalBinario (int numero) ;
void main()
{
INT i;
SET_TRIS_A (0b11111111); //todas entradas
SET_TRIS_B (0b00000000); //todas salidas
SET_TRIS_C (0b00000000); //todas salidas
WHILE (1)
{
FOR (i = 0; i < 10; i++)
{
decimalBinario (i);
IF (!input (PIN_C0))
{output_high (PIN_C0);
output_low (PIN_C1);
}
ELSE
{output_high(PIN_C1);
output_low(PIN_C0);
}
delay_ms (2000);
}
}
}
void decimalBinario(INT numero)
{
SWITCH (numero)
{
CASE 0:
output_b (0b1000000);
BREAK;
CASE 1:
output_b (0b11111001);
BREAK;
CASE 2:
output_b (0b0100100);
BREAK;
CASE 3:
output_b (0b0110000);
BREAK;
CASE 4:
output_b (0b0011001);
BREAK;
CASE 5:
output_b (0b0010010);
BREAK;
CASE 6:
output_b (0b0000010);
BREAK;
CASE 7:
output_b (0b1111000);
BREAK;
CASE 8:
output_b (0b0000000);
BREAK;
CASE 9:
output_b (0b0011000);
BREAK;
}
}
#include <16F876A.h>
#fuses XT,NOWDT,PUT,NOLVP
#use delay(crystal=4000000)
#use FIXED_IO( B_outputs=PIN_B7,PIN_B6,PIN_B5,PIN_B4,PIN_B3,PIN_B2,PIN_B1,PIN_B0 )
#use FIXED_IO( C_outputs=PIN_C1,PIN_C0 )
void decimalBinario(int numero);
void main()
{
int i;
while(1)
{
for (i=0;i<10;i++)
{
decimalBinario(i);
if (!input(PIN_C0))
{
output_high(PIN_C0);
output_low(PIN_C1);
}
else
{
output_high(PIN_C1);
output_low(PIN_C0);
}
delay_ms(2000);
}
}
}
void decimalBinario(int numero)
{
switch (numero)
{
case 0:
output_b (0b1000000);
break;
case 1:
output_b (0b11111001);
break;
case 2:
output_b (0b0100100);
break;
case 3:
output_b (0b0110000);
break;
case 4:
output_b (0b0011001);
break;
case 5:
output_b (0b0010010);
break;
case 6:
output_b (0b0000010);
break;
case 7:
output_b (0b1111000);
break;
case 8:
output_b (0b0000000);
break;
case 9:
output_b (0b0011000);
break;
}
}
Que tal artemis,perfecto agregando esas resistencias ahora funciona la mutliplexación
Pues lo prometido es deuda. Analizando tu código a detalle, el siguiente código es como debería quedar:Código: [Seleccionar]#include <16F876A.h>
#fuses XT,NOWDT,PUT,NOLVP
#use delay(crystal=4000000)
#use FIXED_IO( B_outputs=PIN_B7,PIN_B6,PIN_B5,PIN_B4,PIN_B3,PIN_B2,PIN_B1,PIN_B0 )
#use FIXED_IO( C_outputs=PIN_C1,PIN_C0 )
void decimalBinario(int numero);
void main()
{
int i;
while(1)
{
for (i=0;i<10;i++)
{
decimalBinario(i);
if (!input(PIN_C0))
{
output_high(PIN_C0);
output_low(PIN_C1);
}
else
{
output_high(PIN_C1);
output_low(PIN_C0);
}
delay_ms(2000);
}
}
}
void decimalBinario(int numero)
{
switch (numero)
{
case 0:
output_b (0b1000000);
break;
case 1:
output_b (0b11111001);
break;
case 2:
output_b (0b0100100);
break;
case 3:
output_b (0b0110000);
break;
case 4:
output_b (0b0011001);
break;
case 5:
output_b (0b0010010);
break;
case 6:
output_b (0b0000010);
break;
case 7:
output_b (0b1111000);
break;
case 8:
output_b (0b0000000);
break;
case 9:
output_b (0b0011000);
break;
}
}
Debes agregar unas resitencias de pull-down en los colectores de los transistores (R11 y R12), ya que este display necesita ver un nivel bajo (0) para saber que el digito está apagado correctamente (es una especie de bug que tiene proteus). En la realidad no son necesarias esas resistencias.
Aquí un snapshot de mi simulación:
- Tienes que ingresar para ver archivos adjuntos -
No se cual sea la frecuencia del cristal que estes usando pero yo lo definí como de 4MHz. Eso también lo tienes que definir en las propiedades del microcontrolador en el simulador del proteus. Ojo el agregar un cristal de 4MHz, no significa que proteus simula a esa frecuencia, tienes que seleccionar el microcontrolador, darle click derecho y en donde dice Porecesso Clock Frequency colocar: 4MHz.
saludos y espero esto te sirva
elreypic.