Autor Tema: Ayuda con lcd  (Leído 23614 veces)

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

Desconectado arielmdq

  • PIC16
  • ***
  • Mensajes: 166
Re: Ayuda con lcd
« Respuesta #15 en: 05 de Octubre de 2015, 20:37:50 »
Hola que tal, estoy con este tema de los numeros grandes para lcd 2x16 y estoy queriendo modificar la libreria NumGran.c ,pero no tengo demasiado conocimiento ,la idea es modificar los caracteres que forman los numeros para hacer trazos mas gruesos ,mas o menos me eh dado cuenta como estan formados los caracteres y algunos eh podido cambiar hasta ahora cambié esta parte :
                                                                       
 #rom  0x2100={28,30,30,30,30,30,30,28, //  Media barra lateral derecha.==> Esta quedo como quería
              7,15,15,15,15,15,15,7,  //  Media barra lateral izquierda.           ==> Esta quedo como quería
              31,31,0,0,0,0,0,0,       //  Barra superior sola.                          ==> Esta quedo como quería
              0,0,0,0,0,0,31,31,       //  Barra inferior sola                             
              31,31,0,0,0,0,31,31,     //  Barra superior e inferior.
              31,30,0,0,0,0,0,0,      //  Flecha Izquierda.
              0,0,0,0,0,0,30,31,    //  Flecha Derecha.
              0,0,0,0,0,0,0,0}         //  Vacio.

Pero por lo que veo no aparece ( flecha izquierda) ni ( flecha derecha) ,que en el formato original tampoco aparece ,y la otra cosa es que  los caracteres de la linea de arriba  y los de abajo estan cortados ,le falta la linea de pixeles de abajo pero no me doy cuenta donde tengo que tocar para acomodar esto ,dejo una foto para que se entienda mejor lo que quiero explicar 
https://drive.google.com/file/d/0BwFymA3SNp36V1VUZjZzc3I4Unc/view?usp=sharing
Tampoco entiendo a que es : segmento y grilla 
Si me pueden orientar un poco les estaré agradecido.
                                                                         Saludos !!!
El tiempo es una ilusión ,solo existe el presente................

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re: Ayuda con lcd
« Respuesta #16 en: 06 de Octubre de 2015, 01:07:46 »
Citar
Pero por lo que veo no aparece ( flecha izquierda) ni ( flecha derecha) ,que en el formato original tampoco aparece ,y la otra cosa es que  los caracteres de la linea de arriba  y los de abajo estan cortados ,le falta la linea de pixeles de abajo pero no me doy cuenta donde tengo que tocar para acomodar esto ,dejo una foto para que se entienda mejor lo que quiero explicar 

Primero que vos estas guardando los bits de los cuadritos en la memoria del LCD. Eso hace que se pinten como vos quieras. Luego tenes que traducirlo eso lo haces en C, es decir si vos envias con tu programa que escriba un 890. En el mismo programa dice.. MMmm es un 8 y esta primero, entonces debo decir que mueste la barra lateral izquierda aca, la derecha aca y etc etc etc.
Si vos no tenes nada que le indique al programa en C que debe enviar la flecha arriba cuando tiene como entrada $ el programa no va a saber eso.

Eso con respecto a lo de flecha izquierda y derecha. Sobre el caracter cortado no se a cual te referis, y seria bueno si en la imagen lo marcas. o decis donde exactamente.

Desconectado arielmdq

  • PIC16
  • ***
  • Mensajes: 166
Re: Ayuda con lcd
« Respuesta #17 en: 06 de Octubre de 2015, 13:55:09 »
Hola KILLERJC ,gracias por responder ,voy a intentar explicarme mejor. El primer problema ya se resolvió, yo pensaba que los caracteres estaban cortados o tal vez mal posicionados pero no, eso la hace en proteus solamente .Hoy grabe un pic para probar y salen perfectos :
 https://drive.google.com/file/d/0BwFymA3SNp36bXk3ZlRKZWVYV3M/view?usp=sharing
Si te fijas en la foto que puse ayer, que era de proteus las barras laterales que forman tanto el cero como el uno etc etc, tienen la forma de una D maaaso meeenos  :D .Y a estas les faltaba la parte redondeadita de abajo ,pero bueno era un problema del proteus ya que en la realidad salieron bien .
Ahora el tema de las flechas: en la foto que puse ahora se nota como al numero 2 le falta una parte tanto en el extremo superior como en el inferior que es donde creo yo, que va la flecha que terminaría de completar el numero para que esteticamente se vea mejor .
Estoy usando el programa ejemplo que presento el compañero MGLSOFT que lo adapte para grabarlo en un 16f876a que es el siguiente:

Código: C
  1. #include <16f876a.h>
  2. #device adc=10
  3. #use delay(clock=4000000)
  4. #fuses HS,NOWDT,NOPROTECT,NOLVP,PUT,NODEBUG,BROWNOUT,NOCPD,NOWRT
  5. #include <LCD.C>
  6. #include <NumGran.C>
  7. #use fast_io(B)
  8. #use fast_io(c)
  9. #use fast_io(a)
  10.  
  11. void main()
  12. {
  13.    int16 i;
  14.    set_tris_a (0b00001011);
  15.    output_a(0b00000000);
  16.    set_tris_c (0b01111001);
  17.    output_c(0b00000000);
  18.    // Inicializacion del micro
  19.   setup_adc_ports(AN0_AN1_AN3);
  20.    setup_adc( ADC_CLOCK_INTERNAL );
  21.    set_adc_channel( 0 );
  22.   // setup_psp(PSP_DISABLED);
  23.    setup_spi(FALSE);
  24.    setup_counters(RTCC_INTERNAL,RTCC_DIV_1);
  25.    setup_timer_1(T1_DISABLED);
  26.    setup_timer_2(T2_DISABLED,0,1);
  27.  
  28.    lcd_init();       //Inicializacion del display LCD
  29.  
  30.    // Inicializacion necesaria de la rutina de Numeros Grandes
  31.    NumGran_Init();
  32.  
  33.    WHILE(TRUE)
  34.    {
  35.  
  36.       i = Read_ADC();
  37.       lcd_send_byte(0,1);delay_us(2);  //limpiar LCD - Necesario si
  38.       NumGran(i);          // ademas se quiere escribir en numeros normales
  39.       printf(lcd_putc,"%04lu",i);
  40.       delay_ms(80);      // en las posiciones libres del display LCD
  41.  
  42.       i = Read_ADC();
  43.       delay_ms(300);                  // POSICIONA
  44.       printf(lcd_putc," %04lu    ",i);
  45.  
  46. }
  47. }

Este programa incluye el archivo NumGran.c que es este:

