Autor Tema: LCD en CCS con PIC16F877A  (Leído 1843 veces)

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

Desconectado Rocio

  • PIC10
  • *
  • Mensajes: 7
LCD en CCS con PIC16F877A
« en: 23 de Agosto de 2015, 19:33:27 »
Hola, estoy haciendo un programa con el PIC16F877A en el que necesito utilizar el LCD e interrupción por RB0. El problema es que por algún motivo en la libreria del LCD del programa viene como predeterminado la utilizacion del puerto B para el LCD. Alguien puede explicarme como cambiarlo? Ya le hice de todo, cambie a comentario a linea #define use_portb_lcd TRUE, agregue estas lineas al programa:
#define  LCD_ENABLE_PIN PIN_D0
#define  LCD_RS_PIN PIN_D1
#define  LCD_RW_PIN PIN_D2
#define  LCD_TYPE 2
Y sigue saliendo por el puerto B

Saludos!

Desconectado RALF2

  • Moderadores
  • PIC24H
  • *****
  • Mensajes: 2060
Re: LCD en CCS con PIC16F877A
« Respuesta #1 en: 23 de Agosto de 2015, 19:50:19 »
Lo puedes hacer de esta forma:

Citar
#define LCD_ENABLE_PIN  PIN_D0                                   
#define LCD_RS_PIN      PIN_D1                             
#define LCD_RW_PIN      PIN_D2                                   
#define LCD_DATA4       PIN_D4                                   
#define LCD_DATA5       PIN_D5                                   
#define LCD_DATA6       PIN_D6                                   
#define LCD_DATA7       PIN_D7                         
#include <lcd.c>


Saludos

Desconectado Rocio

  • PIC10
  • *
  • Mensajes: 7
Re: LCD en CCS con PIC16F877A
« Respuesta #2 en: 24 de Agosto de 2015, 18:17:03 »
Gracias por contestar RALF2, probe y no funciona. Ya no se que mas hacer con esto :8} :8} :8}

Desconectado RALF2

  • Moderadores
  • PIC24H
  • *****
  • Mensajes: 2060
Re: LCD en CCS con PIC16F877A
« Respuesta #3 en: 24 de Agosto de 2015, 18:31:50 »
Hola Rocio, decirte que yo probe esa configuracion y por lo menos desde el proteus funciona perfectamente!
Puede que sea entonces un problema de hardware  :?
Prueba conectar la lcd entonces en el puerto B, a ver. 

Saludos

Desconectado Rocio

  • PIC10
  • *
  • Mensajes: 7
Re: LCD en CCS con PIC16F877A
« Respuesta #4 en: 24 de Agosto de 2015, 18:56:31 »
Pienso que el problema ya viene desde la libreria que vino con el programa. Estoy viendo si puedo usar otra, si hay alguna que me puedas recomendar, te agradezco.
Aca te dejo el programa que tengo hecho, a lo mejor detectas algun error que yo no vi:

///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
////                                                                       ////
////      ESTE PROGRAMA MIDE LA TENSION DE UN CIRCUITO EN DIFERENTES       ////
////      PUNTOS DE FORMA DIRECTA. PARA MEDIR LA POTENCIA Y LA COR-        ////
////      RIENTE (LO CUAL NOS INTERESA CONOCER) DE FORMA INDIRECTA.        ////
////      ESTO QUIERE DECIR QUE UTILIZANDO VALORES CONOCIDOS DE TEN-       ////
////      SION Y RESISTENCIAS PODEMOS AVERIGUAR LA POTENCIA EN UN          ////
////      PUNTO, LA CORRIENTE EN UNA CARGA Y LA TENSION DE RED (CON        ////
////      LA QUE SE ALIMENTA EL CIRCUITO.                                  ////
////      LA DIFERECIA ES QUE ESTE PROGRAMA NO MUESTRA DIRECTAMENTE        ////
////      LA MEDICION, SINO QUE LA MUESTRA AL PRESIONAR:                   ////
////      -RB4: LA CORRIENTE EN LA CARGA                                   ////
////      -RB5: LA POTENCIA EN LA CARGA                                    ////
////      -RB6: LA TENSION EN LA CARGA                                     ////
////      -RB7: ALGUNA OTRA COSA QUE SE QUIERA VISUALIZAR                  ////
////                                                                       ////
////                                                                       ////
////      PIC=16F877A             ¡¡¡AUN NO FUNCIONAAAA GRRRRRRR!!!        ////
////                                                                       ////
////       NOTA: AVERIGUAR COMO USAR LCD EN PUERTO D                       ////
////                                                                       ////
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////

