Autor Tema: Mismo puerto para Datos de LCD y RX / TX, ¿cómo multiplexarlo?  (Leído 2257 veces)

0 Usuarios y 1 Visitante están viendo este tema.

Desconectado cereal2

  • PIC10
  • *
  • Mensajes: 26
Mismo puerto para Datos de LCD y RX / TX, ¿cómo multiplexarlo?
« en: 10 de Septiembre de 2005, 07:51:00 »
Buenas, tengo un PIC16F88 con sólo dos puertos, A y B. Pues el puerto A lo uso para el control del LCD (E,R/W,RS), y por tanto, el puerto B lo uso para los datos del LCD (imprimir caracteres). Pues además, el puerto B está RX y Tx. El problema que tengo es que cuando quiero enviar un carácter al LCD, "accidentalmente" también se envia por TX al puerto serie, y no quiero que pase eso, ¿cómo puedo que cada carácter se envie por puerto B (los 8 bits) sin enviar nada por TX (bit 5 del puerto B)? He probado en deshabilitar y habilitar la UART, pero sigue enviando igual.

Os agredecería mucho su ayuda, ya que es el último retoque para presentar el proyecto.

Gracias por adelantado.                                                                                                                                    

Desconectado MGLSOFT

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 7912
RE: Mismo puerto para Datos de LCD y RX / TX, ¿cómo multiplexarlo?
« Respuesta #1 en: 10 de Septiembre de 2005, 07:57:00 »
Prueba a utilizar el LCD en modo a 4 bits, porque es muy dificil imposible multiplexar pines que son inputs y ouputs a la vez, como es el caso de los bits de datos de un LCD.
Direcciona la libreria del lcd y podras usar los 4 bits mas bajos o los mas altos (no recuerdo bien en que parte esta el comm), ademas esto te liberara dos o tres pines mas, si no usas TX.Sonrisa GiganteSonrisa Gigante
Todos los dias aprendo algo nuevo, el ultimo día de mi vida aprenderé a morir....
Mi Abuelo.

Desconectado RaDoN

  • Moderadores
  • PIC24H
  • *****
  • Mensajes: 1498
RE: Mismo puerto para Datos de LCD y RX / TX, ¿cómo multiplexarlo?
« Respuesta #2 en: 10 de Septiembre de 2005, 08:25:00 »
Exacto, controlando el LCD a 4 bits + 3 de control, todo en el puerto B, tienes el puerto A para configurarlo y usar comunicacion rs232 (y encima te sobran otras patas para lo que necesites). Sonrisa Gigante
Si juegas contra el mejor, pierdes como los demás.

Desconectado cereal2

  • PIC10
  • *
  • Mensajes: 26
RE: Mismo puerto para Datos de LCD y RX / TX, ¿cómo multiplexarlo?
« Respuesta #3 en: 10 de Septiembre de 2005, 10:33:00 »
Gracias por las posibles respuestas, pero os pido mil disculpas por no haberme especificado bien anteriormente, ya que no sabeis exactamente el problema que tengo, aquí os explico detalladamente.

De las posibles respuestas, las sabía, pero la placa pcb con sus componentes SMD ya soldados, de manera que no se puede modificar la circutería, que os adjunto la gráfica (circutería):



Si os fijais, la pata TX del PIC no está con los 4 bits del LCD, pero cuando un pic envia un caracter, envia primero los 4 bits de mayor peso, despues los otros 4 bits del menor peso. Entonces, el problema, es que aunque se envie los 4 bits solo, por el puerto se envia los 8 bits, por lo tanto, la pata RA5 / TX se envia algo por el puerto serie.

A ver si hay alguna solución por software. Una de las opciones que he pensado es poner el bit TX del PIC como entrada, y cada vez que tengo que enviar algo por TX, lo pongo como salida y luego vuelvo a poner como entrada, pero así no funciona correctamente. A ver si hay alguna solución por software más eficaz.

Gracias por adelantado!