Código: C
  1. #rom  0x2100={16,24,24,24,24,24,24,16, //  Media barra lateral derecha.
  2.               1,3,3,3,3,3,3,1,         //  Media barra lateral izquierda.
  3.               31,31,0,0,0,0,0,0,       //  Barra superior sola.
  4.               0,0,0,0,0,0,31,31,       //  Barra inferior sola
  5.               31,31,0,0,0,0,31,31,     //  Barra superior e inferior.
  6.               2,6,14,30,14,6,2,0,      //  Flecha Izquierda.
  7.               8,12,14,15,14,12,8,0,    //  Flecha Derecha.
  8.               0,0,0,0,0,0,0,0}         //  Vacio.
  9. int8 Digito[4],Segmento[3],Linea;
  10. const int16 Grilla[2][10]={{120,770,740,740,130,147,147,720,140,140},
  11.                           {130,770,137,730,770,730,130,770,130,770}};
  12. //llamada CGRAM a numeros = 0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9
  13.  
  14. Void Desmembra (int16 Dato);
  15. Void Obtiene_Segmento (int16 Dato);
  16. Void NumGran_Init();
  17.  
  18.  
  19. Void NumGran(int16 Numero)
  20. {
  21.    int Dig;
  22.    Desmembra (Numero);
  23.    for (Linea=1;Linea<3;++Linea)
  24.    {
  25.       switch (Linea)
  26.       {
  27.          Case 1: for (Dig=0;Dig<4;++Dig){
  28.             Obtiene_Segmento (Grilla[0][Digito[Dig]]);
  29.             printf(LCD_PUTC,"%C%C%C",Segmento[2],Segmento[1],Segmento[0]);
  30.          } break;
  31.          Case 2: printf(LCD_PUTC,"\n"); for (Dig=0;Dig<4;++Dig){
  32.             Obtiene_Segmento (Grilla[1][Digito[Dig]]);
  33.             printf(LCD_PUTC,"%C%C%C",Segmento[2],Segmento[1],Segmento[0]);
  34.          } break;
  35.       }
  36.    }
  37. }
  38.  
  39. Void Desmembra (int16 Dato)      //Esta funcion obtiene el valor de los
  40. {                             // digitos a enviar al display
  41.    Digito[0] = Dato/1000; Dato = Dato%1000;
  42.    Digito[1] = Dato/100;  Dato = Dato%100;
  43.    Digito[2] = Dato/10;   Dato = Dato%10;
  44.    Digito[3] = Dato;
  45. }
  46.  
  47. Void Obtiene_Segmento (int16 Dato)  //Esta funcion obtiene el valor de los
  48. {                                // segmentos a enviar al display
  49.    Segmento[2] = Dato/100;  Dato = Dato%100;
  50.    Segmento[1] = Dato/10;   Dato = Dato%10;
  51.    Segmento[0] = Dato;
  52. }
  53.  
  54. Void NumGran_Init()
  55. {
  56.    int8 posicion;
  57.    lcd_send_byte(0x00,0x40);                 // apunta al inicio de la CGRAM y
  58.    for(posicion=0;posicion<=63;++posicion)   //carga los caracteres en la CGRAM
  59.    lcd_send_byte(1,Read_eeprom(posicion));   //traidos de la EEPROM del PIC
  60. }

Al cual yo le modifique solo la parte de la rom que muestro en el psot de arriba .Esto funciono bien ya que los caracteres se ven con trazos mas gruesos ,pero ahora la parte que me falta es la de las flechas .segun como escribió mglsoft en la rom el codigo para las flechas :            
                                                                                                                                  2,6,14,30,14,6,2,0,      //  Flecha Izquierda.
                                                                                                                                  8,12,14,15,14,12,8,0,    //  Flecha Derecha
Deberia salir esto:
https://drive.google.com/file/d/0BwFymA3SNp36WHRwN0FkYzFKSm8/view?usp=sharing
Pero esto es lo que no sale
Entonces algunas preguntas serían:
Como forma los numeros ? Entiendo que esta es la grilla de numeros
const int16 Grilla[2][10]={{120,770,740,740,130,147,147,720,140,140},
                                    {130,770,137,730,770,730,130,770,130,770}};
Pero no entiendo a que hacen referencia estos numeros ? supongo que el 120 forma la parte superior del cero y el 130 la parte inferior ,sera asi?pero de donde salen ?

por que no salen las flechas si es que estas son parte de los numeros ? (correccion en el PD, no son parte de los numeros)
Por que forma el caracter "Vacio" para que sirve ?
Bueno espero haberme explicado correctamente y disculpen tantas preguntas, pero me gustaria aprender a manejar los numero grandes a gusto ,para poder cambiarle las formas.
                                                                                                  Saludos!!!!!


PD : anoche en medio del sueño me di cuenta de algo, las flechas no son para formar parte de los numeros ya que ocupan casi un caracter completo y el numero perderia la forma  asi que la pregunta sería como poder usar los dos caracteres que ocupan las flechas en hacer 2 caracteres mas pequeños para poder darle forma a los numeros, osea como habría que llamar a estos caracteres para que formen parte de los numeros.
                                                                         
« Última modificación: 07 de Octubre de 2015, 08:03:19 por arielmdq »
El tiempo es una ilusión ,solo existe el presente................

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re: Ayuda con lcd
« Respuesta #18 en: 07 de Octubre de 2015, 09:11:51 »
Tendrias que haber seguido el programa :P, te lo voy a poner de otra forma para que lo entiendas.

Respecto a como se dibujan los segmentos:

Código: C
  1. #rom  0x2100={16,24,24,24,24,24,24,16, //  Segmento 0 - Media barra lateral derecha.
  2.                    1, 3, 3, 3, 3, 3, 3, 1, //  Segmento 1
  3.                   31,31, 0, 0, 0, 0, 0, 0, //  Segmento 2
  4.                    0, 0, 0, 0, 0, 0,31,31, //  Segmento 3
  5.                   31,31, 0, 0, 0, 0,31,31, //  Segmento 4
  6.                    2, 6,14,30,14, 6, 2, 0, //  Segmento 5
  7.                    8,12,14,15,14,12, 8, 0, // Segmento 6
  8.                    0, 0, 0, 0, 0, 0, 0, 0} // Segmento 7 - Vacio.
  9.  
  10. const int16 Grilla[2][10]={{120,770,740,740,130,147,147,720,140,140},
  11.                           {130,770,137,730,770,730,130,770,130,770}};
  12. //llamada CGRAM a numeros = 0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9

El array Grilla  son 2 vectores de 10 posiciones, cada vector es una linea del LCD.
Es decir Grilla[0] indice la primer linea del LCD y Grilla[1] la segunda linea.

Si necesitas representar por ejemplo el 1, Observamos Grilla y dice que Grilla[0][1] es 770 y Grilla[1][1] es 770, presta atencion a las centenas,decenas y unidades, ahora vamos a ver los segmentos. El 7 es vacio y el 0 es "Media barra lateral derecha.", entonces que va a dibujar?

1era linea: vacio vacio barra
2da  linea: vacio vacio barra

Ahi tenes tu 1 en numeros grandes. En resumen, si quieres agregarle el cuadrito al 2 deberias editar Grilla. buscar el del 2, cambiarle las centenas a la primera linea y las unidades en la segunda, para facilitarte la vida, ahi le puse una n asi te das cuenta donde esta:

Código: C
  1. const int16 Grilla[2][10]={{120,770,n40,740,130,147,147,720,140,140},
  2.                           {130,770,13n,730,770,730,130,770,130,770}};
  3. //llamada CGRAM a numeros = 0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9

Cambiar las flechas

Si no vas a utilizar esas flechas podes cambiarlas bit a bit es como un gran array de 5x8 en el que lo que tiene un 1 es un pixel negro. Suponete Flecha Izquierda.

             2,6,14,30,14,6,2,0,      //  Flecha Izquierda.

Representado en hexadecimal

             0x02,0x06,0x0E,0x1E,0xE,0x06,0x02,0x00,      //  Flecha Izquierda.

Representado en binario, y puesto verticalmente:

0 0 0 1 0 = 0x02 , recorda que el 1 es el pixel en negro
0 0 1 1 0 = 0x06
0 1 1 1 0 = 0x0E
1 1 1 1 0
0 1 1 1 0
0 0 1 1 0
0 0 0 1 0
0 0 0 0 0
« Última modificación: 07 de Octubre de 2015, 09:57:13 por KILLERJC »

Desconectado arielmdq

  • PIC16
  • ***
  • Mensajes: 166
Re: Ayuda con lcd
« Respuesta #19 en: 07 de Octubre de 2015, 17:40:50 »
Buenisimo KILLERJC ,me hicistes ver la luz  :-/  :D :D :D muchas gracias !!!!! excelente explicacion !!!! ya mostraré los resultados.

                                                                                         Saludos!!!!