#include <16f877a.h>
#device adc=10
#use delay(clock=4000000)
#define LCD_ENABLE_PIN  PIN_D0                                   
#define LCD_RS_PIN      PIN_D1                             
#define LCD_RW_PIN      PIN_D2                                   
#define LCD_DATA4       PIN_D4                                   
#define LCD_DATA5       PIN_D5                                   
#define LCD_DATA6       PIN_D6                                   
#define LCD_DATA7       PIN_D7                         
#include <lcd.c>
#use fast_io(A)
#byte trisb=0x86
#byte portb=0x06
#use fast_io(D)
#byte OPTION_REG=0X81

FLOAT VALOR_MEDIDO=0;      //  variables
float TENSION;             //
float CORRIENTE;           //  para
float POTENCIA;            //
float TENSION_CARGA=0;     //  medicion
float VALOR_MEDIDO_MAYOR=0;//
float valor_eficaz=0;      //  AD
float Valor2;              //
float TensionRed;          //  conversion
float Valor_eficaz_red;    //
float tension_AN1;         //  AD
float CORR2;               //
float tension_de_red;      //  y calculos
 
float RES=0.1;   //Valor de resistencia auxiliar
int a;    //variables auxiliares
int b;    // "         "

#int_RB
void mostrarLCD()
{
   if (bit_test(portb,4)==0){
      printf(lcd_putc,"\f   CORRIENTE:\n      %fA", CORRIENTE);
   }else if (bit_test(portb,5)==0){
      printf(lcd_putc,"\f   POTENCIA:\n     %fW", POTENCIA);
   }else if (bit_test(portb,6)==0){
      printf(lcd_putc,"\f TENSION CARGA:\n      %fV", TENSION_CARGA);
   }else if (bit_test(portb,7)==0){
      printf(lcd_putc,"\f QUE QUIERE QUE \n    MUESTRE");
   }
}

void main ()
{
   SETUP_ADC_PORTS(AN0_AN1_AN4_VREF_VREF);
   SETUP_ADC(ADC_CLOCK_INTERNAL);
   
   bit_clear(OPTION_REG,7);
   
   set_tris_A(0xFF);
   set_tris_B(0XFF);
   set_tris_d(0x00);
   
   enable_interrupts(int_RB);
   enable_interrupts(global);
     
   lcd_init();
   
   while (TRUE)
   {
      lcd_init();
      lcd_putc("\fMEDIDOR DE ENER-\nGIA: MIDIENDO.\n");
      delay_ms(100);
      lcd_putc("\fMEDIDOR DE ENER-\nGIA: MIDIENDO..\n");
      delay_ms(100);
      lcd_putc("\fMEDIDOR DE ENER-\nGIA: MIDIENDO...\n");
      delay_ms(100);
     
      for(a=0;a<250;a++)
      {
         
         
         
         SET_ADC_CHANNEL(0); //en AN0
         VALOR_MEDIDO=READ_ADC(ADC_START_AND_READ); //valor leido por AD
         if(VALOR_MEDIDO>VALOR_MEDIDO_MAYOR){
         
            VALOR_MEDIDO_MAYOR=VALOR_MEDIDO; //mayor tension medida en RES
           
            valor_eficaz=(VALOR_MEDIDO_MAYOR*0.707); //tension eficaz en RES
         }
         else
            VALOR_MEDIDO=READ_ADC(ADC_START_AND_READ); //valor que lee el AD
           
      }
      for(b=0;b<250;b++)
      {
         
         
         SET_ADC_CHANNEL(1); //en AN1
         Valor2=READ_ADC(ADC_START_AND_READ); //Valor que lee el conversor
         if(Valor2>TensionRed){
         
            TensionRed=Valor2;//mayor valor medido en R10k
           
            valor_eficaz_red=(TensionRed*0.707); //valor eficaz en R10k
         }
         else
            Valor2=READ_ADC(ADC_START_AND_READ);
           
      }
     
     
      TENSION=(5*(valor_eficaz/1024)); //CONVERSION AD - tension en RES
     
      Tension_AN1=(5*(valor_eficaz_red/1024)); //CONVERSION AD tension en R10k
     
      CORR2=Tension_AN1/10000; //corriente en cto en paralelo a la carga
     
      tension_de_red=CORR2*1010000; //tension de la red
     
      CORRIENTE=(TENSION/RES); //corriente en cto en serie con la carga
     
      TENSION_CARGA=Tension_de_red-TENSION; //tenion en la carga
     
      POTENCIA=(TENSION_CARGA*CORRIENTE); //potencia en la carga
     
     

   }
}


