Problemas con Display LCD en CCS

En una LCD 4X20, debes construir tus propios caracteres e importarlos a la GRAM de la lcd.

Para generar caracteres puedes utilizar este programa, que es totalmente gratuito(y)
Solo debes construir el caracter, que quieres que se muestra cuando esta encendido,y se va generar un codigo en c, este lo debes copiar y pegar en tu codigo.





Y este es otro que trabaja de la misma manera
 

Adjuntos

  • Captura.PNG
    Captura.PNG
    16.1 KB · Visitas: 20
  • lcdcc.zip
    435.6 KB · Visitas: 30
  • ejecutable y ejemplos.rar
    20.4 KB · Visitas: 28
  • Captura1.PNG
    Captura1.PNG
    39.5 KB · Visitas: 19
Muchas gracias, Anderson.
Voy hacer un mensaje de bienvenida y cuando ejecute el programa salga la imagen de Microchip y Xbee que son los dispositivos que estoy trabajando.



También modifiqué un poco mi código.
Inicia un saludo dentro al menú con # y muestra que con cero miramos el estado de las entradas puerto c y del 1 al 8 control prende y apaga los led.
Pero me parece muy ineficiente. Me gustaría organizarlo mejor con la ayuda de ustedes.
 

Adjuntos

  • Entradas y Salidas.rar
    97.4 KB · Visitas: 16
Última edición:
Muchas gracias, Anderson.
Voy hacer un mensaje de bienvenida y cuando ejecute el programa salga la imagen de Microchip y Xbee que son los dispositivos que estoy trabajando.



También modifiqué un poco mi código.
Inicia un saludo dentro al menú con # y muestra que con cero miramos el estado de las entradas puerto c y del 1 al 8 control prende y apaga los led.
Pero me parece muy ineficiente. Me gustaría organizarlo mejor con la ayuda de ustedes.
No tienes una simulación de tu proyecto para yo probarlo en mi PC!;)
 
Si que pena tuve algunos inconvenientes con mi torpeza pero ojala no los vuelva a cometer, mis disculpas al foro y a todos ustedes.
Trabaje toda la semana en mi proyecto y tengo un problema con un while (TRUE) que le adicione a mi código para que se estuviera preguntando por el estado de la entrada cuando se oprimiera el pulsador mostrara el cambio en la lcd en el mismo instante eso creo un bucle infinito en el cual no pudo salir para poder regresar a menú o encenderlos led que tengo en el (port D) las entradas las tengo por el (port C).
Les adjunto el código y la simulación en proteus.
Código:
#include <16f877a.h>
#use     delay(crystal = 4MHz)

#define use_portb_kbd TRUE
#include <KBD96.c>
#include <LCD420.c>
#include <stdlib.h>

#define  LED_1  PIN_D0
#define  LED_2  PIN_D1
#define  LED_3  PIN_D2
#define  LED_4  PIN_D3
#define  LED_5  PIN_D4
#define  LED_6  PIN_D5
#define  LED_7  PIN_D6
#define  LED_8  PIN_D7

#define ENTRADA1 PIN_C0
#define ENTRADA2 PIN_C1
#define ENTRADA3 PIN_C2
#define ENTRADA4 PIN_C3
#define ENTRADA5 PIN_C4
#define ENTRADA6 PIN_C5

void mostrar_menu(){
lcd_gotoxy(3,1);
printf(lcd_putc,"\fMENU PRINCIPAL\r");
lcd_gotoxy(1,2);
printf(lcd_putc,"0 ESTADO PUERTO C ");
lcd_gotoxy(1,3);
printf(lcd_putc,"1,2,3,4,5,6,7,8");
lcd_gotoxy(1,4);
printf(lcd_putc,"CONTROL OFF/ON DE LED");
}

void funcion_led_1(){
output_toggle(LED_1);
   if (input_state(LED_1))
 printf(lcd_putc,"\fLed 1 encendido");
   else
 printf(lcd_putc,"\fLed 1 apagado");
}