El tiempo es una ilusión ,solo existe el presente................

Desconectado arielmdq

  • PIC16
  • ***
  • Mensajes: 166
Re:Ayuda con lcd
« Respuesta #20 en: 10 de Octubre de 2015, 19:21:20 »
Hola que tal , estuve probando la manera de cambiar la forma de los numeros grandes,gracias a la explicacion de KILLERJC, y me funcionó correctamente con el programa de ejemplo ,peeeero........  :D siempre tengo un pero ,cuando se lo implemente a mi programa
que es un cuenta vueltas y horimetro me encontré con una sorpresa: en mi programa estoy guardando datos en varias posiciones de memoria ,respetando el archivo de numeros grandes, que dice que no se puede grabar en las primeras 64 posiciones ya que estas estan ocupadas para los numeros grandes .
Y lo que me ocurre es que mientras no apague el pic ,puedo guardar mis datos y todo funciona perfecto ,pero cuando lo apago y lo vuelvo a encender le faltan partes a los numeros grandes o aparecen pixeles sueltos ,que pude ser ?
Este es mi programa :
Código: [Seleccionar]
#include <16f876a.h>
#device adc=10
#use delay(clock=4000000)
#fuses HS,NOWDT,NOPROTECT,NOLVP,PUT,NODEBUG,BROWNOUT,NOCPD,NOWRT
#include <lcd.c>
#include <NumGran.C>
#include <internal_eeprom.c>
#use fast_io(B)
#use fast_io(c)
#use fast_io(a)

//****variables del cuneta vueltas***//
int16 contador=0,RPM,i;
float ajuste=10,e;       
//****variables del cuneta horas***//
int8 Segundos=0,SegundosParcial=0,Minuto=0,MinutoParcial=0;
int menu=0,sw;
int16 b,service=1,corte, Hora=0,cont=0, HoraParcial=0,mantenimiento=0;

//*********Funciones**************************
int menus(void)
{
if (input(pin_c2)==1)
{   
  if (menu==0)  //Cambia a programacion
    return('1');
  if (menu==1)  //Info proximo service
    return('2');   
  if (menu==2)  //Cambia el tiempo del proximo service
    return('3'); 
  if (menu==3)  //Calibra RPM
    return('4');
  if (menu==4)  //Reset cuenta horas toatl
    return('5');
  if (menu==5)  //Reset cuenta horas parcial
    return('6');
  if (menu==6)  //Vuelve al comienzo del menu
    return('7');   
}
}

void corte_alimentacion(void) // si la alimentacion es menor que 4,5 Volt
 { if (corte<920)            // Guarda valores en eeprom
       {
          write_int16_eeprom(0x227, Hora);
          delay_ms(15);
          write_int16_eeprom(0x230, HoraParcial);
          delay_ms(15);         
          write_eeprom(0x236, Minuto);
          delay_ms(15);
          write_eeprom(0x238, MinutoParcial);
          delay_ms(15);
       }
 }
 
#int_timer1
void timer1_isr(void)
{  cont++;
  if (cont==2)
  {
   contador=get_timer0();
   set_timer0(0);
   cont=0;
   if (rpm>600)
   {
    Segundos++;
    SegundosParcial++;
  }
//*********Cuenta Horas Total**********************************/         
      if(Segundos == 60)
      {
          Minuto++;
          Segundos=0;
             
      if(Minuto == 60)
       {
          Hora++;
          Minuto=0;
       }
      }
/**********Cuenta Horas Parcial*********************************/
      if(SegundosParcial == 60)
      {           
          MinutoParcial++;
          SegundosParcial=0;
             
      if(MinutoParcial == 60)
       {
         
          HoraParcial++;
          MinutoParcial=0;
       }
      }   
  }
   set_timer1(3036);
   
}
//***************************************************
void main()


   set_tris_a(0b00010011);
   output_a  (0b00000000);
    set_tris_c(0b01111110);
   output_c  (0b00000000);
   
   setup_timer_0(rtcc_ext_h_to_l | rtcc_div_2);
   setup_timer_1(t1_internal | t1_div_by_8);
   
   set_timer0(0);
   set_timer1(3036);
   enable_interrupts(int_timer1);
   enable_interrupts(global);

 //****************ADC**************************
   setup_adc_ports(AN0_AN1_AN3);
   setup_adc (ADC_CLOCK_INTERNAL);
   
 //*************Lectura de eeprom *****************************
   Hora=read_int16_eeprom(0x227);
   delay_ms(15);
   HoraParcial=read_int16_eeprom(0x230);
   delay_ms(15); 
   Minuto=read_eeprom(0x236);
   delay_ms(15);
   MinutoParcial=read_eeprom(0x238);
   delay_ms(15);
   e=read_float_eeprom(0x240);
   delay_ms(15);
   service=read_int16_eeprom(0x245);
   delay_ms(15);
   mantenimiento=read_int16_eeprom(0x250);
   delay_ms(15);