Además la librería de LCD que tengo yo, es decir la que vino con el programa:

///////////////////////////////////////////////////////////////////////////
////                             LCDD.C                                ////
////                 Driver for common LCD modules                     ////
////                                                                   ////
////  lcd_init()   Must be called before any other function.           ////
////                                                                   ////
////  lcd_putc(c)  Will display c on the next position of the LCD.     ////
////                     The following have special meaning:           ////
////                      \f  Clear display                            ////
////                      \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         ////
////                                                                   ////
///////////////////////////////////////////////////////////////////////////
////        (C) Copyright 1996,2007 Custom Computer Services           ////
//// This source code may only be used by licensed users of the CCS C  ////
//// compiler.  This source code may only be distributed to other      ////
//// licensed users of the CCS C compiler.  No other use, reproduction ////
//// or distribution is permitted without written permission.          ////
//// Derivative programs created using this software in object code    ////
//// form are not restricted in any way.                               ////
///////////////////////////////////////////////////////////////////////////

// As defined in the following structure the pin connection is as follows:
//     D0  enable
//     D1  rs
//     D2  rw
//     D4  D4
//     D5  D5
//     D6  D6
//     D7  D7
//
//   LCD pins D0-D3 are not used and PIC D3 is not used.

// Un-comment the following define to use port B
#define use_portb_lcd TRUE


struct lcd_pin_map {                 // This structure is overlayed
           BOOLEAN enable;           // on to an I/O port to gain
           BOOLEAN rs;               // access to the LCD pins.
           BOOLEAN rw;               // The bits are allocated from
           BOOLEAN unused;           // low order up.  ENABLE will
           int     data : 4;         // be pin B0.
        } lcd;


#if defined use_portb_lcd
   //#locate lcd = getenv("sfr:PORTB")    // This puts the entire structure over the port
   #ifdef __pch__
    #locate lcd = 0xf81
   #else
    #locate lcd = 6
   #endif
   #define set_tris_lcd(x) set_tris_b(x)
#else
   //#locate lcd = getenv("sfr:PORTD")    // This puts the entire structure over the port
   #ifdef __pch__
    #locate lcd = 0xf83
   #else
    #locate lcd = 8
   #endif
   #define set_tris_lcd(x) set_tris_d(x)
#endif

#ifndef lcd_type
#define lcd_type 2           // 0=5x7, 1=5x10, 2=2 lines
#endif

#define lcd_line_two 0x40    // LCD RAM address for the second line


BYTE const LCD_INIT_STRING[4] = {0x20 | (lcd_type << 2), 0xc, 1, 6};
                             // These bytes need to be sent to the LCD
                             // to start it up.


                             // The following are used for setting
                             // the I/O port direction register.

