lunes, 24 de octubre de 2011

Hola Mundo con pic16f887 y LCD JHD 162A (PIC C CCS)

Sencillo programa para desplegar algo en una flamante pantalla lcd de 16x2 usando un pic 16f887


#include <16f887.h>                   //Nuestro pic
#use delay (clock=8000000)            //Fosc=8Mhz
#include <lcd.c>                      //Libreria de la lcd


void main()
{
   setup_oscillator(OSC_8MHZ|OSC_INTRC);  //Programamos oscilador interno del Pic a 8MHZ
   set_tris_b(0);                         //Puerto B como salida
   lcd_init();                            //Inicializamos LCD
   lcd_putc("Hola Mundo");                //"Hola Mundo"
   while(1)
   {
      delay_ms(10);                       //Esperamos a lo sonso 10 ms
      output_toggle(PIN_B5);              //Parpadeamos Led, output_toggle cambia el estado logico del pin pasado de parametro
      delay_ms(250);                     //Esperamos a lo sonso 250 ms
   }
}
He aqui el esquemático:


Descargas:

DSC para Isis Proteus: DSN Proteus ISIS
Codigo .c para Pic C de CCS (PCWHD): CodigoC

Fotuca de mi circuito

49 comentarios:

  1. muy buen post. Lo probaré. Gracias

    ResponderEliminar
  2. Y como borro pantalla del LCD?' no lo puedo hacer

    ResponderEliminar
    Respuestas
    1. Para borrar manda:
      lcd_putc("\f");

      Para salto de línea es:
      lcd_putc("\n");

      Son caracteres de escape, chécalos..
      Saludos

      Eliminar
  3. hola que tal en mi pantalla salen todos los cuadrigatos negros en la seccion 1x16 y de ahí no pasa nada que estaré haciendo mal????

    ResponderEliminar
    Respuestas
    1. Me suena a que está algo mal con la resolución de tu pantalla, tienes bien conectado el potenciómetro en el pin VEE de tu LCD?

      Eliminar
  4. No se si fue porque yo utilice otro pic(16f886) pero tuve que definir los pins en el archivo lcd.c
    // define the pinout.
    // only required if port access is being used.
    #define LCD_ENABLE_PIN PIN_A0 ////
    #define LCD_RS_PIN PIN_A1 ////
    #define LCD_RW_PIN PIN_A2 ////
    #define LCD_DATA4 PIN_A4 ////
    #define LCD_DATA5 PIN_A5 ////
    #define LCD_DATA6 PIN_A6 ////
    #define LCD_DATA7 PIN_A7

    de otro modo solo me salian cuadritos. pero me ayudo mucho tu tutorial, saludos!

    ResponderEliminar
    Respuestas
    1. Es muy posible, que bueno que lo mencionas por si alguien usa ese pic, sólo hay que revisar el.h del pic a usar y es todo.
      Saludos ;)

      Eliminar
  5. quiero hacer con un teclado como hago
    para poder escribir en el lcd

    ResponderEliminar
    Respuestas
    1. Con mucho esfuerzo.....

      No, ya en serio, puedes usar un teclado de computadora PS2 conectado al puerto serial del PIC

      info aqui:
      http://laimbio08.escet.urjc.es/assets/files/docencia/DCSE/dcse_p8_ps2.pdf

      O puedes comprar o construir un teclado matricial (4x4 por lo general, es decir 16 teclas) y conectarlo a todo un puerto del PIC, por ejemplo, al puerto A.

      Son solo dos ejemplos sencillos pero por alli puedes empezar a buscarle.

      Saludos

      Eliminar
  6. Hola, muy buen post. Tengo una duda. ¿como le haria para mover de izquierda a derecha el texto.

    Saludos cordiales

    ResponderEliminar
    Respuestas
    1. Bonjour.
      Bueno, eso no lo hace una función específica, tendrías que idearte la manera de hacerlo.

      Si checas el codigo de lcd.c está la siguiente función:

      void lcd_gotoxy( BYTE x, BYTE y)

      Puedes usarla para desplazarte por la lcd.

      por ejemplo para desplazarte por la primera linea:

      while(1)//Bucle while principal
      {
      for(i=16; i>=0; i--)
      {
      lcd_gotoxy(i,1);
      lcd_putc("Hola Mundo");
      }
      lcd_putc("\f");//Borras
      delay_ms(100);//Esperas
      }

      Create un codigo bonito y ni tienes tiempo nos lo compartes!!!

      Saludos!

      Eliminar
  7. ya cargue el programa e igual ya hice las conexiones pero solo prende el lcd y do6 y do7 en donde fue mandada la conexion es que el diagrama muestra otra cosa por eso hago la pregunta si eres amable de contestarme. porfa

    ResponderEliminar
    Respuestas
    1. Disculpa, no logro entender lo que me estas preguntando

      Eliminar
  8. por que pones en el codigo como salida el puerto b en el codigo set_tris_b(0) y en el diagrama las salidas son el puerto D?????:(

    ResponderEliminar
    Respuestas
    1. Una vez que agregar la librería de la lcd y ejecutas la función lcd_init(); no necesitas declarar nada mas para el puerto D.

      El set_tris_b(0) que coloqué allí es para el led.

      (NOTA: checate el codigo de la librería lcd.c para que veas en vivo que hace cada función y en cado caso si quieres modificar el puerto allí puedes hacerlo)

      Saludos

      Eliminar
  9. Una pregunta donde puedo checar la libreria lcd?

    ResponderEliminar
    Respuestas
    1. El compilador de PIC C de CCS busca las librerías en:

      Para x64: "C:\Program Files (x86)\PICC\Drivers\"
      Para x86: "C:\Program Files\PICC\Drivers\"

      Y los .h de los PICS en:
      Para x64: "C:\Program Files (x86)\PICC\Devices\"
      Para x86: "C:\Program Files\PICC\Devices\"

      Saludos.

      Eliminar
  10. hola!! estoy programando una lcd 16x2 pero el profe me pide que despliegue un mensaje mayor a 16 caracteres ya busque por todos lados y no encuentro como hacerle... alguna sugerencia? te adjunto el codigo

    void main()
    {
    int i;
    lcd_init();
    setup_adc_ports(NO_ANALOGS);
    setup_adc(ADC_OFF);
    setup_psp(PSP_DISABLED);
    setup_spi(FALSE);
    setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
    setup_timer_1(T1_DISABLED);
    setup_timer_2(T2_DISABLED,0,1);
    setup_comparator(NC_NC_NC_NC);
    setup_vref(FALSE);

    printf (LCD_PUTC, "\f"); // limpia la LCD

    while(1)
    {
    for (i=16; i>=1; --i)
    {
    lcd_gotoxy (i,1);
    printf (LCD_PUTC, "Universidad Tecnologica");
    delay_ms(1500);
    }

    for (i=16; i>=1; --i)
    {
    lcd_gotoxy (i,2);
    printf (LCD_PUTC, "TSU Mecatronica.");
    delay_ms(1500);
    }

    printf (LCD_PUTC, "\f"); // limpia la LCD

    }

    }

    ResponderEliminar
    Respuestas
    1. Hola MariAngel.

      La verdad, podrías usar algun tipo de corrimiento de letras, o desplegar el mensaje por partes, no estoy seguro que exista alguna librería ya creada para ese fin, tendrías que apañartelas.

      Tu codigo funciona?, por lo que leo parece que podría funcionar en dos partes, primero moviendo el letrero superior (linea superior) y después el inferior...

      Saludos

      Eliminar
  11. Hola que tal?
    Me podrías ayudar por favor …..
    Armé un circuito con un PIC16f88 y un LCD JHD162A.
    El caso es que para ahorrar costos no le puse potenciómetro para controlar el contraste lo mandé directo a tierra, al principio funciono pero de repente uno solo se ven puntitos negros en la línea 1 y en otros ya no se ve nada.
    Que hago?
    Le pongo un potenciómetro de 10k oms con corriente +5 y tierra y el centro al VEE
    O
    Te puedo mandar mi esquema o diagrama para que me puedas ayudar a checarlo y corregirlo
    Porque tengo muchas dudas.
    GRACIAS Y FELICIDADES

    ResponderEliminar
    Respuestas
    1. Hola Oscar Mora.
      Te recomiendo colocar un potenciometro para regularlo, en especial si tu fuente de poder es susceptible a variaciones bruscas y caidas de voltaje ("si estas usando un cargador de celular que no da la corriente que necesitas por ejemplo").

      Si tu fuente de poder es suficientemente estable mandarlo directo a tierra o colocar un arreglo de resistencias debería ser suficiente.

      Saludos

      Eliminar
    2. Te agradezco la pronta respuesta.....
      Pues mira, en mi circuito tengo las dos fuentes de energía (baterías y un cargador de 9V), cuando falla el cargador entran las baterías. Actualmente lo tengo directo(el contraste) a tierra, y falla, de hecho con las baterías aparecen los puntitos y antes no aparecían. Pienso que ya se daño.
      ¿Como podría probarlo que aun funciona?

      Pensé en ponerle un capacitor pero de cuanto y como?
      y
      Me dices "Arreglo de resistencia" como serian y de cuanto?

      Una disculpa como te podraz dar cuanto soy medio lentón para esto y como estoy empezando..... pues por eso soy tan pregunton y pido ayuda

      G R A C I A S

      Eliminar
    3. Si las baterías estan dando mas voltaje puedes haber dañado la lcd...
      acerca del arreglo de resistencias.

      Primero conecta el potenciometro al pin de contraste de la lcd, coloca el potenciometro en el valor deseado.

      Mide la resistencia del pin de en medio del poteciometro a un extremo, y despues del pin de en medio al otro, esos valores de resistencia (o aproximados) son las que necesitas.

      Colocas las resistencias en forma de "Divisor de voltaje" con los valores de resistencias obtenidos.

      http://upload.wikimedia.org/wikipedia/commons/d/db/Resistive_divider.png

      recalco: Necesitas una fuente de voltaje estable,

      Eliminar
  12. UN FAVOR, ME PODRIAS DECIR COMO SE GRABA UN PIC16F88

    ResponderEliminar
    Respuestas
    1. Lo siento abraham sarango guarnizo, es una pregunta muy vaga, es como si me preguntaras como pudes conducir un auto.

      Hay muchas maneras de programar un Microcontrolador y la mayoría dependen del programador que estes usando (Pickit, MasterProg, programadores DIY opensource, programadores universales).

      http://www.diylife.com/2008/02/15/program-a-pic-microcontroller/

      http://articulo.mercadolibre.com.mx/MLM-425820485-master-prog-_JM

      http://www.microchip.com/stellent/idcplg?IdcService=SS_GET_PAGE&nodeId=1406&dDocName=en538340&redirects=pickit3

      Si estas iniciando en el mundo de los microcontroladores podrías checar primero un buen libro:

      * http://books.google.fr/books?id=CB9GaAU1dwsC&printsec=frontcover&dq=microcontrollers+pic&hl=es&sa=X&ei=kWjeUdSQBsXSsgbB-YHoCw&redir_esc=y

      * http://books.google.fr/books?id=pdbf2HuMzREC&printsec=frontcover&dq=microcontrollers+pic&hl=es&sa=X&ei=kWjeUdSQBsXSsgbB-YHoCw&redir_esc=y


      Saludos y Éxito.

      Eliminar
  13. Por fin !!!!! no encontraba la pagina para darte las gracias .....
    Mi lcd funciona perfectamente..... GRACIAS...
    Pero ahora tengo otro problema.
    Me podrás ayudar...???

    En ya tengo todo funcionando, mi programa, mi circuito y todo
    Pero...
    al probarlo ya en vivo, resulta que el reloj se ataraza.... :(
    ya lo moví todo al programa y no logro que este a tiempo..
    Encontré en la red que con un cristal de cuarzo externo funciona bien, y bueno, ya lo instale en Proteus en la pata 15 y 16.... y me la he pasado intentando configurarlo y nada no puedo...
    me puedes ayudar oscarmora_2000@yahoo.com.mx
    Ya le movi al archivo *.h, al 16h88, al *.c y solo logré casi ahorcar al monitor, y la verdad nadie como tu para apoyarlo a uno.
    Si gustas a vuelta de correo te envió mis archivos y el diseño en proteus, para que así en vivo veas donde la estoy regando, digo si se puede.
    He rastreado mucho en la red tratando de encontrar la forma de hacerlo y nada.
    De antemano te agradezco la atención a mi solicitud (ruego)
    SALUDOS ;)

    ResponderEliminar
  14. Muchas gracias me sirvió de mucho amigo :D

    ResponderEliminar
  15. Que tal, intento usar la libreria de lcd pero a la hora de compilar me sale que existen errores en la librería, set_tris_lcd(LCD_READ); es esta parte es el error, espero y me puedas ayudar

    ResponderEliminar
  16. Disculpa como podria hacer que lo que aparece en la pantalla aparezca de letra por letra o corrimiento de letras o las letras separadas por favor podrías ayudarme

    ResponderEliminar
    Respuestas
    1. Hola.
      Para hacer eso tienes que crear tu propia funcion.

      Algo sencillo como:
      lcd_putc("H");
      delay_ms(10);
      lcd_putc("\f");
      lcd_putc("Ho");
      delay_ms(10);
      lcd_putc("\f");
      lcd_putc("Hol");
      delay_ms(10);
      lcd_putc("\f");
      lcd_putc("Hola");
      delay_ms(10);
      lcd_putc("\f");
      lcd_putc("Hola ");
      delay_ms(10);
      lcd_putc("\f");
      lcd_putc("Hola Mundo");

      O algo mas complicado y util como guardar la palabra en un array, usar un for para recorrerlo e irlo mostrando poco a poco.
      Arriba alguien me pregunto casi lo mismo

      Saludos.

      Eliminar
    2. si vi eso pero cuando quieres poner varios palabras como por ejemplo: en una sola linea hacer que aparesca el nombre de una persona recorra todo letra x letra y despues terminando aparesca otro nombre diferente como podria hacerlo la vdd no se mucho de programacion pero me han pedido hacer esto y pues hize lo que tu en la explicacion pero me confundi al ponerlo todos los nombres

      Eliminar
    3. Lo siento amigo lo que pides es algo basico en electronica digital pero no podria ayudarte por ahora (por tiempo).

      Si realmente no tienes experiencia en Microcontroladores y Progra Basica te recomiendo leer antes unos cuantos libros (los pongo abajo)

      El segundo trae una explicacion de la libreria precompilada LCD de mikroC, podrias intentar.

      1.- http://books.google.com.mx/books?id=pdbf2HuMzREC&printsec=frontcover&dq=pic&hl=es&sa=X&ei=ssxsU66CBubT8gGKioGwDQ&ved=0CHcQ6AEwCQ#v=onepage&q=pic&f=false

      2.- http://books.google.com.mx/books?id=NPSQShtCQaUC&printsec=frontcover&dq=pic&hl=es&sa=X&ei=ssxsU66CBubT8gGKioGwDQ&ved=0CFYQ6AEwBQ#v=onepage&q=pic&f=false


      Es lo mas que puedo hacer :)

      Saludos.

      Eliminar
    4. de ante mano muchas gracias amigo por tomarte la molestia en ayudarme gracias saludos :)

      Eliminar
  17. ola oye ya compile tu programa de "hola mundo" pero solo prende el display en el isis proteus y ya revise el codigo pero no se que pase espero y puedas ayudarme

    ResponderEliminar
    Respuestas
    1. Pareciera que no esta corriendo el software del PIC. Estas seguro que estas montando bien el .hex al PIC en ISIS??

      Eliminar
  18. Hazael podrias ayudarme con mi codigo? no quiere funcionar el teclado ni la lcd no se si es por librerias o que pasa. El codigo es para el control de acceso con clave.

    #include<16f887.h>
    #FUSES NODEBUG //Debugger Mode - Desactivado
    #FUSES NOLVP //Low-Voltage Programming - Desactivado
    #FUSES NOBROWNOUT //Brown-out Reset - Desactivado
    #FUSES NOCPD //Data EE Memory Code Protection - Desactivado
    #FUSES NOPROTECT //Program Memory Write Protected - Desactivado
    #FUSES PUT //Power Up Timer - Activado
    #FUSES NOWDT //WatchDogTimer - Desactivado
    #FUSES XT //Oscillator <= 4 Mhz
    #FUSES NOWRT //Flash Program Memory Write - Desactivado
    #use delay(clock=4000000) //Frecuencia del cristal para el cálculo de los retardos
    #rom 0x2100={'2','8','8','4','2','3'}

    #define use_portb_kbd TRUE //Habilitamos la lectura del Teclado por el Puerto B
    #include //Libreria para el manejo del teclado

    #define Uno 0x1
    #define Dos 0x2
    #define Tres 0x3
    #define CarA 0xA
    #define Cuatro 0x4
    #define Cinco 0x5
    #define Seis 0x6
    #define CarB 0xB
    #define Siete 0x7
    #define Ocho 0x8
    #define Nueve 0x9
    #define CarC 0xC
    #define Asterisco 0xE
    #define Cero 0x0
    #define Numeral 0xF
    #define CarD 0xD


    void Configura() { //Configura el microcontrolador para el hardware
    kbd_init(); //Funcion para inicializar el uso del teclado
    port_b_pullups(TRUE); //Habilita las Resistecias Pull-up del Puerto B
    output_c(0x00); //Limpia el puerto C
    set_tris_c(0x00); //Puerto C como salidas
    }
    void main() { //Programa principal

    char C; //Declaracion de la Variable ?C? de tipo char
    int i; //Declaracion de la variable i de tipo int
    char data[6],clave[6];//matrices para guardar clave y datos
    aqui_1:
    output_low(PIN_C0);
    output_low(PIN_C2);//Led verde=off
    output_high(PIN_C1);//Led Rojo=on
    delay_ms(10000);


    Configura(); //Llama ala funcion Configura
    while(TRUE) {

    i=0; //posición de la matriz

    while(i<=5){ //Para 6 datos
    C=kbd_getc(); //Lee el teclado
    if (C!=0) //Si se ha pulsado alguna tecla
    {
    data[i]=C; //se guarda en la posición correspondiente
    i++; //de la matriz

    }
    }
    for (i=0;i<=5;i++) { //Pasa datos de eeprom a la matriz clave
    clave[i]=read_eeprom(i);}

    if ((data[0]==clave[0])&&(data[1]==clave[1])&&(data[2]==clave[2])&&(data[3]==clave[3])&&(data[4]==clave[4])&&(data[5]==clave[5]))
    //compara digito a digito los valores almacenados en la EEPROMy la clave
    // introducida
    {
    output_low(PIN_C1); //Led Rojo=off
    output_high(PIN_C0);//Abre la cerradura con pulso al relé
    output_high(PIN_C2);//Led Verde=on
    delay_ms(3000);
    output_low(PIN_C0);//Cierra la cerradura con pulso al relé
    output_low(PIN_C2);//Led Verde=off
    output_high(PIN_C1);//Led Rojo=on
    delay_ms(2000);
    }
    else {
    goto aqui_1;
    }
    }
    }//Fin Programa principal

    ResponderEliminar
    Respuestas
    1. Hola felipe.
      Por desgracia no tengo el compilador en estos momentos.

      Los fusibles parecen estar bien, pero yo recomendaria, hacer un test por partes?
      El codigo tu lo hiciste o lo sacaste de algun lugar?.

      1.- Deja solo fuses y el bloque main().
      Dentro de main coloca el codigo suficiente para hacer parpadear un led.
      Asi te aseguras que compila bien y el PIC jala bien.

      2.- agrega codigo poco a poco.
      i.e. primero el teclado e imprime algo por puerto serial.
      Recomiendo ampliamente que debuggees por puerto serial con algun serial monitor (como el de arduino), solo ocupas un FTDI y un puerto USB de tu PC.

      https://www.sparkfun.com/products/9716

      Saludos.

      Eliminar
  19. Disculpen me pueden ayudar estoy haciendo un proyecto en el cual. al presionar tal numero de veces un boton , me salga en la lcd el numero de veces apretado ese boton.

    ResponderEliminar
    Respuestas
    1. Hola.

      Modificando un poco el codigo de arriba y con las mismas conexiones pero agregando el push button y suponiendo que tu Push Button esta en el PIN A1 en Pull Down (abierto a tierra, cerrado a vcc)

      Este codigo deberia servirte.

      #include <16f887.h> //Nuestro pic
      #use delay (clock=8000000) //Fosc=8Mhz
      #include //Libreria de la lcd


      void main()
      {
      unsigned int x;
      setup_oscillator(OSC_8MHZ|OSC_INTRC); //Programamos oscilador interno del Pic a 8MHZ
      set_tris_b(0); //Puerto B como salida
      lcd_init(); //Inicializamos LCD
      lcd_putc("Hola Mundo"); //"Hola Mundo"
      x = 0;
      while(1)
      {
      if(input(PIN_A1))
      {//Suponiendo que el push-button esta en el PIN A1 en configuracion pull down
      x += 1;
      lcd_putc('\f'); //Limpia LCD
      printf(LCD_PUTC, "%u",x); //Imprime valor
      }
      delay_ms(10); //Esperamos a lo sonso 10 ms
      output_toggle(PIN_B5); //Parpadeamos Led, output_toggle cambia el estado logico del pin pasado de parametro
      delay_ms(250); //Esperamos a lo sonso 250 ms
      }
      }

      Eliminar
  20. Respuestas
    1. Se supone que está en el link de arriba, donde dice DSC para Isis Proteus

      Eliminar
  21. disculpa y si quiero usar el pic 18f4550 es lo mismo?

    ResponderEliminar
  22. como seria el codigo para MPLAB sim??? Alguien me puede ayudar porfa

    ResponderEliminar
  23. como realizo el codigo de la pantalla lcd con el I2C que muestre el nombre y un contador

    ResponderEliminar