//*************************************************************
    lcd_init();
    NumGran_Init();       
     lcd_gotoxy(1,1);           
      lcd_putc("    PROYECTO    \n RPM Y HORIMETRO ");           
      delay_ms(2000);               
 
      lcd_gotoxy(1,1);           
      lcd_putc(" GRACIAS TODOPIC \n    SALUDOS!!!   ");         
      delay_ms(2000);             

      lcd_putc("\f");
 
   while(1)
    {

       
         set_adc_channel(1);     //Lee la tension de alimentacion
         delay_ms(10);          // del pic ,si baja de 4,5volt
         corte=read_adc();     //
         corte_alimentacion();// actua esta funcion
         
         mantenimiento=read_int16_eeprom(0x250);
         delay_ms(15);
         
          service=read_int16_eeprom(0x245);
         delay_ms(15);
         e=read_float_eeprom(0x240);
         delay_ms(15);                             
         RPM= contador*e;       
         

      if (input(pin_c2)==0)        // Funcionamiento normal
     {       
          menu=0;
      if ( Minuto<mantenimiento)// ATENCION: cambiar Minuto por horas
      {

      output_low(pin_c7);
      i =RPM;
      lcd_send_byte(0,1);delay_us(2);
      NumGran(i);         
      printf(lcd_putc,"RPM");
      delay_ms(80);     

      i = RPM;
      delay_ms(300);                 
      printf(lcd_putc," %04lu    ",i);     
         
      if(input(pin_c6))
      {
         delay_ms(50);
      while(input(pin_c6)==0);
         
                       
         lcd_gotoxy(1,1);                       
         printf(lcd_putc,"    RPM %lu       " ,RPM);     
 
         lcd_gotoxy(1,2);
         printf(lcd_putc,"Par  %05lu:%02u:%02u",HoraParcial,MinutoParcial,SegundosParcial);
         delay_ms(3000);
         
         lcd_gotoxy(1,2);
         printf(lcd_putc,"Tot  %05lu:%02u:%02u",Hora,Minuto,Segundos);
         delay_ms(3000);
     
     
      }
      }
     
     
//********************************************************************************     
     if ( Minuto>=mantenimiento&&mantenimiento>0)//ATENCION cambiar Minuto por horas
      { 
       
        output_high(pin_c7); // Aviso luminoso de mantenimiento     
        lcd_gotoxy(1,1);                   //           
        lcd_putc("    ATENCION    \n  MANTENIMIENTO ");
                                 
        if (input(pin_c6))
       {   delay_ms(50);
       while(input(pin_c6)==0);//hasta q no suelta no graba
       
         mantenimiento=mantenimiento+1;
         write_int16_eeprom(0x250,mantenimiento);  // escribe en la memoria
         delay_ms(15);                           // tiempo para escritura
         lcd_gotoxy(1,1);                       //           
         lcd_putc("   SE POSPUSO   \n    + 1 HORA    ");
         delay_ms(2000);
         lcd_gotoxy(1,1);                   //           
         lcd_putc("INGRESE AL MENU \n PARA CAMBIARLO ");
         delay_ms(2000);
       
      } 
     }
     }//cierra funcionamiento normal
     
 /***********************ENTRA AL  MENU*************************************/
 
  if (input(pin_c2)==1)//
 {      menus();
         
     
        if (input(pin_c3)==1)
       {   delay_ms(50);
       while(input(pin_c3));
        {
           menu++; 
       if (menu>7)
           menu=0;             
        }           
       }
       
    sw=menus();     
   switch (sw)
   {
     case '1':
              lcd_gotoxy(1,1);
              printf(lcd_putc," Uds A INGRESADO \n     AL MENU    ");
              delay_ms(1000);
              menu++;
              break;
     case '2':         
              service=read_int16_eeprom(0x245);
              delay_ms(15);
              lcd_gotoxy(1,1);
              printf(lcd_putc,"Proximo Service \n   %4lu Horas     ",service);
             
              break;
                 

     case '3':                             //Service

              lcd_gotoxy(1,1);
              printf(lcd_putc,"Programe Service");
             
              if (input(pin_c4)==1)   
             {    delay_ms(50);       // antirebote
              while(input(pin_c4)); 
                    b+=1;         
             }
             if (input(pin_c5)==1)  // Boton que decrementa
             { delay_ms(50);
              while(input(pin_c5));
                    b-=1;
             }
             
             lcd_gotoxy(1,2);
             printf(lcd_putc,"   Horas  %4lu    ",b);
             
             if (input(pin_c6)==1)
             { delay_ms(50);
              while(input(pin_c6));           
               write_int16_eeprom(0x245, b);  // escribe en la memoria
               delay_ms(25);
               service=read_int16_eeprom(0x245);
               delay_ms(15);
               mantenimiento=Minuto+service;//ATENCION cambiar Minuto por hora
               write_int16_eeprom(0x250,mantenimiento);  // escribe en la memoria
               delay_ms(15);               
               mantenimiento=read_int16_eeprom(0x250);
               delay_ms(15);
               lcd_gotoxy(1,1);
               printf(lcd_putc,"     PROXIMO    \nMANT:%05lu Horas   ",mantenimiento ) ;
               delay_ms(2000);
             }
              break;
             
     case '4':                               //CALIBRA RPM
              e=read_float_eeprom(0x240);
              delay_ms(15);
              RPM= contador*e;
              lcd_gotoxy(1,1);
              printf(lcd_putc,"Actual RPM %lu       ",RPM);
              if (input(pin_c4)==1)
             {   
                   delay_ms(150);                   
                   ajuste+=0.02;          // Incremento
             }
             if (input(pin_c5)==1)
             {   
                 delay_ms(150);
                 ajuste-=0.02;        //Decremento 
             }             
             if (input(pin_c6)==1)
             { delay_ms(50);
              while(input(pin_c6));           
               write_float_eeprom(0x240, ajuste); 
               delay_ms(15); 
             }               
              RPM= contador*ajuste;
              lcd_gotoxy(1,2);
              printf(lcd_putc,"Ajuste RPM %lu       ",RPM);       
              break;
               
     case '5':                               
              lcd_gotoxy(1,1);
              printf(lcd_putc,"   RESET TOTAL    ");
              lcd_gotoxy(1,2);
              printf(lcd_putc,"   %05lu:%02u:%02u  ",Hora,Minuto,Segundos);
              if (input(pin_c6)==1) // Reset de cuenta horas parcial
               {  delay_ms(100);
                  Hora=00000;
                  write_int16_eeprom(0x227, Hora);
                  delay_ms(15);
                  Minuto=00;
                  write_eeprom(0x236, Minuto);
                  delay_ms(15);
              }
              break; 
 
             
     case '6':
              lcd_gotoxy(1,1);
              printf(lcd_putc,"  RESET PARCIAL    ");
              lcd_gotoxy(1,2);
              printf(lcd_putc,"   %05lu:%02u:%02u  ",HoraParcial,MinutoParcial,Segundos);
              if (input(pin_c6)==1) // Reset de cuenta horasparcial
               {  delay_ms(50);
                  HoraParcial=00000;
                  write_int16_eeprom(0x230, HoraParcial);
                  delay_ms(15);               
                  MinutoParcial=00;
                  write_eeprom(0x238, MinutoParcial);
                  delay_ms(15);
               }
              break;               
      case '7':
               menu=1;
               break;
   }       
 }         
    }
}
Esta es la foto como se ven los numeros correctamente:
https://drive.google.com/file/d/0BwFymA3SNp36SXJNMGVUbHRmNFU/view?usp=sharing

Y estas  despues de quitar la alimentacion y volver a conectarlo :
https://drive.google.com/file/d/0BwFymA3SNp36T3pBZk5rRUZtLU0/view?usp=sharing
https://drive.google.com/file/d/0BwFymA3SNp36QlJ1VkFFQmMxV1k/view?usp=sharing

                                                                                        Saludos!!!!!

El tiempo es una ilusión ,solo existe el presente................

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re:Ayuda con lcd
« Respuesta #21 en: 10 de Octubre de 2015, 19:50:43 »
Tal ves estes equivocandote de direccion xD

Código: C++
  1. Hora=read_int16_eeprom(0x227);
  2.    delay_ms(15);
  3.    HoraParcial=read_int16_eeprom(0x230);
  4.    delay_ms(15);
  5.    Minuto=read_eeprom(0x236);
  6.    delay_ms(15);
  7.    MinutoParcial=read_eeprom(0x238);
  8.    delay_ms(15);
  9.    e=read_float_eeprom(0x240);
  10.    delay_ms(15);
  11.    service=read_int16_eeprom(0x245);
  12.    delay_ms(15);
  13.    mantenimiento=read_int16_eeprom(0x250);
  14.    delay_ms(15);

0x250 no es lo mismo que el byte 250, 0x250 es igual a 592 y tu memoria tiene solo 256 bytes :P. El byte 250 es 0xFA , pero podes usar decimales en esa funcion sin problemas.
Otra cosa que vi solo al comienzo (ya que no vi todo el programa):

Código: C++
  1. if (menu==0)  //Cambia a programacion
  2.     return('1');
  3.   if (menu==1)  //Info proximo service
  4.     return('2');  
  5.   if (menu==2)  //Cambia el tiempo del proximo service
  6.     return('3');
  7.   if (menu==3)  //Calibra RPM
  8.     return('4');
  9.   if (menu==4)  //Reset cuenta horas toatl
  10.     return('5');
  11.   if (menu==5)  //Reset cuenta horas parcial
  12.     return('6');
  13.   if (menu==6)  //Vuelve al comienzo del menu
  14.     return('7');

Por

Código: C++
  1. return (menu+'1');      //Suponiendo que menu sea solamente numeros de 0 a 7 , sino vas a tener que agregar un if(menu<7) si es que es unsigned

En la interrupcion del timer1 intenta poner el valor mas al comienzo, asi de esa forma hay menos errores, ya que al cargarlo al final no estas teniendo en cuenta todas las lineas entre medio y suma al tiempo, incluso deberias usar el modulo CCP para mayor precision, me refiero a esta linea:

Código: C++
  1. set_timer1(3036);

El corte de la alimentacion deberias hacerlo en una interrupcion del ADC por ejemplo o por flanco segun tu hardware, ya que ahi en el while corres riesgo de que se quede enviando al LCD y no llegue a guardar.
Especialmente cuando estas teniendo delays de 100us o mas dentro del menu. Otra cosa espero que no grabe demasiado la memoria sino la vas a terminar rompiendo.