void funcion_led_2(){
output_toggle(LED_2);
   if (input_state(LED_2))
printf(lcd_putc,"\fLed 2 encendido");
   else
printf(lcd_putc,"\fLed 2 apagado");
}
void funcion_led_3(){
output_toggle(LED_3);
   if (input_state(LED_3))
printf(lcd_putc,"\fLed 3 encendido");
   else
printf(lcd_putc,"\fLed 3 apagado");
}


void funcion_led_4(){
output_toggle(LED_4);
   if (input_state(LED_1))
printf(lcd_putc,"\fLed 4 encendido");
   else
printf(lcd_putc,"\fLed 4 apagado");
}

void funcion_led_5(){
output_toggle(LED_5);
   if (input_state(LED_5))
printf(lcd_putc,"\fLed 5 encendido");
   else
printf(lcd_putc,"\fLed 5 apagado");
}

void funcion_led_6(){
output_toggle(LED_6);
   if (input_state(LED_6))
printf(lcd_putc,"\fLed 6 encendido");
   else
printf(lcd_putc,"\fLed 6 apagado");
}

void funcion_led_7(){
output_toggle(LED_7);
   if (input_state(LED_7))
printf(lcd_putc,"\fLed 7 encendido");
   else
printf(lcd_putc,"\fLed 7 apagado");
}

void funcion_led_8(){
output_toggle(LED_8);
   if (input_state(LED_8))
printf(lcd_putc,"\fLed 8 encendido");
   else
printf(lcd_putc,"\fLed 8 apagado");
}

void funcion_lectura_entradas(){
lcd_gotoxy(1,1);
printf(lcd_putc,"\fINPUT1=%u",input(ENTRADA1));
lcd_gotoxy(1,2);
printf(lcd_putc,"INPUT2=%u",input(ENTRADA2));
lcd_gotoxy(1,3);
printf(lcd_putc,"INPUT3=%u",input(ENTRADA3));
lcd_gotoxy(11,1);
printf(lcd_putc,"INPUT4=%u",input(ENTRADA4));
lcd_gotoxy(11,2);
printf(lcd_putc,"INPUT5=%u",input(ENTRADA5));
lcd_gotoxy(11,3);
printf(lcd_putc,"INPUT6=%u",input(ENTRADA6));
lcd_gotoxy(1,4);
printf(lcd_putc,"REGRESO MENU PULSE #");
}

void main () 
{
CHAR k;

   lcd_init();
   kbd_init();
   port_b_pullups(TRUE);
 
   output_low(LED_1),(LED_2),(LED_3),(LED_4),(LED_5),(LED_6),(LED_7),(LED_8);
   lcd_gotoxy(1,1);
   printf(lcd_putc,"Bienvenidos (^^,)");
   lcd_gotoxy(1,2);
   printf(lcd_putc,"Pulsa # para ir menu");
   
   while (kbd_getc()!='#'){};
   mostrar_menu();

   while (true)
   {
      k = kbd_getc();
      
      if (k!=0)
         switch(k)
         {
         case '0':
   while (TRUE){
            delay_ms(500);
            funcion_lectura_entradas();
            k = kbd_getc();
            if (k!=0)
            break;
   }
         case '1':
            funcion_led_1();
            break;    // Brake ya no se coloca al final de la selección.
         case '2':
            funcion_led_2();
            break;
            case '3':
            funcion_led_3();
            break;
            case '4':
            funcion_led_4();
            break;
            case '5':
            funcion_led_5();
            break;
            case '6':
            funcion_led_6();
            break;
            case '7':
            funcion_led_7();
            break;
            case '8':
            funcion_led_8();
            break; 
            case '#':
            mostrar_menu();
            break;
         }
   }
}
 

Adjuntos

  • Entradas y salidas.rar
    99.3 KB · Visitas: 28
Pues no lo chusmie a fondo, pero creo que el segundo while(TRUE) esta de mas, ya que con la funcion swich te quedas esperando para ver a que caso saltar, en todo caso si quieres volver al sensado tendrias que ponerlo mas arriba, otra opcion seria hacer uso del repeat.
 
Pues no lo chusmie a fondo, pero creo que el segundo while(TRUE) esta de mas, ya que con la funcion swich te quedas esperando para ver a que caso saltar, en todo caso si quieres volver al sensado tendrias que ponerlo mas arriba, otra opcion seria hacer uso del repeat.