Desconectado MGLSOFT

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 7912
RE: Mismo puerto para Datos de LCD y RX / TX, ¿cómo multiplexarlo?
« Respuesta #4 en: 10 de Septiembre de 2005, 10:49:00 »
Ahora si lo entiendo, aunque asi tambien estas mal, porque lo normal es que en el modo a 4 bits (mira las rutinas sino) se enmascaran los bits de mayor peso primero y se envia al puerto de datos, luego se rota 4 posiciones el dato y se vuelve a enviar enmascarado.
Tendras que revisar el valor con el cual enmascaras este dato, y si tiene (como lo tiene la funcion del driver que viene con CCS) una forma de armar una estructura que deje afuera los bits no utilizados.
Yo uso una forma similar, pero no comparto el puerto donde esta el bit del puerto serie....Sonrisa GiganteSonrisa GiganteSonrisa Gigante
Todos los dias aprendo algo nuevo, el ultimo día de mi vida aprenderé a morir....
Mi Abuelo.

Desconectado cereal2

  • PIC10
  • *
  • Mensajes: 26
RE: Mismo puerto para Datos de LCD y RX / TX, ¿cómo multiplexarlo?
« Respuesta #5 en: 10 de Septiembre de 2005, 17:28:00 »
Gracias MGLSOFT, pero en lugar de usar las librerías, las hago yo mismo en el programa principal para un mejor control y más preciso, os adjunto el código, con cada una de sus funciones:

Codigo:
void LCD_E (void)
{
   bit_set(puerto_a,1);
   delay_cycles(12);
   bit_clear(puerto_a,1);
   return;
}
void LCD_REG (void)
{
   bit_clear(puerto_a,3);
   bit_clear(puerto_a,2);
   puerto_b=registro_w;
   delay_us(100);
   LCD_E();
   return;
}
void LCD_DATOS (void)
{
   bit_set(puerto_a,3);
   puerto_b=registro_w;
   delay_us(100);
   LCD_E();
   return;
}
void LCD_DATOS2 (void)
{
   swap(registro_w);
   LCD_DATOS();
   swap(registro_w);
   LCD_DATOS();
   return;
}
   
void LCD_INI (void)
{
   registro_w=0x0E;
   LCD_REG();
   delay_ms(20);
   registro_w=0x03;
   LCD_REG();
   delay_ms(6);
   registro_w=0x03;
   LCD_REG();
   delay_ms(1);
   registro_w=0x03;
   LCD_REG();
   delay_ms(6);
   registro_w=0x02;
   LCD_REG();
   registro_w=0x02;
   LCD_REG();
   delay_ms(7);
   registro_w=0x08;
   LCD_REG();
   delay_ms(7);
   registro_w=0x00;
   LCD_REG();
   delay_ms(7);
   registro_w=0x08;
   LCD_REG();
   delay_ms(7);
   registro_w=0x00;
   LCD_REG();
   delay_ms(7);
   registro_w=0x01;
   LCD_REG();
   delay_ms(7);
   registro_w=0x00;
   LCD_REG();
   delay_ms(7);
   registro_w=0x06;
   LCD_REG();
   delay_ms(7);
   registro_w=0x00;
   LCD_REG();
   delay_ms(7);
   registro_w=0x0C;
   LCD_REG();
   delay_ms(7);
   return;
}



Codigo:
void config_ports(void)  
{
    delay_cycles(3);

    set_tris_a(0x00);    
    set_tris_b(0x20);    // en el TX pongo entrada para no enviar nada al hyperterminal al enviar un caracter, se pone como salida en el momento de enviar (enviar_serie())

//    bit_clear(puerto_a,3);       // RS=0 (modo instruccion)
//    bit_clear(puerto_a,1);       // E=0  (señal enable)

   ansel=0x00;       // todas las puertas como digital
    adcon_1=0x00;                

    osccon=0x6C;                 // configuración para 4 MHz
    delay_ms(10);    // espera minima de 4 ms para acabar de configurar el reloj interno (pag 41 de datasheet)
    option_reg=0x80;
    delay_ms(10);            

    puerto_a=0;
    puerto_b=0;

  return;
}


Codigo:
void inicio_USART (void)
{

                bit_set(txsta,2);      //BGRH=1 (velocidad alta)
                bit_clear(txsta,4);      //SYNC=0 (modo asíncrono)
   bit_set(txsta,5);      //TXEN=1 (habilita transmisión)
   bit_clear(txsta,6);     //TX9=0  (modo de 8 bits)
   bit_clear(rcsta,1);
   bit_clear(rcsta,2);
   bit_clear(rcsta,3);
   bit_set(rcsta,4);      //CREN=1 (habilita recepción)
   bit_clear(rcsta,6);     //RX900  (modo de 8 bits)

      //TX<-0  (salida), RX<-1 (entrada)

   spbrg=0x19;           //9.600 baudios (25 en decimal)

//   bit_set(rcsta,7);      //SPEN=1 (habilita puerto serie)
}