Bueno son unas cosa que vi apenas comenzo el programa hasta llegar ahi, no segui mas adelante.
« Última modificación: 10 de Octubre de 2015, 19:52:59 por KILLERJC »

Desconectado arielmdq

  • PIC16
  • ***
  • Mensajes: 166
Re:Ayuda con lcd
« Respuesta #22 en: 10 de Octubre de 2015, 20:39:11 »
Muchas gracias KILLERJC ,hasta ahora hice los cambios que me dijiste y todo funciona ,por ahora en simulacion, pero lo de la memoria seguro que era eso  :5] como se me paso ese detalle  :mrgreen: ,.
No puedo creer como se simplifico la funcion del menu  :D  el que sabe sabe ......
Me quedó una duda con lo que me decis de grabar mucho en la memoria ,y quiero contarte la manera en que pense el programa a ver si esta bien: en la memoria solo voy a grabar los parametros una sola vez ,cuando se instale el instrumento.Luego hice la funcion corte para que cuando el adc detecte menos de 4,5 volt  me guarde los datos de la hora y minutos parcial y total y hasta ahora funciona bien esto ya lo probé y alcanza a guardar los datos cuando le quito la alimentacion al pic  , pero ahora me entra la duda si solo me esta grabando en la eeprom cuando baje la tension de 4,5 volt o constantemente ? ya que si se me paso por alto de confundir hexa con decimal  :D cualquier cosa me podria pasar  :oops:
Voy a ver la manera que me decis de detectar un flanco para grabar en la memoria a ver como me funciona ,si me sale jaja
Para contar los pulsos tenia un programa hecho con CCP ,pero se me ponia muy inestable la lectura  por eso decidí usar este metodo ,de todos modos como ya sabes yo no se mucho de esto solo me funcionó asi   ;-)
Bueno te agradezco muchisimo la ayuda ya te estaré contando los resultados
                                                                                                                            Saludos!!!!
El tiempo es una ilusión ,solo existe el presente................

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re:Ayuda con lcd
« Respuesta #23 en: 10 de Octubre de 2015, 20:47:06 »
Citar
No puedo creer como se simplifico la funcion del menu  :D  el que sabe sabe ......

Y podes simplificarla aun mas, yo creo que eso vos lo haces por el tema de que en tus switch case usas '1','2','3' esos son caracteres ASCII, 0x31 , 0x32 , 0x33 respectivamente.