gracias juanma por explicarme el error, entonces la solución estaría en poner el repeat en el void funcion_lectura_entradas() que puse para revisar las entradas las actualizaría en milisegundos para ver el cambio cuando se pulse.

Código:
void funcion_lectura_entradas(){
lcd_gotoxy(1,1);
printf(lcd_putc,"\fINPUT1=%u",input(ENTRADA1));
lcd_gotoxy(1,2);
printf(lcd_putc,"INPUT2=%u",input(ENTRADA2));
lcd_gotoxy(1,3);
printf(lcd_putc,"INPUT3=%u",input(ENTRADA3));
lcd_gotoxy(11,1);
printf(lcd_putc,"INPUT4=%u",input(ENTRADA4));
lcd_gotoxy(11,2);
printf(lcd_putc,"INPUT5=%u",input(ENTRADA5));
lcd_gotoxy(11,3);
printf(lcd_putc,"INPUT6=%u",input(ENTRADA6));
lcd_gotoxy(1,4);
printf(lcd_putc,"REGRESO MENU PULSE #");
}
Me podarías dar un ejemplo es que no pude solucionarlo.
 
Última edición:
Hola gracias por su ayuda e avanzado enormemente pero algo no me funciona bien que no pude solucionar.

Resulta que en mi código cuando oprimo 'C' reviso las entradas con visualización su estado si están en 0 y 1 normalmente funciona pero me di cuenta que no se actualizaba el estado de la entrada hasta que se volviera a oprimir 'C'. Comencé a
buscar la solución pero se me complico generando errores.