struct lcd_pin_map const LCD_WRITE = {0,0,0,0,0}; // For write mode all pins are out
struct lcd_pin_map const LCD_READ = {0,0,0,0,15}; // For read mode data pins are in



BYTE lcd_read_byte() {
      BYTE low,high;
      set_tris_lcd(LCD_READ);
      lcd.rw = 1;
      delay_cycles(1);
      lcd.enable = 1;
      delay_cycles(1);
      high = lcd.data;
      lcd.enable = 0;
      delay_cycles(1);
      lcd.enable = 1;
      delay_us(1);
      low = lcd.data;
      lcd.enable = 0;
      set_tris_lcd(LCD_WRITE);
      return( (high<<4) | low);
}


void lcd_send_nibble( BYTE n ) {
      lcd.data = n;
      delay_cycles(1);
      lcd.enable = 1;
      delay_us(2);
      lcd.enable = 0;
}


void lcd_send_byte( BYTE address, BYTE n ) {

      lcd.rs = 0;
      while ( bit_test(lcd_read_byte(),7) ) ;
      lcd.rs = address;
      delay_cycles(1);
      lcd.rw = 0;
      delay_cycles(1);
      lcd.enable = 0;
      lcd_send_nibble(n >> 4);
      lcd_send_nibble(n & 0xf);
}


void lcd_init() {
    BYTE i;
    set_tris_lcd(LCD_WRITE);
    lcd.rs = 0;
    lcd.rw = 0;
    lcd.enable = 0;
    delay_ms(15);
    for(i=1;i<=3;++i) {
       lcd_send_nibble(3);
       delay_ms(5);
    }
    lcd_send_nibble(2);
    for(i=0;i<=3;++i)
       lcd_send_byte(0,LCD_INIT_STRING);
}


void lcd_gotoxy( BYTE x, BYTE y) {
   BYTE 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;
   }
}

char lcd_getc( BYTE x, BYTE y) {
   char value;

    lcd_gotoxy(x,y);
    while ( bit_test(lcd_read_byte(),7) ); // wait until busy flag is low
    lcd.rs=1;
    value = lcd_read_byte();
    lcd.rs=0;
    return(value);
}


Me parece algo rara porque vi en internet varias y son mucho mas largas que esta.

Saludos!

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re: LCD en CCS con PIC16F877A
« Respuesta #5 en: 24 de Agosto de 2015, 19:02:23 »
Código: C
  1. for(b=0;b<250;b++)
  2.       {
  3.          
  4.          
  5.          SET_ADC_CHANNEL(1); //en AN1
  6.          Valor2=READ_ADC(ADC_START_AND_READ); //Valor que lee el conversor
  7.          if(Valor2>TensionRed){
  8.          
  9.             TensionRed=Valor2;//mayor valor medido en R10k
  10.            
  11.             valor_eficaz_red=(TensionRed*0.707); //valor eficaz en R10k
  12.          }
  13.          else
  14.             Valor2=READ_ADC(ADC_START_AND_READ);
  15.            
  16.       }

500 lecturas de ADC + posibles multiplicacion con punto fijo.. eso debe llevar muchisimo tiempo cad ves que se ejecuta.

Desconectado Rocio

  • PIC10
  • *
  • Mensajes: 7
Re: LCD en CCS con PIC16F877A
« Respuesta #6 en: 24 de Agosto de 2015, 19:45:31 »
En realidad no, es menos de 1/2 segundo.
De todas formas ya resolvi mi problema, use otra libreria.

Desconectado RALF2

  • Moderadores
  • PIC24H
  • *****
  • Mensajes: 2060
Re: LCD en CCS con PIC16F877A
« Respuesta #7 en: 24 de Agosto de 2015, 21:50:36 »
Efectivamente el problema esta en la libreria lcd.c, tu estas empleando una libreria antigua por eso no te funciona lo que te coloque y claro como no habia visto tu codigo no me habia percatado de ese detalle.  :mrgreen:

Me alegro de todas formas que hallas resuelto el problema.

Saludos