Citar
    sw=menus();     
   switch (sw)
   {
     case '1':

Si hubieras realizado simplemente asi:

Citar
   switch (menu+1)
   {
     case 1:

Hubiera sido mas corto, el tema es que preguntas por la entrada esa.. y tal ves tengas que cambiar otra parte del programa. Poniendole un if antes.
Bue mi idea no fue complicarte la vida, solo ver que estabas haciendo mucho para sacar poco provecho. Y no termine de ver el programa. Asi que puede haber aun mas. Proba lo de la direccion de memoria y luego contas como te fue

Desconectado arielmdq

  • PIC16
  • ***
  • Mensajes: 166
Re:Ayuda con lcd
« Respuesta #24 en: 11 de Octubre de 2015, 23:06:03 »
Hola Killerjc, no me complicas para nada ,todo lo contrario me estas enseñando un monton la idea es ir aprendiendo de a poco y te agradezco mucho  ;-)
Te cuento que probé lo de la memoria y funciona bien asi que era eso nomas  .Estuve chequeando todo el programa otra vez y descubrí un par de errores ,cosas que en realidad no hacian nada ja ja, implemente lo del switch y dentro de la funcion corte saque el if de ahi y lo puse dentro del while, seguro debe haber mucho por mejorar pero hasta ahora asi funciona cualquier correccion bienvenida sea ,dejo el programa correjido.
                Saludos!!!
Código: C++
  1. #include <16f876a.h>
  2. #device adc=10
  3. #use delay(clock=4000000)
  4. #fuses HS,NOWDT,NOPROTECT,NOLVP,PUT,NODEBUG,BROWNOUT,NOCPD,NOWRT
  5. #include <lcd.c>
  6. #include <NumGran.C>
  7. #include <internal_eeprom.c>
  8. #use fast_io(B)
  9. #use fast_io(c)
  10. #use fast_io(a)
  11.  
  12. //****variables del cuneta vueltas***//
  13. int16 contador=0,RPM,i;
  14. float ajuste=10,e;      
  15. //****variables del cuneta horas***//
  16. int8 Segundos=0,SegundosParcial=0,Minuto=0,MinutoParcial=0;
  17. int menu=0;
  18. int16 b,service=1,corte, Hora=0,cont=0, HoraParcial=0,mantenimiento=0;
  19.  
  20. //*********Funciones**************************
  21. int menus(void)
  22. { return (menu+'1');
  23.  
  24. }
  25.  
  26. void corte_alimentacion(void) // si la alimentacion es menor que 4,5 Volt
  27.  {
  28.           write_int16_eeprom(100, Hora);
  29.           delay_ms(15);
  30.           write_int16_eeprom(110, HoraParcial);
  31.           delay_ms(15);          
  32.           write_eeprom(120, Minuto);
  33.           delay_ms(15);
  34.           write_eeprom(130, MinutoParcial);
  35.           delay_ms(15);      
  36.  }
  37.  
  38. #int_timer1
  39. void timer1_isr(void)
  40. {  cont++;
  41.   if (cont==2)
  42.   {
  43.    contador=get_timer0();
  44.    set_timer0(0);
  45.    set_timer1(3036);
  46.    cont=0;
  47.    if (rpm>600)
  48.    {
  49.     Segundos++;
  50.     SegundosParcial++;
  51.   }
  52. //*********Cuenta Horas Total**********************************/        
  53.       if(Segundos == 60)
  54.       {
  55.           Minuto++;
  56.           Segundos=0;
  57.              
  58.       if(Minuto == 60)
  59.        {
  60.           Hora++;
  61.           Minuto=0;
  62.        }
  63.       }
  64. /**********Cuenta Horas Parcial*********************************/
  65.       if(SegundosParcial == 60)
  66.       {          
  67.           MinutoParcial++;
  68.           SegundosParcial=0;
  69.              
  70.       if(MinutoParcial == 60)
  71.        {
  72.          
  73.           HoraParcial++;
  74.           MinutoParcial=0;
  75.        }
  76.     }  
  77.   }    
  78. }
  79. //***************************************************
  80. void main()
  81. {  
  82.  
  83.    set_tris_a(0b00010001);
  84.    output_a  (0b00000000);
  85.     set_tris_c(0b01111110);
  86.    output_c  (0b00000000);
  87.    
  88.    setup_timer_0(rtcc_ext_h_to_l | rtcc_div_2);
  89.    setup_timer_1(t1_internal | t1_div_by_8);
  90.    
  91.    set_timer0(0);
  92.    set_timer1(3036);
  93.    enable_interrupts(int_timer1);
  94.    enable_interrupts(global);
  95.  
  96.  //****************ADC**************************
  97.    setup_adc_ports(AN0_AN1_AN3);
  98.    setup_adc (ADC_CLOCK_INTERNAL);
  99.    
  100.  //*************Lectura de eeprom *****************************
  101.    Hora=read_int16_eeprom(100);
  102.    delay_ms(15);
  103.    HoraParcial=read_int16_eeprom(110);
  104.    delay_ms(15);  
  105.    Minuto=read_eeprom(120);
  106.    delay_ms(15);
  107.    MinutoParcial=read_eeprom(130);
  108.    delay_ms(15);
  109.    e=read_float_eeprom(140);
  110.    delay_ms(15);
  111.    service=read_int16_eeprom(150);
  112.    delay_ms(15);
  113.    mantenimiento=read_int16_eeprom(160);
  114.    delay_ms(15);
  115. //*************************************************************
  116.     lcd_init();
  117.     NumGran_Init();      
  118.      lcd_gotoxy(1,1);          
  119.       lcd_putc("    PROYECTO    \n RPM Y HORIMETRO ");          
  120.       delay_ms(2000);              
  121.  
  122.       lcd_gotoxy(1,1);          
  123.       lcd_putc(" GRACIAS TODOPIC \n    SALUDOS!!!   ");        
  124.       delay_ms(2000);            
  125.  
  126.       lcd_putc("\f");
  127.  
  128.    while(1)
  129.     {
  130.  
  131.        
  132.          set_adc_channel(0);     //Lee la tension de alimentacion
  133.          delay_ms(10);          // del pic ,si baja de 4,5volt
  134.          corte=read_adc(); //
  135.          if (corte<920)            // Guarda valores en eeprom
  136.        {
  137.         corte_alimentacion();// actua esta funcion
  138.        }
  139.          mantenimiento=read_int16_eeprom(160);
  140.          delay_ms(15);
  141.          
  142.           service=read_int16_eeprom(150);
  143.          delay_ms(15);
  144.          e=read_float_eeprom(140);
  145.          delay_ms(15);                              
  146.          RPM= contador*e;      
  147.          
  148.  
  149.       if (input(pin_c2)==0)        // Funcionamiento normal
  150.      {        
  151.           menu=0;                 // vuelve a cero el menu
  152.       if ( Minuto<mantenimiento)// ATENCION: cambiar Minuto por horas
  153.       {
  154.  
  155.       output_low(pin_c7);
  156.       i =RPM;
  157.       lcd_send_byte(0,1);delay_us(2);
  158.       NumGran(i);          
  159.       printf(lcd_putc,"RPM");
  160.       delay_ms(80);    
  161.  
  162.       i = RPM;
  163.       delay_ms(300);                  
  164.       printf(lcd_putc," %04lu    ",i);    
  165.          
  166.       if(input(pin_c6))
  167.       {
  168.          delay_ms(50);
  169.       while(input(pin_c6));
  170.          
  171.                        
  172.          lcd_gotoxy(1,1);                      
  173.          printf(lcd_putc,"    RPM %lu       " ,RPM);      
  174.  
  175.          lcd_gotoxy(1,2);
  176.          printf(lcd_putc,"Par  %05lu:%02u:%02u",HoraParcial,MinutoParcial,SegundosParcial);
  177.          delay_ms(3000);
  178.          
  179.          lcd_gotoxy(1,2);
  180.          printf(lcd_putc,"Tot  %05lu:%02u:%02u",Hora,Minuto,Segundos);
  181.          delay_ms(3000);
  182.      
  183.      
  184.       }
  185.       }
  186.      
  187.      
  188. //********************************************************************************      
  189.      if ( Minuto>=mantenimiento&&mantenimiento>0)//ATENCION cambiar Minuto por horas
  190.       {  
  191.        
  192.         output_high(pin_c7); // Aviso luminoso de mantenimiento    
  193.         lcd_gotoxy(1,1);                   //          
  194.         lcd_putc("    ATENCION    \n  MANTENIMIENTO ");
  195.                                  
  196.         if (input(pin_c6))
  197.        {   delay_ms(50);
  198.        while(input(pin_c6));//hasta q no suelta no graba
  199.        
  200.          mantenimiento=mantenimiento+1;
  201.          write_int16_eeprom(160,mantenimiento);  // escribe en la memoria
  202.          delay_ms(15);                           // tiempo para escritura
  203.          lcd_gotoxy(1,1);                       //          
  204.          lcd_putc("   SE POSPUSO   \n    + 1 HORA    ");
  205.          delay_ms(2000);
  206.          lcd_gotoxy(1,1);                   //          
  207.          lcd_putc("INGRESE AL MENU \n PARA CAMBIARLO ");
  208.          delay_ms(2000);
  209.        
  210.       }  
  211.      }
  212.      }//cierra funcionamiento normal
  213.      
  214.  /***********************ENTRA AL  MENU*************************************/
  215.  
  216.   if (input(pin_c2))//si es igual a 1
  217.  {      menus();
  218.          
  219.      
  220.         if (input(pin_c3))
  221.        {   delay_ms(100);
  222.        while(input(pin_c3));
  223.         {
  224.            menu++;  
  225.        if (menu>7)
  226.            menu=0;            
  227.         }          
  228.        }
  229.            
  230.    switch (menu+1)
  231.    {
  232.      case  1:
  233.               lcd_gotoxy(1,1);
  234.               printf(lcd_putc," Uds A INGRESADO \n     AL MENU    ");
  235.               delay_ms(1000);
  236.               menu++;
  237.               break;
  238.      case  2 :          
  239.               service=read_int16_eeprom(150);
  240.               delay_ms(15);
  241.               lcd_gotoxy(1,1);
  242.               printf(lcd_putc,"Proximo Service \n   %4lu Horas     ",service);
  243.              
  244.               break;
  245.                  
  246.  
  247.      case  3 :                             //Service
  248.  
  249.               lcd_gotoxy(1,1);
  250.               printf(lcd_putc,"Programe Service");
  251.              
  252.               if (input(pin_c4))    
  253.              {  
  254.                   delay_ms(300);       // antirebote              
  255.                   b+=1;        
  256.              }
  257.              if (input(pin_c5))  // Boton que decrementa
  258.              {
  259.                  delay_ms(300);
  260.                  b-=1;
  261.              }
  262.              
  263.              lcd_gotoxy(1,2);
  264.              printf(lcd_putc,"   Horas  %4lu    ",b);
  265.              
  266.              if (input(pin_c6))
  267.              { delay_ms(50);
  268.               while(input(pin_c6));            
  269.                write_int16_eeprom(150, b);  // escribe en la memoria
  270.                delay_ms(25);
  271.                service=read_int16_eeprom(150);
  272.                delay_ms(15);
  273.                mantenimiento=Minuto+service;//ATENCION cambiar Minuto por hora
  274.                write_int16_eeprom(160,mantenimiento);  // escribe en la memoria
  275.                delay_ms(15);              
  276.                mantenimiento=read_int16_eeprom(160);
  277.                delay_ms(15);
  278.                lcd_gotoxy(1,1);
  279.                printf(lcd_putc,"     PROXIMO    \nMANT:%05lu Horas   ",mantenimiento ) ;
  280.                delay_ms(2000);
  281.              }
  282.               break;
  283.              
  284.      case  4 :                               //CALIBRA RPM
  285.               e=read_float_eeprom(140);
  286.               delay_ms(15);
  287.               RPM= contador*e;
  288.               lcd_gotoxy(1,1);
  289.               printf(lcd_putc,"Actual RPM %lu       ",RPM);
  290.               if (input(pin_c4))
  291.              {  
  292.                   delay_ms(300);                    
  293.                   ajuste+=0.02;          // Incremento
  294.              }
  295.              if (input(pin_c5))
  296.              {  
  297.                  delay_ms(300);
  298.                  ajuste-=0.02;        //Decremento  
  299.              }              
  300.              if (input(pin_c6))
  301.              { delay_ms(50);
  302.               while(input(pin_c6));            
  303.                write_float_eeprom(140, ajuste);  
  304.                delay_ms(15);  
  305.              }              
  306.               RPM= contador*ajuste;
  307.               lcd_gotoxy(1,2);
  308.               printf(lcd_putc,"Ajuste RPM %lu       ",RPM);        
  309.               break;
  310.                
  311.      case  5 :                                
  312.               lcd_gotoxy(1,1);
  313.               printf(lcd_putc,"   RESET TOTAL    ");
  314.               lcd_gotoxy(1,2);
  315.               printf(lcd_putc,"   %05lu:%02u:%02u  ",Hora,Minuto,Segundos);
  316.               if (input(pin_c6)) // Reset de cuenta horas parcial
  317.                {  delay_ms(50);
  318.                 while(input(pin_c6));
  319.                   Hora=00000;
  320.                   write_int16_eeprom(100, Hora);
  321.                   delay_ms(15);
  322.                   Minuto=00;
  323.                   write_eeprom(120, Minuto);
  324.                   delay_ms(15);
  325.               }
  326.               break;  
  327.  
  328.              
  329.      case  6 :
  330.               lcd_gotoxy(1,1);
  331.               printf(lcd_putc,"  RESET PARCIAL    ");
  332.               lcd_gotoxy(1,2);
  333.               printf(lcd_putc,"   %05lu:%02u:%02u  ",HoraParcial,MinutoParcial,Segundos);
  334.               if (input(pin_c6)) // Reset de cuenta horasparcial
  335.                {  delay_ms(50);
  336.                while(input(pin_c6));
  337.                   HoraParcial=00000;
  338.                   write_int16_eeprom(110, HoraParcial);
  339.                   delay_ms(15);              
  340.                   MinutoParcial=00;
  341.                   write_eeprom(130, MinutoParcial);
  342.                   delay_ms(15);
  343.                }
  344.               break;              
  345.       case  7 :
  346.                menu=1;
  347.                break;
  348.    }        
  349.  }        
  350.     }
  351. }
El tiempo es una ilusión ,solo existe el presente................

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re:Ayuda con lcd
« Respuesta #25 en: 11 de Octubre de 2015, 23:48:06 »
el set_timer1() lo pusiste dentro del if del timer1, deberia ir fuera y al comienzo, antes del cont++ . Ya que cuando entra ahi deberia cargarse, si termina no entrando al if no va a cargarse con el valor adecuado. Y la duracion va a ser variable

Respecto al programa hay MUCHOS delays. Especialmente esos delays de 3 segundos o cosas asi que no hacen nada bien. Esto se podria evitar totalmente (y dejar algunos pequeños como el de antirebote de las teclas) si es que lo programas de otra forma. Parecido pero pensando en otra forma. De esta forma que digo tu programa puede responder al instante. Ademas si aprovechas el CCP aun mejor, tendrias la misma interrupcion y no deberias cargar el timer. Pero bueno, hacerlo como te digo implica cambiar mucho, tu programa. Y si asi funciona bien.... que mejor :P, Si por alguna razon deseas crearlo de esta forma postea Aca o crea un nuevo tema y te voy diciendo como hacerlo.

Desconectado arielmdq

  • PIC16
  • ***
  • Mensajes: 166
Re:Ayuda con lcd
« Respuesta #26 en: 13 de Octubre de 2015, 22:49:37 »
Hola killerjc ,como le pifié al set_timer1()  :D  lo modifique despues de haber hecho la prueba ,par dejar correjido el codigo y lo terminé empeorando   :(  ,de todos modos entiendo por que va donde me decis , gracias.
Ahora encontré un problema peor  :5] ,y es que estaba leyendo el canal (1) del adc y llamando a la funcion corte()  cuando detecte que la tension bajaba de 5v asi guardaba los cuatro datos de horas y minutos parcial y total.Pero en realidad en la placa estaba leyendo el canal (0) no el (1) con lo cual como nunca detectaba tension,me estaba grabando constantemente los valores en la memoria y yo pensaba que estaba funcionando bien por que cuando cortaba la alimentacion efectivamente los valores se guardaban pero no de la manera que yo pensaba ja ja,asique estuve haciendo unas pruebas por hardware pero no me funcionó.Una de las cosas creo que es la manera en que quiero detectar la falta de alimentacion con la funcion corte ,y de aca sale una pregunta :en  un momento me dijiste que debía detectar con el adc un flanco de bajada pero no me doy cuenta con que instruccion debería detectarlo ? o como debería hacer una funcion para hacerlo.O si es algo que hacen comunmente y ya esta todo resuelto de una manera sencilla y justo  a mi se me ocurre inovar  :D :D :D
Con respecto a los delays de 3 seg los puse como en la pantalla solo voy a mostrar las rpm en numeros grandes ,tenga la opcion que pulsando un boton me muestra primero las horas min y seg parcial y luego de 3 seg el total y luego vuelvo a las rpm en numeros grandes. La otra forma de hacerlo que sugeris(es lo que se me ocurre pensar desde mi ignorancia)es en vez de usar los delays usar la base de tiempo que ya voy llevando con los segundos ? .
Con lo de cambiar el programa no tengo problema ya que es la manera de poder aprender y es lo que quiero hacer  :)
Desde que leí tu mensaje ayer que me puse a investigar lo del CCP, yo habia probado con un programa  muy basico a mi estilo :oops:  desde lo que había entendido de como hacerlo   y no me había gustado por el tema de la inestabilidad, como ya te había contado ,pero buscando una manera mejor de hacerlo encontre un ejemplo en la web que adapte para probarlo .Te lo adjunto para ver que te parece.
Código: C
  1. #include <16f876a.h>
  2. #device adc=10
  3. #use delay(clock=4000000)
  4. #fuses HS,NOWDT,NOPROTECT,NOLVP,PUT,NODEBUG,BROWNOUT,NOCPD,NOWRT
  5. #include <lcd.c>
  6. #include <internal_eeprom.c>
  7. #use fast_io(B)
  8. #use fast_io(c)
  9. #use fast_io(a)
  10.  
  11. unsigned int16 ps=0;
  12. unsigned int16 ss=0;
  13. int1 pulso=0, cambiapulso=0;
  14. long frec;
  15.  
  16. #int_CCP1
  17. void  CCP1_isr(void)
  18. {
  19.    if (pulso==0)
  20.    {
  21.       ps=CCP_1;
  22.       pulso=1;
  23.    }
  24.    else
  25.    {
  26.       ss=CCP_1;
  27.       pulso=0;
  28.    if(cambiapulso==0)
  29.    {
  30.       cambiapulso=1;
  31.    }
  32. }
  33. }
  34.  
  35. void main()
  36. {
  37. unsigned int16 tiempo=0;
  38.  
  39.     setup_timer_1(T1_INTERNAL|T1_DIV_BY_1);
  40.    // setup_ccp1(CCP_CAPTURE_DIV_4);
  41.     setup_ccp1(CCP_CAPTURE_RE);
  42.     enable_interrupts(INT_CCP1);
  43.     enable_interrupts(GLOBAL);
  44.     set_timer1(0);
  45.     lcd_init();
  46. while(true)
  47. {
  48.    if (cambiapulso==1)
  49.    {
  50.        disable_interrupts(GLOBAL);
  51.        tiempo=ss-ps;
  52.       // tiempo=tiempo/4;
  53.        frec= 1000000/tiempo;
  54.        lcd_gotoxy(1,1);
  55.        printf(lcd_putc,"   HZ %lu", frec);
  56.        cambiapulso=0;
  57.        enable_interrupts(global);
  58.    }
  59. }
  60. }