Con un while (TRUE) que le adicione en el case 'C' para que se estuviera preguntando por el estado de la entrada y cuando se oprimiera el pulsador mostrara el cambio al instante en la lcd, pero eso creo un bucle infinito en el cual no pude salir para poder regresar a menú o encender los led que tengo en el (port D).
Esto le adicione pero lo elimine.
Código:
  switch(k)
         {
         case 'C':
   while (TRUE){
            delay_ms(500);
            funcion_lectura_entradas();
            k = kbd_getc();
            if (k!=0)
            break;
   }

Después me recomendaron poner un REPEAT mas arriba del void pero la verdad no encontré ningún ejemplo para esa función.
Estoy realizando un menú y sub menú e llegado a este punto gracias a todos ustedes gracias por su ayuda. :apreton:

Código:
#include <16f877a.h>
#use     delay(crystal = 4MHz)

#define  LCD_ENABLE_PIN PIN_A0
#define  LCD_RS_PIN     PIN_A1
#define  LCD_RW_PIN     PIN_A2
#define  LCD_DATA4      PIN_B4
#define  LCD_DATA5      PIN_B5
#define  LCD_DATA6      PIN_B6
#define  LCD_DATA7      PIN_B7

#include "lcd420ap.c"
#include <kbd_lib.c>

#define  LED_1  PIN_D0
#define  LED_2  PIN_D1
#define  LED_3  PIN_D2
#define  LED_4  PIN_D3
#define  LED_5  PIN_D4
#define  LED_6  PIN_D5
#define  LED_7  PIN_D6
#define  LED_8  PIN_D7

#define ENTRADA1 PIN_C0
#define ENTRADA2 PIN_C1
#define ENTRADA3 PIN_C2
#define ENTRADA4 PIN_C3
#define ENTRADA5 PIN_C4
#define ENTRADA6 PIN_C5

void mostrar_menu(){
lcd_gotoxy(1,1);
printf(lcd_putc,"\f>A ENTRADA ANALOGICA\r");
lcd_gotoxy(1,2);
printf(lcd_putc,">B CONTROL PWM");
lcd_gotoxy(1,3);
printf(lcd_putc,">C ENTRADAS DIGITALES");
lcd_gotoxy(1,4);
printf(lcd_putc,">D SALIDAS DIGITALES");
}

void funcion_lectura_entradas_analogas(){
lcd_gotoxy(1,1);
printf(lcd_putc,"\fpendiente entradas");
lcd_gotoxy(1,2);
printf(lcd_putc,"analoga y visualizar");
}

void funcion_pwm(){
printf(lcd_putc,"\fpendiente el PWM");
}

void funcion_control_salidas_digitales(){
lcd_gotoxy(1,1);
printf(lcd_putc,"\fFalta panel de");
lcd_gotoxy(1,2);
printf(lcd_putc,"Control para los led");
}

void funcion_led_1(){
output_toggle(LED_1);
   if (input_state(LED_1))
 printf(lcd_putc,"\fLed 1 encendido");
   else
 printf(lcd_putc,"\fLed 1 apagado");
}

void funcion_led_2(){
output_toggle(LED_2);
   if (input_state(LED_2))
printf(lcd_putc,"\fLed 2 encendido");
   else
printf(lcd_putc,"\fLed 2 apagado");
}

void funcion_led_3(){
output_toggle(LED_3);
   if (input_state(LED_3))
printf(lcd_putc,"\fLed 3 encendido");
   else
printf(lcd_putc,"\fLed 3 apagado");
}

void funcion_led_4(){
output_toggle(LED_4);
   if (input_state(LED_1))
printf(lcd_putc,"\fLed 4 encendido");
   else
printf(lcd_putc,"\fLed 4 apagado");
}

void funcion_led_5(){
output_toggle(LED_5);
   if (input_state(LED_5))
printf(lcd_putc,"\fLed 5 encendido");
   else
printf(lcd_putc,"\fLed 5 apagado");
}

void funcion_led_6(){
output_toggle(LED_6);
   if (input_state(LED_6))
printf(lcd_putc,"\fLed 6 encendido");
   else
printf(lcd_putc,"\fLed 6 apagado");
}

void funcion_led_7(){
output_toggle(LED_7);
   if (input_state(LED_7))
printf(lcd_putc,"\fLed 7 encendido");
   else
printf(lcd_putc,"\fLed 7 apagado");
}

void funcion_led_8(){
output_toggle(LED_8);
   if (input_state(LED_8))
printf(lcd_putc,"\fLed 8 encendido");
   else
printf(lcd_putc,"\fLed 8 apagado");
}

void funcion_lectura_entradas_digitales(){
lcd_gotoxy(1,1);
printf(lcd_putc,"\fINPUT1=%u",input(ENTRADA1));
lcd_gotoxy(1,2);
printf(lcd_putc,"INPUT2=%u",input(ENTRADA2));
lcd_gotoxy(1,3);
printf(lcd_putc,"INPUT3=%u",input(ENTRADA3));
lcd_gotoxy(11,1);
printf(lcd_putc,"INPUT4=%u",input(ENTRADA4));
lcd_gotoxy(11,2);
printf(lcd_putc,"INPUT5=%u",input(ENTRADA5));
lcd_gotoxy(11,3);
printf(lcd_putc,"INPUT6=%u",input(ENTRADA6));
lcd_gotoxy(1,4);
printf(lcd_putc,"REGRESO MENU PULSE #");
}

void main () 
{
CHAR k;

   lcd_init();
   kbd_init();
   port_b_pullups(TRUE);
   output_low(LED_1),(LED_2),(LED_3),(LED_4),(LED_5),(LED_6),(LED_7),(LED_8);
   lcd_gotoxy(2,2);
   printf(lcd_putc,"Bienvenidos  (^^,)");
   lcd_gotoxy(1,3);
   printf(lcd_putc,"Pulsa # para ir menu");
   
   while (kbd_getc()!='#'){};
   mostrar_menu();

   while (true)
   {
      k = kbd_getc();
      
      if (k!=0)
         switch(k)
         {
         case 'A':
            funcion_lectura_entradas_analogas();
           break;
         case 'B':
            funcion_pwm();
            break;
         case 'C':
            funcion_lectura_entradas_digitales();
           break;
         case 'D':
            funcion_control_salidas_digitales();
           break;
         case '1':
            funcion_led_1();
            break;
         case '2':
            funcion_led_2();
           break;
         case '3':
            funcion_led_3();
           break;
         case '4':
            funcion_led_4();
            break;
         case '5':
            funcion_led_5();
           break;
         case '6':
            funcion_led_6();
           break;
         case '7':
            funcion_led_7();
           break;
         case '8':
            funcion_led_8();
           break; 
         case '#':
            mostrar_menu();
           break;
         }
   }
}
 

Adjuntos

  • menu ccs.rar
    45.5 KB · Visitas: 18
Resulta que en mi código cuando oprimo 'C' reviso las entradas con visualización su estado si están en 0 y 1 normalmente funciona pero me di cuenta que no se actualizaba el estado de la entrada hasta que se volviera a oprimir 'C'.
Comencé a buscar la solución pero se me complico generando errores.
¿Y si lo haces por medio de interrupciones?
Por ejemplo, las del puerto B por cambio de estado en RB4:RB7.

Adjunto un ejemplo que no realiza exactamente lo de tu programa, pero es similar y te puede dar ideas.
 

Adjuntos

  • 16F877A Menú LCD.rar
    38.3 KB · Visitas: 32
hola amigos, tengo un problema con la libreria FLEX_LCD.c como hago para limpiar la pantalla del LCD despues de haber escrito unas lineas o como borrar una de las lineas y escribir algo nuevo, porque lo intento hacerlo y se escribe encima .... uso pic ccs , que comando tengo que usar ???? o que codigo me permite borrar esas lineas escritas??.... gracias
 

Adjuntos

  • Cinco encoders con un solo PIC CCS C.zip
    3.3 KB · Visitas: 19
Si vas a mostrar una valor numérico, puedes usar %0x donde x es la cantidad de dígitos a mostrar.
Pero no escribas %x, porque eso no define la cantidad de dígitos.

Por ejemplo: printf(lcd_putc,"Valor: %04lu",cantidad); // Muestra una cifra de 4 dígitos.

PD:
Por defecto todos los puertos son entradas, así que los set_tris_x(0b11111111); salen sobrando.

Esto no tiene caso:
Código:
   set_tris_b(0b11111111);        //Todo el puerto B como entradas.
   set_tris_c(0b11111111);        //Todo el puerto C como entradas.

Y toda esta configuración inicial tampoco sirve de nada, pues no estás usando esos módulos.
Código:
   port_b_pullups(FALSE);
   setup_adc_ports(NO_ANALOGS);
   setup_adc(ADC_CLOCK_DIV_2);
   setup_spi(SPI_SS_DISABLED);
   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);