void enviar_serie(char c)     //envia un caracter
{
   int saltar=0;

   set_tris_b(0x00);       //TX como salida
   bit_set(rcsta,7);      //SPEN=1 (habilita puerto serie)

   do
   {
        if (bit_test(txsta,1)) saltar++;
   }while(!saltar);
   txreg=c;   


   bit_clear(rcsta,7);      //SPEN=0 (deshabilita puerto serie)
   set_tris_b(0x20);       //TX como entrada, para no enviar transmitir nada al enviar un caracter por PORT_B

}

char recibir_serie (void)     //recibe un caracter
{
   char c;
   int saltar=0;

   bit_set(rcsta,7);      //SPEN=1 (habilita puerto serie)
    set_tris_b(0x24);     //bit 2 del puerto B como entrada  (RB2,RX)

   do
   {
      if (bit_test(pir1,5)) saltar++;
   }while(!saltar);
    c=rcreg;
    registro_w=c;

    set_tris_b(0x20);                //dejamos como estaba el puerto B
    enviar_serie(c);                //hace "ECO" en el hyperterminal
   bit_clear(rcsta,7);               //SPEN=0 (deshabilita puerto serie)

   return c;
}



Tal como se ve en el código, a lahora de enviar un caracter por lcd, lo envio por todo el puerto, supongo que para arreglar (enviar solo 4 bits), ¿como es posible enviar por un puerto los 4 bits de golpe?

También intento solucionar poniendo como entrada la pata TX por derfecto, asi despues, cada vez que tenga que enviar algo por puerto serie, lo configuro como salida y vuelgo a poner como entrada una vez enviado. Pienso que es una buena solucion, pero no funciona muy bien.

Gracias!

Desconectado MGLSOFT

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 7912
RE: Mismo puerto para Datos de LCD y RX / TX, ¿cómo multiplexarlo?
« Respuesta #6 en: 12 de Septiembre de 2005, 06:53:00 »
Cuando envias por el puerto estas enviando los 8 bits, deberas hacer un XOR (que me corrijan si me equivoco) con los ultimos estados necesarios en el resto del puerto, para evitar enviar cosas por el serial que no necesites enviar...
Todos los dias aprendo algo nuevo, el ultimo día de mi vida aprenderé a morir....
Mi Abuelo.

Desconectado MGLSOFT

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 7912
RE: Mismo puerto para Datos de LCD y RX / TX, ¿cómo multiplexarlo?
« Respuesta #7 en: 12 de Septiembre de 2005, 07:21:00 »
Mejor haz esto:

    output_bit ( LCD_D4, cX & 0x01 );
    output_bit ( LCD_D5, cX & 0x02 );
    output_bit ( LCD_D6, cX & 0x04 );
    output_bit ( LCD_D7, cX & 0x08 );

las dos veces que envies el dato al LCD, luego del Swap del byte cX (reemplazalo por el nombre de tu byte) y los bits del puerto por el nombre o directamente la direccion que les has dado.

Esta forma no es intrusiva respecto al puerto de comunicacion...Sonrisa GiganteSonrisa GiganteSonrisa Gigante
Todos los dias aprendo algo nuevo, el ultimo día de mi vida aprenderé a morir....
Mi Abuelo.

Desconectado cereal2

  • PIC10
  • *
  • Mensajes: 26
RE: Mismo puerto para Datos de LCD y RX / TX, ¿cómo multiplexarlo?
« Respuesta #8 en: 12 de Septiembre de 2005, 10:09:00 »
Ok, gracias, ahora mismo lo pruebo, a ver qué tal funciona. No sabía que existía la instrucción output_bit(pin, value).

Os diré algo.

Gracias.

Desconectado cereal2

  • PIC10
  • *
  • Mensajes: 26
RE: Mismo puerto para Datos de LCD y RX / TX, ¿cómo multiplexarlo?
« Respuesta #9 en: 12 de Septiembre de 2005, 11:40:00 »
Como había dicho que os contestaría, aquí teneis mi respuesta.

Pues mira, con la solución del output_bit(pin,value) es correcta, sólo para enviar unos determinados bits por un puerto, pero no soluciona mi problema, que por cierto, he descubierto que es un problema de hardware, que nada tiene que ver con el software.

Gracias de todas las maneras. CIAO!!!


 

anything