Autor Tema: problema xc8 y rutina para LCD  (Leído 2308 veces)

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

Desconectado lagruya

  • PIC16
  • ***
  • Mensajes: 204
problema xc8 y rutina para LCD
« en: 16 de Febrero de 2013, 00:54:53 »
venia demasiado bien con el ANSI C y xc8 hasta que me di contra la pared.
la cuestion es que con el fin de entender y poner en practica conceptos como punteros cadenas de caracteres, definiciones etc, me plantie el desafio de armarme una pequeña rutina para manejar un LCD de 16x2 (el gdm1602 para ser exactos) y ahi llego la pared, es decir no puedo descubrir donde la estoy pifiando, no puedo ni siquiera imprimir la letra A  :oops: no pude probar las funciones para cadenas de caracteres ni nada de lo que tanto me entusiasma.

el LCD lo configuro para 4 bits, no se si la secuencia de inicio esta bien.

este es el codigo:

Código: C
  1. /* ---------------------------------------------------------------------------
  2.  * File:   main.c
  3.  * Author: Lagruya
  4.  * Pic usado 16F88
  5.  * Created on 22 de enero de 2013, 11:12
  6.  * --------------------------------------------------------------------------*/
  7.  
  8. #include <xc.h>
  9. #include <stdio.h>
  10.  
  11.  
  12. /*-----configuracion de bits de configuracion para el pic 16f88 (fuses)----- */
  13. #pragma config BOREN = OFF, CPD = OFF, CCPMX = RB0, DEBUG = OFF, WRT = OFF, \
  14.                FOSC = INTOSCIO, MCLRE = OFF, WDTE = OFF, CP = OFF, LVP = OFF, \
  15.                PWRTE = OFF, IESO = ON, FCMEN = ON
  16. /*---------------------------------------------------------------------------*/
  17.  
  18. /*---definicion para el correcto funcionamiento de la funcion delayms y us---*/
  19. #define _XTAL_FREQ              8000000UL
  20. #pragma intrinsic(_delay)
  21. extern void _delay(unsigned long);
  22. #define __delay_us(x) _delay((unsigned long)((x)*(_XTAL_FREQ/4000000.0)))
  23. #define __delay_ms(x) _delay((unsigned long)((x)*(_XTAL_FREQ/4000.0)))
  24. /*---------------------------------------------------------------------------*/
  25.  
  26. /*-----Etiquetas para los puertos del pic segun su coneccion con el LCD------*/
  27.  
  28. #define LCDBus                  PORTA
  29. #define LCDenable               RA6
  30. #define LCDregisterselect       RA7
  31. #define LCDdata4                RA0
  32. #define LCDdata5                RA1
  33. #define LCDdata6                RA2
  34. #define LCDdata7                RA3
  35.  
  36. #define mascara         0b11110000 // comentar si se usa nibble alto para LCD
  37. //#define mascara         0b00001111 // descomentar si se usa nibble bajo
  38. /*#define mascaraH    /* descomentar si se usa el nibble alto del
  39.                           * puerto para comunicarce con el LCD */
  40.  
  41. #define mascaraH    >> 4 /* comentar si se usa el nibble alto del puerto para
  42.                           * comunicarce con el LCD */
  43.  
  44. /*#define mascaraL  << 4 /* idem mascaraH */
  45. #define mascaraL      /* idem mascaraH */
  46.  
  47. /*---------------------------------------------------------------------------*/
  48.  
  49. /*------------------------Etiquetas comandos LCD-----------------------------*/
  50.  
  51. #define borrapantalla           (0b00000001)
  52. #define cursor_home             (0b00000010)
  53. #define cursor_der_LCDquieto    (0b00000110)
  54. #define LCD_off                 (0b00001000)
  55. #define LCD_on                  (0b00001111)
  56. #define cursor_off              (0b00001100)
  57. #define cursor_on               (0b00001110)
  58. #define cursor_parpadeo_off     (0b00001110)
  59. #define cursor_parpadeo_on      (0b00001111)
  60. #define _2lineas4bits5x7        (0b00101000)
  61. #define direccionDDRAM_0x08     (0b10001000)
  62.  
  63. /*---------------------------------------------------------------------------*/
  64.  
  65. /*------------------------Declaracion de funciones---------------------------*/
  66.  
  67. void inicializaLCD(void); // funcion para inicializa LCD
  68. void enviacomando(unsigned char); // funcion para enviar comando al LCD
  69. void enviadato(unsigned char); // funcion que enviara los datos al LCD
  70. void imprime_cadena_literal(const unsigned char *); /* funcion para imprimir
  71.                                                      * en el LCD una cadena
  72.                                                      * literal de caracteres */
  73. void imprime_cadena(unsigned char *);   /* funcion para imprimir un dato
  74.                                          * numerico convertido a cadena de
  75.                                          * caracteres */
  76.  
  77.  
  78. void conf_oscilador (void); // Configuracion del oscilador
  79. void conf_puertos (void);   // Configuracion de puertos I/O
  80.  
  81.  
  82.  
  83. /*---------------------CUERPO PRINCIPAL DEL PROGRAMA-------------------------*/
  84.  
  85. int main(void) {
  86.  
  87.     conf_oscilador ();
  88.     conf_puertos ();
  89.    
  90.  
  91.     RA4 = 1;
  92.     __delay_ms(1000);
  93.     RA4 = 0;
  94.     inicializaLCD();
  95.     LCDregisterselect = 1;
  96.     enviadato(0b01000001);
  97.     RA4 = 1;
  98.     while (1)
  99.     {
  100.         continue;  // bucle infinito, se queda esperando por interrupciones
  101.     }
  102.        
  103.        
  104.  
  105. }
  106.  
  107. /*------------------------------FUNCIONES------------------------------------*/
  108.  
  109. /* Funcion para la configuracion del oscilador del pic16f88 */
  110. void conf_oscilador (void) {
  111.  
  112.     OSCCONbits.IRCF2 = 1;
  113.     OSCCONbits.IRCF1 = 1;
  114.     OSCCONbits.IRCF0 = 1; // IRCF <2:0> = 111 setea Fosc 8MHz
  115.  
  116.     OSCCONbits.SCS1 = 0;
  117.     OSCCONbits.SCS0 = 0; /* SCS <1:0> = 00 Modo del oscilador definido por
  118.                           * FOSC <2:0> en #pragma config FOSC = INTOSCIO */
  119. }
  120. /* Funcion para la configuracion de los puertos entrada salida del pic 16f88 */
  121. void conf_puertos (void) {
  122.  
  123.     ANSEL = 0;          // registro ANSEL = 0 no se usan puertos analogicos
  124.     TRISA = 0b00100000; /* RA0-4 y RA6-7 como salidas */
  125.     TRISB = 0b11111111; // todo el puerto B como entradas
  126.     PORTA = 0;
  127. }
  128.  
  129.  
  130. void inicializaLCD(void){   // inicializacion de LCD seteo para bus de 4 bits
  131.  
  132.     LCDenable = 0;
  133.     LCDregisterselect = 0;
  134.  
  135.     LCDBus &= mascara;      // pone a 0 los 4 bits de datos
  136.     LCDBus |= (0b00100000 mascaraH);   // inicio secuencia de seteo 4bits
  137.     LCDenable = 1;          // habilita transmision
  138.     __delay_us(5);
  139.     LCDenable = 0;
  140.  
  141.     enviadato(0b00101000);//envio en 2 partes la confirmacion de comando 4 bits
  142.  
  143.     enviadato(0b00000110);  //comando display quieto incrementa cursor
  144.  
  145.     enviadato(0b00001110);  //comando LCD on Cursor on
  146.  
  147. }
  148.  
  149. void enviacomando(unsigned char comando){
  150.  
  151.     LCDregisterselect = 0;
  152.     enviadato(comando);
  153.  
  154. }
  155.  
  156. void enviadato(unsigned char datoLCD){
  157.  
  158.     unsigned char nibbleH;
  159.     unsigned char nibbleL;
  160.  
  161.     nibbleH = (datoLCD & 0b11110000) mascaraH;
  162.     /* se obtiene el nibble alto de datoLCD si se usa el nibble bajo del puerto
  163.      * mascaraH "corre" los 4 bits mas significativos al lugar de los menos
  164.      * significativos */
  165.  
  166.     nibbleL = (datoLCD & 0b00001111) mascaraL;
  167.     /* se obtiene el nibble bajo de datoLCD ...*/
  168.  
  169.     LCDBus &= mascara;
  170.     LCDBus |= nibbleH;     // se transmite al LCD el nibble alto de datoLCD
  171.     LCDenable = 1;         // se habilita el LCD para que procese LCDBus
  172.     __delay_us(5);        // retardo para garantizar pasaje de datos al LCD
  173.     LCDenable = 0;         // se deshabilita el LCD
  174.  
  175.     LCDBus &= mascara;
  176.     LCDBus |= nibbleL;     // se transmite al LCD el nibble bajo de datoLCD
  177.     LCDenable = 1;         // se habilita el LCD para que procese LCDBus
  178.     __delay_us(5);        // retardo para garantizar pasaje de datos al LCD
  179.     LCDenable = 0;         // se deshabilita el LCD
  180.  
  181.     if (LCDregisterselect)  // retardo segun tarea del LCD
  182.         __delay_us(50);     // escritura RAM del LCD
  183.     else
  184.         __delay_ms(2);      // comando
  185.  
  186.  
  187. }
  188.  
  189. void imprime_cadena(unsigned char *buffer){  /* *buffer es un puntero que apunta
  190.                                              *  a la posicion de memoria donde
  191.                                              * comienza la matriz de caracteres
  192.                                              * o lo que es lo mismo: es el
  193.                                              * nombre de la matriz  */
  194.  
  195.         LCDregisterselect = 1;  /* se prepara el LCD para escribir en la
  196.                                      * DDRAM */
  197.         while(*buffer)  /* siempre que *bufer sea un valor verdadero hasta que
  198.                          * sea NULL (el final de la matriz de caracteres) */
  199.         {
  200.  
  201.                 enviadato(*buffer); /* se le pasa el char alojado en la
  202.                                      * direccion *bufer a la funcion
  203.                                      * enviadato*/
  204.                 buffer++;   /* se incrementa en 1 la direccion para enviar el
  205.                              * siguiente caracter de la cadena */
  206.         }
  207. }
  208.  
  209. void imprime_cadena_literal(const unsigned char *buffer){
  210. /* *buffer es un puntero que apunta a la posicion de memoria donde comienza la
  211.  * matriz de caracteres o lo que es lo mismo: es el nombre de la matriz, que en
  212.  * este caso se pasa como un argumento literal a la funcion  */
  213.  
  214.         LCDregisterselect = 1;  /* se prepara el LCD para escribir en la
  215.                                      * DDRAM */
  216.         while(*buffer)  /* siempre que *bufer sea un valor verdadero hasta que
  217.                          * sea NULL (el final de la matriz de caracteres) */
  218.         {
  219.  
  220.                 enviadato(*buffer); /* se le pasa el char alojado en la
  221.                                      * direccion *bufer a la funcion
  222.                                      * enviadato*/
  223.                 buffer++;   /* se incrementa en 1 la direccion para enviar el
  224.                              * siguiente caracter de la cadena */
  225.         }
  226. }
  227.  
  228. /*---------------------------------------------------------------------------*/

saludos

Desconectado lagruya

  • PIC16
  • ***
  • Mensajes: 204
Re: problema xc8 y rutina para LCD
« Respuesta #1 en: 18 de Febrero de 2013, 19:18:51 »
ejem... :oops:

el codigo no tiene problema....

el problema lo tenia el maldito ajuste de contraste!!!!!!! ajjjjj las horas....
en 1V anda bien

en fin igualmente recomiendo para usar con xc8 la rutina lcd_pic16.c que subio el sr todopic, esta bien completa, documentada y se tiene un control del LCD mas que amplio.

saludos.


 

anything