Todo eso no es necesario que lo tengas en tu proyecto.

Si después piensas usar alguno de eso módulos, ya lo puedes usar y configurar.
Y te conviene usar las resistencias pull-up del puerto B para los encoders, y no deshabilitarlas.

Suerte.

 
Última edición:
D@rkbytes hola digame por favor si puede decirme como limpiar las lineas en un lcd cuando estas ya han sido escritas??? osea quiero que siga saliendo nuevos mensajes en las lineas pero las anteriores no se como limpiarlas o borrarlas

uso como libreria el archivo c flex_lcd.c
alguna sugerencia por favor ? le adjunto el archivo flex_lcd y parte del codigo como ejemplo que estoy desarrollando.

Código:
include <16f877a.h>
#include <flex_lcd.c>

#fuses XT, NOWDT , NOPROTECT,NOPUT,BROWNOUT,NOLVP,NOCPD,NOWRT
#use delay (clock=4000000)
//#use fast_io(B)// usa el puerto B no define en la posicion de memoria 
//#use standard_io(b)// confi el micro dela mejor manera
//#use standard_io(a) 

void main(){

  lcd_init();
  delay_ms(10);
while(1){
   lcd_gotoxy(1,1);
   lcd_putc("RENZO LCD");
   lcd_gotoxy(1,2);
   lcd_putc("Prueba de CoD");
   delay_ms(2000);
   printf(lcd_putc,"f " ) ;
   lcd_gotoxy(1,1);
   delay_ms(10);
   lcd_putc("Upp....Tronic");

}


}
 

Adjuntos

  • flex_lcd.rar
    1.8 KB · Visitas: 17
Para limpiar la pantalla se usa: "\f"

