TODOPIC
Microcontroladores PIC => Lenguaje C para microcontroladores PIC => Mensaje iniciado por: jmosorio en 04 de Marzo de 2008, 13:59:00
-
hola
necesito tomar un dato del puerto serial, y poderlo visualizar en 3 displays de 7 segmentos usando un pic18f452
es posible hacer esto usando 1 solo puerto del pic para la visualizacion en los 3 displays?
en caso de no ser posible, y necesitar decodificadores de 7 segmentos, me podrian ayudar con el codigo?
me podrian ayudar con el codigo en C que me permita hacerlo?
gracias por la ayuda que me puedan prestar.
John
-
Si puedes hacerlo con un puerto de 8 bits, puedes utilizar un solo decodificador de esos que le das el dato en BCD osea que utilizarias 4 bits y necesitaras otros 3 bits para multiplexar los displays.
Utiliza el buscador, seguro que por ahi encuentras algun ejemplo.
Saludos.
-
Ya mas o menos se como hacerlo, pero tengo una duda: al enviar el dato, no se modificarian todos los displays? es decir, si tengo el dato en el puerto, al cambiarlo, inicialmente cambiaria el display que yo habilite, pero el dato que se presentará en los otros cambiaria??
Si acaso es una pregunta estupida te pido disculpas :)
otra cosa, me puedes ilustrar un poco con el codigo para la recepcion del dato del puerto serial?? lo he mirado un poco en el buscador pero no lo encuentro, es para un pic18f452
grax
-
al enviar el dato, no se modificarian todos los displays?
No, es algo asi...
Envias dato1, display 1 on, display 2 off, display 3 off, retardo (unos 10 o 5 ms)
Envias dato2, display 1 off, display 2 on, display 3 off, retardo
Envias dato3, display 1 off, display 2 off, display 3 on, retardo
y se repite el proceso.
Para la recepcion puedes utilizar la interrupcion, trabajas con CCS?'
si trabajas con ccs seria algo asi
#use rs232(baud=xxxxx, xmit=xxxxx, rcv=xxxxx, stream=PC)
#INT_RDA
void serial_isr(void)
{
dato = getc(PC);
y procesas el dato...
}
}
Saludos
-
Hola, creo que ya lo tengo casi funcionando. pero se me ocurre una modificacion, te hago una pregunta:
necesito ahora hacer que se vea un dato tomado del puerto serial en 2 displays (un numero de 00 a 99), habilitando los 2 displays. en total necesito 8 juegos de 2 displays de 7 segmentos, si me llega por el pc un dato, mostrarlo por ejemplo en la pareja 1, y si me llega otro dato, mostrarlo por ejemplo en la pareja 2 pero sin que el dato de la pareja 1 desaparezca, y asi sucesivamente, la idea es que el dato que llegue aparezca en la pareja de displays que necesito, sin que el dato que estan mostrando las otrs 7 parejas se modifique. esto será posible trabajando de la misma manera?
la idea seria tomar 1 puerto de 8 bits, separarlo en 2 x 4 bits, conectado cada uno a un decodificador para los displays, cada uno de los 7447 maneja 1 cifra del numero, y a estos conectaria 8 displays, y usar otro puerto para realizar la habilitacion de la pareja de displays. Si funcionaría?
gracias por tu ayuda, no sabia que existian estos foros donde podemos aprender tanto!! 8)
-
la idea seria tomar 1 puerto de 8 bits, separarlo en 2 x 4 bits, conectado cada uno a un decodificador para los displays, cada uno de los 7447 maneja 1 cifra del numero, y a estos conectaria 8 displays, y usar otro puerto para realizar la habilitacion de la pareja de displays. Si funcionaría?
Sii suena bien, utilizarias los 4 MSB del puerto para un digito y los 4 LSB para el otro digito, y con otro puerto activas los displays, con el bit 0 activas un par, con el bit 1 otro par...
Pues yo a lo mucho he multiplexado 4 o 5 displays sin problemas, si seran 16 displays donde se activan 2 al mismo tiempo seria como tener 8 displays, no creo que haya problema, en el caso de notar parpadeo habria que probar reduciendo el tiempo del retardo.
Suerte con esto y no olvides comentarnos tus avances y/o dudas.
Saludos.
-
Hola
gracias por la gran ayuda, ya estoy trabajando en el tema, tengo otra pregunta
como puedo separar el numero, por ejemplo un numero cualquiera como 54, como puedo pasarlo a los 2 nibles, es decir mandar el 5 por 4 bits y el 4 por los otrs 4.
la pregunta es porque necesito leer el dato que me llega del pc (numero 54 en este caso) y separarlo en unidades y decenas para mostrarlo. para esto estoy haciendo un switch y un case de esta manera:
las variables son tipo int
cifra1=datopc/10;
digito1=cifra1;//primer digito del display para pasar a bcd
digito2=datopc-(cifra1*10);//2do digito del display para pasar a bcd
switch (digito1)
{
case 1
//pasariamos el dato al codigo bcd para el numero 1
....
....
}
existe una funcion que me pase un numero de 2 digitos a 2 numeros bcd, o alguna manera sencilla de realizar esto, que se me hace muy larga metiendo numero por numero por medio de un "case"
gracias
-
Hola, Mmm ahora mismo se me ocurre esto.
siguiendo con el ejemplo que muestras en digito1 ya tienes 5 y en digito2 el 4.
digito1 = 5 = 00000101
digito2 = 4 = 00000100
lo que seguiria seria rotar 4 bits en digito1 de manera que te quede digito1 = 01010000
despues hacer una operacion or entre digito1 y digito2 y quedaria por ejemplo digito3 = 01010100
y ya tienes el BCD en la parte alta el digito 1 y en la baja el 2.
Mmm No se si es lo que querias saber, pero bueno, es lo que ahora se me ocurre, talvez haya una mejor forma de realizarlo.
Saludos.
-
nuevamente gracias, ya tengo el codigo bastante adelantado
ahora la duda es:
yo puedo tener ya la variable con el numero, y enviarla directamente al puerto asi:
suponemos que tenemos el dato 54 ya pasado al bdc, que seria 0101 0100, el cual en decimal es 84
yo puedo decir directamente
numero=84;
portb=numero;
o como puedo enviar ese dato al puerto??
gracias nuevamente por la gran ayuda recibida
-
Bueno, si es en CCS seria output_b(84);
si definiste anteriormente a portb con su direccion correspondiente...
numero=84;
portb=numero;
Esto es correcto.
Saludos
-
hola a todos.
Mi programa / montaje va biento en popa, quiero agradecer la valiosisima colaboracion del foro, al cual seguiré visitando y cualquier duda que tenga o algo que pueda aportar pues se los hare saber.
una pregunta, estoy trabajando con mcc18, cual es mejor para trabajar, ese o el ccs?
gracias
-
hola nuevamente.
habia dejado el tema de lado por algunos dias, ahora estoy tratando de simularlo y no me esta funcionando.
la idea es:
del puerto B estoy sacando 4 bits a un decodificador de 7 segmentos y los 4 restantes al otro
del puerto D estoy sacando cada bit para la habiilitacion del display
no se si este codigo tenga algun problema:
//
TRISB=0;
TRISD=0;
PORTB=3; //coloco un 0 en el primer display y un 3 en el segundo
PORTD=1; //habilito el primer juego de displays
Delay10KTCYx(1); //retardo
PORTB=147; // coloco un 9 en el primer display y un 3 en el segundo
PORTD=2; //habilito el segundo juego de displays
Delay10KTCYx(1);//retardo
//
la simulacion en proteus no me esta funcionando, pero la verdad no se si esto lo tengo que colocar dentro de un ciclo o que mas tengo que hacer. agradezco la ayuda que me puedan prestar.
-
hola jmosorio
Mira, yo tenia un problema similar en la simulacion con C18 y era porque no configuraba los "config" en el programa. Yo lo hago de la siguiente manera:
En la carpeta doc del mcc18 esta el Addendum.pdf en donde estan los "config" de los diferentes pics.
Otra cosa que puede ser (o que a mi me paso), es que la conmutacion de 2 o mas 7 segmentos individuales no funciona, por eso hay, en las librerias de proteus, 7 segmentos multiples (de 2 y 4 digitos) en un mismo "device", yo hice el cambio y me funciono correctamente.
Espero te sirva mi ayuda :)
-
hola, estoy teniendo problemas con la multiplexacion, no logro que se vean los numeros en cada uno, sino que en cada uno de los displays se ven todos los numeros, como puedo configurar los delays de manera que logre esto. el cristal que estoy usando es de 4M, y tengo 5 displays conectados, la rutina para mostrarlos la tengo de esta manera:
PORTD=0;//APAGO DISPLAYS
Delay10KTCYx(1);
PORTB=numero1; //MANDO DATO
Delay10KTCYx(1);//DELAY
PORTD=1; //HABILITO DISPLAY1
Delay10KTCYx(50);//DELAY PARA QUE SE VEA
PORTD=0;//APAGO DISPLAYS
Delay10KTCYx(1);//DELAY
PORTB=numero2;//PONGO NUMERO 2
Delay10KTCYx(1);//DELAY
PORTD=2; //HABILITO DISPLAY 2
Delay10KTCYx(50);//DELAY PARA QUE SE VEA
......................
......................
agradezco la ayuda que me puedan prestar
-
Mmmm, te podrias ahorrar las siguientes lineas...
PORTD=0;//APAGO DISPLAYS
Delay10KTCYx(1);<-------------------------------
PORTB=numero1; //MANDO DATO
Delay10KTCYx(1);//DELAY<-------------------------------
PORTD=1; //HABILITO DISPLAY1
Delay10KTCYx(50);//DELAY PARA QUE SE VEA
PORTD=0;//APAGO DISPLAYS
Delay10KTCYx(1);//DELAY<-------------------------------
PORTB=numero2;//PONGO NUMERO 2
Delay10KTCYx(1);//DELAY<-------------------------------
PORTD=2; //HABILITO DISPLAY 2
Delay10KTCYx(50);//DELAY PARA QUE SE VEA
solo una duda, Delay10KTCYx(50); a cuanto tiempo equivale?'' =S no conosco ese C =P
Para habilitar el display 3 pones PORTD=3;?'''' o PORTD=5;?''
saludos.
-
para habilitar el display 3 mando un 4, para habilitar el 4 pongo un 8....es poner un 1 en el bit donde quiero encender el display.
el delay...(50) es
50*(1/4000000)*10000 = 0.125s
-
para habilitar el display 3 mando un 4, para habilitar el 4 pongo un 8....es poner un 1 en el bit donde quiero encender el display.
Mmmm eso esta bien entonces
50*(1/4000000)*10000 = 0.125s
No sera mas bien 50*(4/4000000)*10000 ?''' bueno no se
Deberia funcionar, puedes probar con un tiempo mas largo, de manera que alcances a ver como se activa display por display, a ver que ves. si puedes poner algun esquema de tu circuito y/o el programa completo podria ayudar.
Saludos.
-
Pues el codigo con el que estoy probando es el siguiente, para visualizar lo que tengo en cada variable en cada uno de los 4 displays. la verdad no se como "jugar" con los delays de manera que pueda ver los datos en los 4 juegos al tiempo. el puerto B esta con 4 bits a un decod de 7 segmentos, y los 4 restantes a otro decodificador igual. logro ver los datos si muevo los delays, pero lo que logro es que aparezcan todos en todos, apagandose secuencialmente uno. gracias por la excelente ayuda que he recibido en este foro, aun siendo un principiante :)
# include <p18f452.h>
# include <delays.h>
void main (void)
{
int numero1,numero2,numero3,numero4;
TRISB=0; //puerto de salida
TRISD=0;
numero1=39;
numero2=1;
numero3=22;
numero4=0;
//visualizacion dinamica
PORTD=0;//APAGO DISPLAYS
Delay100TCYx(100);
PORTB=numero1; //MANDO DATO
Delay100TCYx(1);//DELAY
PORTD=1; //HABILITO DISPLAY1
Delay100TCYx(10);//DELAY PARA QUE SE VE
PORTD=0;//APAGO DISPLAYS
Delay100TCYx(100);//DELAY
PORTB=numero2;//PONGO NUMERO 2
Delay100TCYx(1);//DELAY
PORTD=2; //HABILITO DISPLAY 2
Delay100TCYx(10);//DELAY PARA QUE SE VEA
PORTD=0;//APAGO DISPLAYS
Delay100TCYx(100);//DELAY
PORTB=numero3; //PONGO NUMERO 3
Delay100TCYx(1);//DELAY
PORTD=4; //HABILITO DISPLAY3
Delay100TCYx(10);//DELAY PARA QUE SE VEA
PORTD=0;//APAGO DISPLAYS
Delay100TCYx(100);//DELAY
PORTB=numero4;//PONGO NUMERO 4
Delay100TCYx(1);//DELAY
PORTD=8; //HABILITO DISPLAY 4
Delay100TCYx(10);//DELAY PARA QUE SE VEA
}
-
Mmmm, Creo que ya me perdi mas, aclarame
logras ver los 4 datos en todos los 4 pares de displays? o como :?
Que tipo de displays tienes?' Anodo comun o Catodo comun?
Podras probar con este codigo a ver que tal va? seria para displays anodo comun, ya que activas los displays con un 1 que sale del port d.
por lo que si numero1=39=0010 0111 mostrarias en un display un 2 y en el otro un 7
# include <p18f452.h>
# include <delays.h>
void main (void)
{
int numero1,numero2,numero3,numero4;
TRISB=0; //puerto de salida
TRISD=0;
numero1=39;
numero2=1;
numero3=22;
numero4=0;
//visualizacion dinamica
while(1)
{
PORTD=1;
PORTB=numero1;
Delay100TCYx(50);
PORTD=2;
PORTB=numero2;
Delay100TCYx(50);
PORTD=4;
PORTB=numero3;
Delay100TCYx(50);
PORTD=8;
PORTB=numero4;
Delay100TCYx(50);
}
}
si no me equivoco Delay100TCYx(50); = 50*(4/4000000)*100?'' = 5ms
Saludos
-
hola :)
si, logro ver que el display 1 prende con el primer numero, apaga segundo numero, apaga, tercer numero, apaga...y esto se hace secuencial. los displays son de anodo, voy a probar con el codigo que me recomiendas, te estaré contando como me va, nuevamente gracias por tu colaboracion, vamos a ver si lo logro
-
Mmm, pues va a ser lo mismo, si ves los 4 numeros en todos los display debe haber algun error en tu diagrama o en tus conexiones.
:?
-
tengo otro problema. tengo que leer un dato del puerto serial, tengo la siguiente rutina, si alguien me puede decir si esta bien seria de gran ayuda, o corregirme para ver que error tiene. el dato "y" de que tipo deberia ser, y el dato "x" para que podamos leer el dato. si quisiera mostrarlo en el puerto B como deberia hacer?
gracias por la ayuda que me puedan prestar.
#include<p18f452.h>
#include <delays.h>
#include <usart.h>
#include <timers.h>
void lectura(void);
void serial(void);
unsigned int result=0;
unsigned int result1=0;
void main(void)
{
OpenUSART( USART_TX_INT_OFF &
USART_RX_INT_OFF &
USART_ASYNCH_MODE &
USART_EIGHT_BIT &
USART_CONT_RX &
USART_BRGH_HIGH, 25 );
while(1)
{
lectura();
}
}
void lectura (void)
{
result1= ReadUSART();
x=0x01;
y=x&&result1;
}
-
saludos
ya solucione el problema de la visualizacion. el problema estaba en mi montaje, ya puedo visualizar correctamente todo, y la parte de los delays estaba funcionando mal precisamente por el montaje, proximamente adicionare el codigo.
ahora el problema que tengo es como recibir un dato del puerto serial. el codigo que estoy usando es como esta en el post inmediatamente anterior. quisiera saber como puedo hacer para visualizar el dato que digito en el teclado, por el puerto B. la idea es que por alli voy a recibir numeros entre 0 y 99, para visualizarlos en los displays, como puedo pasar el dato ASCII que recibo para visualizarlo en el puerto?? como siempre gracias por la gran ayuda que he recibido en este foro.
-
Hola.
logre tambien solucionar el problema, ya estoy recibiendo el dato del pc, y logro trabajar con el. muchas gracias, voy a ver como logro poner los codigos en caso de ser utiles para alguien. nuevamente muchas gracias por todo.