Con respecto a esto tengo la duda si puedo lograr estabilidad contando cada flanco o cada 4 flancos o 16 o no se logra estabilidad con variar esto.Bueno te agradezco mucho la ayuda .
                                                                                  Saludos !!!
 PD: en el programa solo estoy leyendo frecuencia ,si funciona bien haré los calculos para sacar las RPM
« Última modificación: 13 de Octubre de 2015, 22:55:28 por arielmdq »
El tiempo es una ilusión ,solo existe el presente................

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re:Ayuda con lcd
« Respuesta #27 en: 13 de Octubre de 2015, 23:32:16 »
No tengo CCS para probarlo, no me gusta por otra parte. utilizo XC8, asi que los codigos que ponga con funciones de CCS por favor tomalos con pinza.

CCP
Yo lo decia por el Timer1. Vos normalmente haces:

set_timer1(3036);

asi el timer cuenta: 62500 ciclos, cuando cuenta eso el Timer1 pasa de 0xFFFF a 0x0000 y se activa la interrupcion. Luego a medida que entras a la interrupcion el Timer1 sigue contando hasta que nuevamente le decis que ponga 3036 en el Timer, entonces si supongamos que tardo 5 instrucciones hasta poner a 3036 el Timer 1, deberias haber cargado 3041. En el modulo CCP vos cargas 62500 en los registros del CCP, Y al comienzo pones el Timer1 en 0. El timer cuenta hasta llegar a 62500 en el que tiene el mismo contenido que los registros del modulo CCP, al producirse la igualdad, si esta bien configurado el modulo, produce que el Timer1 se pone a 0 por si solo y activa una interrupcion. Entonces vos no tenes mas el trabajo de andar cargando una y otra ves el timer, ni siquiera pensar en cuantas instrucciones pasaron desde la interrupcion hasta que seteas el Timer1, ya se hace todo por Hardware.  Para eso debes configurar el Timer a tu gusto(como lo tenes normalmente) y el CCP en modo compare, tenes 3 modos de ahi el C-C-P Capture-Compare-PWM