Esto viene explicado el la librería "lcd.c" de PIC C Compiler:
lcd_init() Must be called before any other function.
\a Set cursor position to upper left
\f Clear display, set cursor to upper left
\n Go to start of second line
\b Move back one position
lcd_gotoxy(x,y) Set write position on LCD (upper left is 1,1)
lcd_getc(x,y) Returns character at position x,y on LCD
lcd_cursor_on(int1 on) Turn the cursor on (on=TRUE) or off (on = FALSE)
lcd_set_cgram_char(w, *p) Write a custom character to the CGRAM.

Y algunos de esos comandos como: (\f) también sirven para la librería "flex_lcd.c"
flex_lcd.c dijo:
void lcd_putc(char c)
{
switch(c)
{
case '\f':
lcd_send_byte(0,1);
delay_ms(2);
break;
...
 
D@rkbytes MUCHAS gracias amigo... yo vengo del codigo Ansi C y con el compilador HITECH alli era poner LCD_CLEAR() O LCD_puts(" ") Y LISTO , entonces se me hacia algo difícil ahora entender y aprender los mandos en PIC CCS , había visto lo que me indicabas pero no sabia como ponerlo para que me de resultado, bueno haciendo pruebas con el código ejemplo que puse y tus indicaciones entendí mejor como usarlo para pic ccs ,

reitero mis agradecimientos y si cause alguna molestia disculpa pues pense que habia puesto mi aviso en el foro indicado no me percate que decia arduino en esa seccion :oops: , disculpas nuevamente, y gracias por todo (Y) (y)
 
Hola buenos dias n.n, soy nuevo en esto de programar y mi programa si compila pero al momento que lo simulo en proteus no realiza nada, no se si me podrian ayudar de ante mano gracias,( el programa esta a la mitad solo quiero que el valor medido sea visible en el lcd)
Código:
#include <16f877a.h>
#use delay(clock=4000000)
#include <LCD.C>
#fuses XT,NOWDT,NOPROTECT,NOLVP,PUT,BROWNOUT
#use standard_io(b)


int valor=0x00;

void toma_adc(void){

// Lectura del canal 0
set_adc_channel(0);
delay_ms(1);
valor=read_adc();
delay_ms(1); //para que se estabilice
}



void main()
{
float x;

setup_adc(ADC_CLOCK_INTERNAL); //configura el converso
setup_adc_ports(RA0_analog); //entrada 0 como analogica

   while(true);
   {
   toma_adc();
   output_b(valor);
   
   lcd_init();
   
   for (;;) {
   set_adc_channel(0);  
    delay_us(400);
    x = read_adc();                 
   delay_us(400);
  lcd_gotoxy(1,1);
  printf(lcd_putc, "\\f Voltaje= %6ld",x);
  delay_ms(100);
   }
}
}

circuito.jpg
...
 

Adjuntos

  • circuito.jpg
    circuito.jpg
    187.6 KB · Visitas: 16
muy facil

PHP:
#include <16f877a.h>
#use delay(clock=4000000)
#include <LCD.C>
#fuses XT,NOWDT,NOPROTECT,NOLVP,PUT,BROWNOUT
#use standard_io(b)


int16 valor=0;

void toma_adc(void){

// Lectura del canal 0
//set_adc_channel(0);
delay_us(20);
valor=read_adc();
//delay_ms(1); //para que se estabilice
}



void main()
{
float x;

setup_adc(ADC_CLOCK_INTERNAL); //configura el converso
setup_adc_ports(RA0_analog); //entrada 0 como analogica
set_adc_channel(0);  

lcd_init();

   while(true);
   {
   toma_adc();
   output_b(valor);
   
   
   
   //for (;;) {   // este bucle infinito no va ya fue declarado en el while true 
   //set_adc_channel(0);  
   // delay_us(400);
    x = read_adc();                 
   delay_us(400);
  lcd_gotoxy(1,1);
  printf(lcd_putc,"\f Voltaje= %6ld",x);
  delay_ms(100);
   //}
}
}
 
mi programa si compila, pero al momento que lo simulo en proteus, no realiza nada
Ese programa está muy mal, parte ya lo corrigió TRILO-BYTE, pero aún tiene un problema por el cual nunca llegará a mostrarse nada en la pantalla.

En esta parte se genera un bucle que no permitirá que el programa continúe:
PHP:
   while(true);
   {
   toma_adc();
   ...
Ten en cuenta que si la instrucción while (true); termina con punto y coma, se genera un bucle sin fin en si misma.
Ese es el problema principal de tu programa, los otros, es la forma en que estás usando las variables.

int equivale a una variable de 16 bits y el puerto B tan sólo es de 8 bits.
x es una variable del tipo Float y se debe mostrar por ejemplo, así para dos decimales a la derecha: %0.2f

También debes especificar con cuantos bits va a funcionar el ADC, ya que por defecto el compilador establece 8 bits.
Esto se hace en la cabecera del programa, escribiendo por ejemplo: #device ADC = 10 // 10 Bits

El programa que realizaste es básico, pero aquí te lo dejo funcional y de forma simplificada.
PHP:
#include <16f877a.h>
#device  adc = 8
#use     delay(crystal = 4MHz)
#include <lcd.c>

void main()
{
   int8 valor;
   float x;

   setup_adc(ADC_CLOCK_INTERNAL);   // Usar el reloj interno para el ADC
   setup_adc_ports(AN0);            // Establecer el canal 0
   set_adc_channel(0);              // Seleccionar el canal 0
   delay_us(50);                    // Retardo de 50 us.

   lcd_init();                      // Inicializar la pantalla.
   
   while(true)                      // Iniciar el bucle principal.
   {
      valor = read_adc();           // Leer el canal 0 (Canal seleccionado anteriormente)
      
      output_b(valor);              // Puerto B = valor de "valor" (8 Bits)

      x = (valor * 5.0 / 256);      // Realizar una conversión para determinar el voltaje de entrada.        
      lcd_gotoxy(1,1);
      printf(lcd_putc,"Voltaje = %0.2f",x);
      delay_ms(100);
   }
}
Suerte.
 
Saludos a todos.
Estoy tratando de visualizar unas variables en un LCD de 2x8 utilizando un PIC16F88.
Por ahora quiero probar con palabras.

He usado el compilador PIC C de CCS y una librería llamada flex_lcd, pero no me funciona, no sé si es problema de la librería (Quizá sea sólo para LCD2x16) o no sé qué será.

Me gustaría que me pudieran ayudar.
Muchas gracias de antemano.

Código principal:
PHP:
#include <16F88.h>
#fuseS XT,NOWDT //HS
#use delay (clock=31000)//31k 0x00


#include <flex_lcd.c>
void main()
{
lcd_init();  
   while(true) 
   {
   
    lcd_putc("linea1");
    lcd_gotoxy(1,2);
    lcd_putc("linea2");
   }
 }
Librería flex_lcd:
PHP:
// flex_lcd.c

// These pins are for the Microchip PicDem2-Plus board,
// which is what I used to test the driver.  Change these
// pins to fit your own board.

#define LCD_DB4   PIN_B4
#define LCD_DB5   PIN_B5
#define LCD_DB6   PIN_B6
#define LCD_DB7   PIN_B7
//
#define LCD_RS    PIN_B3
#define LCD_RW    PIN_B1
#define LCD_E     PIN_B2

// If you only want a 6-pin interface to your LCD, then
// connect the R/W pin on the LCD to ground, and comment
// out the following line.

#define USE_LCD_RW   1

//===========================
#define lcd_type 2        // 0=5x7, 1=5x10, 2=2 lines
#define lcd_line_two 0x40 // LCD RAM address for the 2nd line


int8 const LCD_INIT_STRING[4] =
{
 0x20 | (lcd_type << 2), // Func set: 4-bit, 2 lines, 5x8 dots
 0xc,                    // Display on
 1,                      // Clear display
 6                       // Increment cursor
 };


//-------------------------------------
void lcd_send_nibble(int8 nibble)
{
// Note:  !! converts an integer expression
// to a boolean (1 or 0).
 output_bit(LCD_DB4, !!(nibble & 1));
 output_bit(LCD_DB5, !!(nibble & 2));
 output_bit(LCD_DB6, !!(nibble & 4));
 output_bit(LCD_DB7, !!(nibble & 8));

 delay_cycles(1);
 output_high(LCD_E);
 delay_us(2);
 output_low(LCD_E);
}

//-----------------------------------
// This sub-routine is only called by lcd_read_byte().
// It's not a stand-alone routine.  For example, the
// R/W signal is set high by lcd_read_byte() before
// this routine is called.

#ifdef USE_LCD_RW
int8 lcd_read_nibble(void)
{
int8 retval;
// Create bit variables so that we can easily set
// individual bits in the retval variable.
#bit retval_0 = retval.0
#bit retval_1 = retval.1
#bit retval_2 = retval.2
#bit retval_3 = retval.3

retval = 0;

output_high(LCD_E);
delay_cycles(1);

retval_0 = input(LCD_DB4);
retval_1 = input(LCD_DB5);
retval_2 = input(LCD_DB6);
retval_3 = input(LCD_DB7);

output_low(LCD_E);

return(retval);
}
#endif

//---------------------------------------
// Read a byte from the LCD and return it.

#ifdef USE_LCD_RW
int8 lcd_read_byte(void)
{
int8 low;
int8 high;

output_high(LCD_RW);
delay_cycles(1);

high = lcd_read_nibble();

low = lcd_read_nibble();

return( (high<<4) | low);
}
#endif

//----------------------------------------
// Send a byte to the LCD.
void lcd_send_byte(int8 address, int8 n)
{
output_low(LCD_RS);

#ifdef USE_LCD_RW
while(bit_test(lcd_read_byte(),7)) ;
#else
delay_us(60);
#endif

if(address)
   output_high(LCD_RS);
else
   output_low(LCD_RS);

 delay_cycles(1);

#ifdef USE_LCD_RW
output_low(LCD_RW);
delay_cycles(1);
#endif

output_low(LCD_E);

lcd_send_nibble(n >> 4);
lcd_send_nibble(n & 0xf);
}

//----------------------------
void lcd_init(void)
{
int8 i;

output_low(LCD_RS);

#ifdef USE_LCD_RW
output_low(LCD_RW);
#endif

output_low(LCD_E);

delay_ms(15);

for(i=0 ;i < 3; i++)
   {
    lcd_send_nibble(0x03);
    delay_ms(5);
   }

lcd_send_nibble(0x02);

for(i=0; i < sizeof(LCD_INIT_STRING); i++)
   {
    lcd_send_byte(0, LCD_INIT_STRING[i]);

    // If the R/W signal is not used, then
    // the busy bit can't be polled.  One of
    // the init commands takes longer than
    // the hard-coded delay of 60 us, so in
    // that case, lets just do a 5 ms delay
    // after all four of them.
    #ifndef USE_LCD_RW
    delay_ms(5);
    #endif
   }

}

//----------------------------

void lcd_gotoxy(int8 x, int8 y)
{
int8 address;

if(y != 1)
   address = lcd_line_two;
else
   address=0;

address += x-1;
lcd_send_byte(0, 0x80 | address);
}

//-----------------------------
void lcd_putc(char c)
{
 switch(c)
   {
    case '\f':
      lcd_send_byte(0,1);
      delay_ms(2);
      break;

    case '\n':
       lcd_gotoxy(1,2);
       break;

    case '\b':
       lcd_send_byte(0,0x10);
       break;

    default:
       lcd_send_byte(1,c);
       break;
   }
}

//------------------------------
#ifdef USE_LCD_RW
char lcd_getc(int8 x, int8 y)
{
char value;

lcd_gotoxy(x,y);

// Wait until busy flag is low.
while(bit_test(lcd_read_byte(),7));

output_high(LCD_RS);
value = lcd_read_byte();
output_low(lcd_RS);

return(value);
}
#endif

void lcd_setcursor_vb(short visible, short blink) { 
  lcd_send_byte(0, 0xC|(visible<<1)|blink); 
}
PD: Los pines que configuré al inicio para el LCD coinciden con la conexión en la protoboard.

Atte. Cesar Beltrán.
 
Atrás
Arriba