El Capture es para cuando se produce un evento como puede ser una entrada externa, toma el valor del Timer 1 y lo guarda en los registros CCP, util para medir el pulso de una señal.
El Compare esta comparandose siempre el Timer1 con lo que hay dentro de los registros del CCP, cuando son iguales se produce la interrupcion ( lo que nos interesa )
El PWM Hace uso de 1 registro mas, Ambos comparados con el Timer1, cuando el registro de duty es igual que el timer1 pone a 0 la salida, cuando el registro de periodo es igual al timer1, pone a 0 el timer1 y a 1 la salida, y ahi tenes un PWM :P,

segun el manual CCS:
setup_ccp1(CCP_COMPARE_RESET_TIMER);

Decirle que el ccp tenga el valor 62500 y poner a 0 el timer y esperar xD

Algo asi:

Código: C
  1. #include <16f876a.h>
  2. #device adc=10
  3. #use delay(clock=4000000)
  4. #fuses HS,NOWDT,NOPROTECT,NOLVP,PUT,NODEBUG,BROWNOUT,NOCPD,NOWRT
  5. #use fast_io(B)
  6. #use fast_io(c)
  7. #use fast_io(a)
  8.  
  9. #int_CCP1
  10. void  CCP1_isr(void)
  11. {
  12.         bit_toggle(PIN_C0);
  13. }
  14.  
  15. void main()
  16. {
  17.     setup_timer_1(T1_INTERNAL|T1_DIV_BY_1);
  18.     setup_ccp1(CCP_COMPARE_RESET_TIMER);
  19.     CCP_1 = 62500;
  20.     set_timer1(0);
  21.     enable_interrupts(INT_CCP1);
  22.     enable_interrupts(GLOBAL);
  23.     while(true);
  24. }

No se si falta configurar algo mas, o si es necesario ademas el limpiar la flag, pero creo que tu timer duraba 0.5s, con ese valor, este va a durar lo mismo y cada ves que entre a la interrupcion va a cambiar el estado del pin C0, al menos en este ejemplo. observaras que no cargo el timer ni nada, defini los valores iniciales y que corra nomas.

A fines practicos es identico hacerlo con timer o con el CCP, lo unico que te ahorras es la cargada del timer y esto te lleva a tener un poco mas de precision final en el tiempo.

Corte
Esto puede ser de varias formas:

- la mejor seria que tengas un comparador analogico con el PIC, es lo mas rapido y no agrega circuito. Ese PIC no posee comparadores analogicos.
- La otra es usar una entrada que tenga deteccion de flanco, como Rb0 (no se si otro pin lo posee en ese pic) de esa forma usas un comparador externo y cuando se produce la caida de tension se pone a 0 la salida de ese comparador, de esa forma detectas el flanco de bajada y actuas. El circuito exterior es el que te va a fijar la tension de corte. Esto implica agregar Hardware. Pero lo bueno es que podes detectar el corte incluso antes del regulador/filtrado etc. permitiendo que si hay corte rapido al menos con la poca carga de los condensadores guardar los datos.
- Finalmente otra de las mas baratas es... el ADC ... en tu caso utilizaria el ADC y posiblimente interrupciones del mismo, entonces al comienzo pones a hacer funcionar y le decis que convierta. Apartir de ahi cada ves que entra a la interrupcion o esperas un tiempo para pedir otra muestra o pedis continuamente, siempre tratando de utilizar alguna funcion no bloqueante. Ejemplo Read_ADC() espera que el ADC termine, y deberias buscar una funcion que no haga eso, que lo active y salga.  Para tener un control verdadero en este caso deberias estar leyendo una y otra ves el ADC, lo cual va a tener un GRAN impacto en tu programa. Ya que vas a hacer: X instrucciones - ADC - otras X instr - ADC - y asi continuamente
Por lo que optes va a depender de vos. tambien va a depender de donde estes midiendo con el ADC, al igual de donde pones el comparador si es que armas un circuito externo.

EEPROM
Citar
estaba grabando constantemente los valores en la memoria
Si siguen funcionando por las dudas segui con los mismos lugares de memoria, si ya encontras problemas o algo por el estilo, cambias los lugares de las memorias, ya que con tantas grabaciones se pueden haber roto. Una ves que lo tengas como "final" y arreglado todo tambien podes cambiarle la posicion de memoria si es que no lo habias cambiado antes.
En este caso te salvo todos esos delays que tenias xD.

Para leer o escribir en el EEPROM no necesitas delays.

Tiempo y Delays

Citar
La otra forma de hacerlo que sugeris(es lo que se me ocurre pensar desde mi ignorancia)es en vez de usar los delays usar la base de tiempo que ya voy llevando con los segundos ? .

Exacto, pero ojo, eso no quiere decir que esperes ahi hasta que pasen X interrupciones, sino que no se produzca ningun cambio en el LCD mientras continua haciendo el bucle while con lo cual podes seguir leyendo las entradas, con lo que tu programa pasaria mas a tener "estados"
« Última modificación: 14 de Octubre de 2015, 01:33:29 por KILLERJC »

Desconectado arielmdq

  • PIC16
  • ***
  • Mensajes: 166
Re:Ayuda con lcd
« Respuesta #28 en: 14 de Octubre de 2015, 08:03:25 »
Muchas gracias por la respuesta ,bueno esto me va a llevar tiempo ja ja , en cuanto tenga algo te cuento
                                                                                        Saludos !!!!
El tiempo es una ilusión ,solo existe el presente................

Desconectado MGLSOFT

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 7918
Re:Ayuda con lcd
« Respuesta #29 en: 14 de Octubre de 2015, 08:05:34 »
Me alegro que les sirviera Numgran, hace mucho que lo hice, de hecho fue una de mis primeras cosas hechas en lenguaje C, antes usaba PicBasic.
Killer, excelente explicación sobre como crear los caracteres.
Las flechas no tienen nada que ver con los números, solo las uso para marcar en los menúes largos, en que posición estoy.

La perdida de parte de los números grandes es un problema de glitch en el lcd.

Habría que hacer una rutina que compruebe cada tanto si los caracteres estan bien (recuerden que son posiciones de RAM dentro del LCD) o de hecho, regrabarlos cada tanto, lo que lleva unos 18 milisegundos en los LCD que yo use, que son buenos, no se en otros.

Mi próximo desafió, aunque por ahora no tengo tiempo, es hacerlo en LCD del tipo OLED, que tienen otro driver diferente al estándar.

Saludos
Todos los dias aprendo algo nuevo, el ultimo día de mi vida aprenderé a morir....
Mi Abuelo.


 

anything