Autor Tema: Duda con RTC ds1307 + 18f2550.  (Leído 5843 veces)

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

Desconectado alperez

  • PIC18
  • ****
  • Mensajes: 255
Duda con RTC ds1307 + 18f2550.
« en: 31 de Julio de 2011, 13:46:10 »
[/size]Hola a todos. Este es mi primer mensaje en el foro, aunque llevo un tiempo usándolo como una biblia.
Acabo de empezar con los microcontroladores pic hace relativamente poco y tengo un proyecto entre manos que está bastante avanzado, pero tengo algunas (bastantes) dudas.

La idea es sencilla, aunque a mi se me hace un mundo, se trata de un sensor de temperatura (LM35) del cual mostramos la temperatura en display 16x2, lleva un RTC ds1307 y una memoria EEPROM externa 24lc32, en la cual grabaremos los datos de temperatura con una cadencia que configuramos a través de una interfaz de usuario realizada en VC++/CLI (visual studio 2010). Además de esta cadencia, tenemos la opción de grabar la hora, la fecha o ambas, teniendo un calculo de los registros que tenemos disponibles para que no se nos "salga" de la EEPROM. Tenemos tambien la opción de sincronizar la hora y la fecha en la misma interfaz y los datos se los pasamos por USB (COM  virtual).

Pues hasta aquí, si no se queda nada atras, ya está todo hecho probado y funcionando (despues de no pocos dolores de cabeza), pero ahora me surgen dudas:

1ª Veo que (todo) el mundo utiliza las interrupciones para detectar la entrada de comunicaciones por USB y yo no las utilizo (entre otras cosas por que no tengo idea de como es). ¿Es importante utilizarlas? ¿que ventajas tiene? ¿que inconvenientes tiene? No es extrictamente necesario por que funciona sin el manejo de este recurso pero ¿deberia plantearme la utilizacion de las INT?


2ª Y esto es lo siguiente por donde tengo que continuar: Tengo que grabar la temperatura y la hora y/o fecha (segun previa configuración) cada cierto tiempo (cadencia tambien configurable) que por supuesto en el momento de la programacion del pic no conocemos, pero que toda esta información esta grabada en la EEPROM externa. Habia pensado en hacer un seteo de la fecha y hora hasta que coincidiera con la que tenemos que grabar en la eeprom, me explico, tengo guardada en la eeprom la cadencia, es decir, puedo saber cuando será la proxima vez que tengo que grabar un registro de temperatura y de esta forma la comparo con la actual, si coincide, grabamos en la eeprom y calculamos cuando será la proxima muestra y vuelta a empezar. ¿es esta la mejor forma?¿existen otras alternativas?, teniendo en cuenta que el while tiene muy pocas instrucciones ¿influiría de algun modo el que estemos continuamente "mirando" la hora y comparandola?


Gracias a todos ustedes por la información que me proporcionan y espero haber colocado en su sitio este mensaje (ademas de que no les resulte un toston).
Un saludo.


Desconectado Francirius

  • PIC10
  • *
  • Mensajes: 32
Re: Duda con RTC ds1307 + 18f2550.
« Respuesta #1 en: 05 de Agosto de 2011, 17:22:57 »
Lo de las interrupciones le da cierta libertad al micro, por que no esta "amarrado" a una lectura constante de un puerto. Me explico.
Piensa que quieres leer un interruptor en un puerto. Lo que haces es que en el programa estas constantemente leyendo el puerto para ver si se acciono o no el interruptor, y en base a eso,
ejecutas una accion (prender un led).
En cambio con la interrupcion, tu le dices al pic que quieres que prenda el led si ese puerto se activa, y mientras eso no suceda, el micro puede hacer lo que quiera.
No se si me entendiste, me puedo explayar mas si kieres.
Saludos!

Desconectado alperez

  • PIC18
  • ****
  • Mensajes: 255
Re: Duda con RTC ds1307 + 18f2550.
« Respuesta #2 en: 06 de Agosto de 2011, 04:21:13 »
Lo de las interrupciones le da cierta libertad al micro, por que no esta "amarrado" a una lectura constante de un puerto. Me explico.
Piensa que quieres leer un interruptor en un puerto. Lo que haces es que en el programa estas constantemente leyendo el puerto para ver si se acciono o no el interruptor, y en base a eso,
ejecutas una accion (prender un led).
En cambio con la interrupcion, tu le dices al pic que quieres que prenda el led si ese puerto se activa, y mientras eso no suceda, el micro puede hacer lo que quiera.
No se si me entendiste, me puedo explayar mas si kieres.
Saludos!

Perfecto, lo entendi perfectamente, he implementado una interrupcion externa pero no funciona en la simulación con proteus, aunque no lo he examinado a fondo. Me estoy rompiendo la cabeza con como puedo hacer para detectar la hora y el dia en que tengo que grabar los datos en la eeprom externa, porque estoy a la espera de que me llegue el sensor de humedad y tengo la rom ya al 64% y no se si me va a dar para todo, tengo aprox 500 lineas de codigo CCS y mas de 2000 de vc++. 
Es mi primer proyecto y voy aprendiendo sobre la marcha, y creo que se me esta llendo de las manos.
Gracias por la respuesta y a ver si continúo o lo dejo apartado.

Desconectado korpaztk

  • Colaborador
  • PIC16
  • *****
  • Mensajes: 202
Re: Duda con RTC ds1307 + 18f2550.
« Respuesta #3 en: 06 de Agosto de 2011, 11:41:00 »
puedes postear tu código? capaz que hay lineas que se puedan sacar, o acomodar mejor...te lo digo porque yo hice hace un par de meses atras un proyecto de fin de año muy parecido al tullo, pero con comunicacion rs232. y lo hice con un 16f877a que tiene la octava parte de memoria flash de el que usas vos...
el sensor es de temperatura o de húmedad el que utilizas?? (ya que en el primer post mencionas el lm35 que es de temperatura y luego en el tercer post haces comentas de un sensor de humedad
a no desesperarse que mientras tengas la voluntad te podemos apoyar entre todos.... :)


Saludos.-

Korpaz.
Técnico Electronico.

El Papel Es Mi Mejor Psicologo

Desconectado alperez

  • PIC18
  • ****
  • Mensajes: 255
Re: Duda con RTC ds1307 + 18f2550.
« Respuesta #4 en: 06 de Agosto de 2011, 13:40:26 »
seguro que el codigo se puede depurar, eso por descontado, pero no lo puedo publicar aun hasta que no hable con el propietario de ciertas librerias que uso y me de su autorización. Cuando lo acabe (creo que no acabará nunca) lo publicaré en algun blog o algo parecido, porque no habia visto nada parecido, seguro que alguien lo ideo pero yo no lo vi en ninguna pagina web ni en ningun foro. En el mismo proyecto se manejan pantalla LCD comunicación USB y bus I2C, para mi es toda una azaña, nunca pensé que lograría programar un trasto de estos.

Lo del LM35 es facil de explicar, al principio (y todavia) tiene un sensor de este tipo, pero hace poco pedí (free sample) un sensor de humedad para incluirlo en el proyecto, y ya de paso, pedí tambien otro sensor de temperatura (tambien free sample) para cambiar el LM35 por uno con i2c. Y ya para hacerlo completo queria un sensor de presión pero los de freescale me querian cobrar por la manipulación, asi que de momento nada de presión.

Aqui teneis una imagen de la aplicación que regoge los datos del pic





Aún me queda la rutina para exportar a excel, pero creo que cuando este terminada y se vean las graficas de temperatura , humedad y... ¿presion? junto con sus valores medios, será una aplicación bastante interesante.

Se me está ocurriendo una cosa.... uf, creo que este proyecto no acabará nunca, y.... ¿si pudieramos bajarnos los valores medios de los ultimos años disponibles en
internet y mostrarlos en la grafica? Creo que estará guapo, pero vayamos poco a poco que todavia no se como "saber" cuando hay que grabar en la memoria, por cierto hoy me ha llegado una 25LC1024 (free sample por supuesto), para cuando tenga el sensor de humedad.

Un saludo.

Desconectado alperez

  • PIC18
  • ****
  • Mensajes: 255
Re: Duda con RTC ds1307 + 18f2550.
« Respuesta #5 en: 08 de Agosto de 2011, 07:30:19 »
Bueno pues ahora tengo otro problema, si conecto el i2c a los pines B0 y B1 con FORCE_HW la simulacion no funciona, de otra forma si que funciona.
Solo queria ponerlo asi para ahorrar algo de ROM, ya que me pasa del 63% al 58%...

Desconectado alperez

  • PIC18
  • ****
  • Mensajes: 255
Re: Duda con RTC ds1307 + 18f2550.
« Respuesta #6 en: 12 de Agosto de 2011, 05:06:56 »
Aqui muestro el codigo.
Seguro que hay fallos, de hecho, sé donde hay varios, pero tengo que terminarlo o no acabaré nunca, ya que ya me ha llegado el sensor de humedad y tengo que reestructurar muchas cosas antes de incluirlo. Por favor posteen y a ver si pronto lo publico en un blog o algo asi junto con el software del PC.

Quiero agradecer a todos los miembros de este foro la información aportada, ya que todo lo que he aprendido (hace un par de meses no sabia absolutamente nada) lo he aprendido aqui y en menor medida de otros foros.
Un agradecimiento especial a RedPic y a su web http://picmania.garcia-cuervo.net/index.php, me ha sido de muchisima ayuda para iniciarme en los microcontroladores PIC, y sobre todo su libreria _ds1307.c ( http://picmania.garcia-cuervo.net/proyectos_aux_rtc.php ).

Con este humilde proyecto, quiero hacer mi pequeña aportación a este inmenso foro, pero sobre todo demostrarme a mi mismo que en estos tiempos dificiles, cuando uno pasa por momentos complicados, sin trabajo y con tiempo libre, merece la pena estudiar un poco y aprender cosas nuevas que nos llenen y aumenten nuestra autoestima, y si es posible aumentar nuestro curriculum.
Yo no soy ingeniero, ni tengo experiencia en la programación, pero queria demostrarme a mi mismo, que cuando uno quiere, puede, aun siendo todo aparentemente  "inaccesible", siempre hay alguien que por un interés u otro, aporta sus conocimientos al mundo a traves de diversos medios.

El prototipo tiene un coste para mi casi ridiculo:

PIC 18f2550. cortesia de Microchip
Panatalla LCD 16x2. Reciclaje
Memoria EEPROM. cortesia de Microchip
DS1307. Cortesia de Maxim
Conector USB. Reciclaje
XTAL's. Reciclaje
Añadimos pila cr2032, portapilas, lm35 y algunos componentes, en total no creo que llegue a los 5€.




Código: [Seleccionar]
#define USB_HID_DEVICE     FALSE             //deshabilitamos el uso de las directivas HID
#define USB_EP1_TX_ENABLE  USB_ENABLE_BULK   //turn on EP1(EndPoint1) for IN bulk/interrupt transfers
#define USB_EP1_RX_ENABLE  USB_ENABLE_BULK   //turn on EP1(EndPoint1) for OUT bulk/interrupt transfers
#define USB_EP1_TX_SIZE    32                //size to allocate for the tx endpoint 1 buffer
#define USB_EP1_RX_SIZE    32                //size to allocate for the rx endpoint 1 buffer
#include <includes\Lectura_de_datos_USB_y_muestra_LCD.h>
#include <pic18_usb.h> //Microchip PIC18Fxx5x Hardware layer for CCS's PIC USB driver
#include <includes\usb_cdc.h> // Descripción de funciones del USB.
#include <usb.c> //handles usb setup tokens and get descriptor reports
#include <stdlib.h>
#include <math.h>
#include <includes\2432.c>
#include <includes\floatee.c>
#include <includes\_ds1307.c>

#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_A1
#define LCD_E     PIN_B2
#define PRIMER_BYTE 0x0014
#include <includes\flex_LCD.C>
#use fast_io(a)
#use fast_io(b)
#use fast_io(c)
#define _version 106     // Version
char version[]="106";
long adc_valor;                           //varias muestras para luego promediarlas
float conversion;
int i;    //Para los bucles
char datosRecibidos;
short modoConfig;
short recibeDateTime;
short recibeDatosCaptura;
short memoriaOk = 0;
byte sec;
byte min;
byte hrs;
byte day;
byte month;
byte yr;
byte dow;
//char sdow[11];
char dia[3];
char mes[3];
char ano[3];
char hora[3];
char minu[3];
char seg[3];
char registros[5];  // numero maximo registros
char direccionMax[7]; // numero maximo de direcciones de memoria
char fechahora[2];  // si vamos a grabar la fecha, la hora o ambos (0->nada , 1->fecha,2->hora,3->ambos)
char cadencia[2];   // indica la cadencia de la captura (1->dia , 2->hora,3->minuto,4->segundo)
char undCadencia[3];// indica el multiplicador de cadencia (unidades)   
int16 iregistros;
int16 iSiguienteDireccion = PRIMER_BYTE;   // La direccion de memoria donde comenzará el siguiente registro (quedará guardado en 0x000E y 0x000F)
char modoCaptura[2]; // modo de captura ON / OFF
int iUndCadencia;
int iCadencia;
short isModo;
short intExterna = 0;  // una bandera, para saber si se pulsó en RB0, se utilizará en el while principal
#int_EXT     // RB0
void  EXT_isr(void)   
{   
   intExterna = 1;  // Una bandera
}
void cambioModo(){
   int read = read_ext_eeprom(0x0002);
   if (read == 0){     
      write_ext_eeprom(0x0002, 0x0001);      //Ponemos el byte 0x0002 a 1 --->>>>>    isModo = 1 ; isCaptura();     
   }
   if (read == 1){               
      write_ext_eeprom(0x0002, 0x0000);         
   }   
}
void isCaptura(){
   /////////////////////////////////////////////
   // Vemos si hay que ponerlo en modo captura
   /////////////////////////////////////////////   
   int read = read_ext_eeprom(0x002);
   if (read == 1)                 // El byte 0x002 establece si estamos en modo captura 0/1
   {
      output_high(PIN_C7);
      isModo = 1;
      iUndCadencia = read_ext_eeprom(0x009);
      iCadencia = read_ext_eeprom(0x0008);
      iregistros = make16(read_ext_eeprom(0x000A),read_ext_eeprom(0x000B));  // iregistros toma el numero de registros que quedan disponibles
   }
   if (read == 0)
   {
      output_low(PIN_C7);
      isModo = 0;
   }
}
/////////////////////////////////////////////////////////
// Para cuando queramos poner una memoria como OK
// Las direcciones 0x000C y 0x000D almacenan el numero
// de bytes
/////////////////////////////////////////////////////////
SetMemoria(){
   char OK = "O";
   if (make16(read_ext_eeprom(0x000C),read_ext_eeprom(0x000D)) == 0)   // Vemos cuantos bytes tiene la memoria, si es 0 devolvemos False
   {   
      return 0;
   }
   else
   {
      write_ext_eeprom(make16(read_ext_eeprom(0x000C),read_ext_eeprom(0x000D)), OK); // En caso de que no sea 0 grabamos un O en el ultimo byte
      return 1;
   }   
}
comprobarEEPROM(){
   lcd_putc("\f");
   lcd_gotoxy(1,1);
   printf(lcd_putc,"Comprobando");
   printf(lcd_putc,"\n");
   printf(lcd_putc,"Memoria externa");
   delay_ms(1000);
   
   if (make16(read_ext_eeprom(0x000C),read_ext_eeprom(0x000D)) == 0)
   {
      return 0;
   }
   if (read_ext_eeprom(make16(read_ext_eeprom(0x000C),read_ext_eeprom(0x000D))) == 0x4F)     //0x4F = "O"
   {
      return 1;
   }
   else
   {
      return 0;
   }
}
short SetGrabacion(int hora, int min,int seg){                  // Decide si hay que grabar el dato
   int pHora;     // proxima hora en la que hacemos grabación
   int pMin;      // proximo minuto en el que hacemos grabación
   int pSeg;      // proximo segundo en el que hacemos grabación
   pHora = read_ext_eeprom(0x0011);    // Leemos de la memoria la proxima hora en la que hacemos grabación
   pMin = read_ext_eeprom(0x0012);     // Leemos de la memoria el proximo minuto en el que hacemos grabación
   pSeg = read_ext_eeprom(0x0013);     // Leemos de la memoria el proximo segundo en el que hacemos grabación   
   if (pHora == hora && pMin == min && pSeg == seg){
      return 1;
   }
   else{
      return 0;
   }   

void ProxGrabacion(){                                                        // Grabamos en la memoria cuando será la proxima grabacion
   int pHora;     // proxima hora en la que hacemos grabación
   int pMin;      // proximo minuto en el que hacemos grabación
   int pSeg;      // proximo segundo en el que hacemos grabación
   ds1307_get_date(day,month,yr,dow);
   ds1307_get_time(hrs,min,sec);
   if (iCadencia == 1){
      pHora = hrs + iUndCadencia;
      pMin = min;
      pSeg = sec;     
   }
   if (iCadencia == 2){
      pHora = hrs;
      pMin = min + iUndCadencia;
      pSeg = sec;
   }
   if (iCadencia == 3){
      pHora = hrs;
      pMin = min;
      pSeg = sec + iUndCadencia;
   } 
   if (pSeg > 59){
      pSeg = pSeg - 60;
      pMin ++;
   }
   if (pMin > 59){
      pMin = pMin - 60;
      pHora++;
   }     
   if (pHora > 23){
         pHora = pHora - 24;
   }   
   write_ext_eeprom(0x0011, pHora);
   write_ext_eeprom(0x0012, pMin);
   write_ext_eeprom(0x0013, pSeg);
}
void modoConfiguracion(){
   int16 iregistrosCapturados;
   lcd_putc('\f');
   printf(lcd_putc, "Modo configuracion");
   modoConfig=true;
   delay_ms(1000);
   while(modoConfig){
      if(usb_cdc_kbhit())  //Devuelve 1 se hay un nuevo dato en buffer de recepcion
        {
         datosRecibidos = usb_cdc_getc();
         if (datosRecibidos=='d'){           //si desconectamos el modo configuracion
               modoConfig=false;               
         }
         if (datosRecibidos=='B'){           //Solicitar el borrado de la memoria externa
            int16 porcentaje = 0;
            int16 i = 0x000;
            int factor;
            iregistros = make16(read_ext_eeprom(0x000C),read_ext_eeprom(0x000D));      //direccion maxima de memoria
            lcd_putc('\f'); //Limpia pantalla
            printf(lcd_putc,"Borrando MEMORIA.");
            if (iregistros == 0)
            {
               printf(usb_cdc_putc,"100");
            }               
            factor = (iregistros / 100) + 1; //porque 40.95 redondea a 40, asi que le sumamos 1           
            for (i=0;i<=iregistros;i++)
            {
               write_ext_eeprom(i, 0x0000);
               delay_ms(5);
                                   
               if (porcentaje < ((int16) i/factor)){
                  porcentaje= i /factor;
                  lcd_gotoxy(1,2);
                  printf(lcd_putc,"Completado: %Lu%%",porcentaje);
                  printf(usb_cdc_putc,"%Lu",porcentaje);
               }
            }
               lcd_putc('\f');
               printf(lcd_putc,"MEMORIA borrada");
               delay_ms(1000);
               //reset_cpu();
         } // END IF
         if (datosRecibidos=='f'){                 //Solicita fecha y hora
            ds1307_get_date(day,month,yr,dow);
            ds1307_get_time(hrs,min,sec);
            printf(usb_cdc_putc,"%02d/%02d/%02d %02d:%02d:%02d",day,month,yr,hrs,min,sec);
         } // END IF
         if (datosRecibidos=='F'){                 //Cambiamos fecha
            recibeDateTime = true;
            lcd_gotoxy(1,2);
            printf(lcd_putc,"Esperando fecha");
            while(recibeDateTime){
               if(usb_cdc_kbhit()){
                  get_string_usb(dia, 3);
                  get_string_usb(mes, 3);
                  get_string_usb(ano, 3);
                  get_string_usb(hora, 3);
                  get_string_usb(minu, 3);
                  get_string_usb(seg, 3);                 
                  ds1307_set_date_time(atoi(dia),atoi(mes),atoi(ano),dow,atoi(hora),atoi(minu),atoi(seg));                   
                  lcd_putc('\f'); //Limpia pantalla
                  printf(lcd_putc,"Fecha y hora\n" );
                  printf(lcd_putc,"establecida..." );
                  delay_ms(500);
                  lcd_putc('\f'); //Limpia pantalla
                  ds1307_get_date(day,month,yr,dow);
                  ds1307_get_time(hrs,min,sec);
                  printf(lcd_putc,"\%02d/\%02d/\%02d ",day,month,yr);
                  printf(lcd_putc,"\%02d:\%02d", hrs,min);
                  delay_ms(750);
                  lcd_putc('\f');
                  printf(lcd_putc, "Modo configuracion");
                  recibeDateTime = 0;
               } // end if
            } // end while recibeDateTime
         } // end if datosRecibidos == 'F'
         if (datosRecibidos=='G'){                 //Establecemos configuracion de la captura
            recibeDatosCaptura = true;
            lcd_gotoxy(1,2);
            printf(lcd_putc,"Esperando config.");
            while(recibeDatosCaptura){
               if(usb_cdc_kbhit()){
                  get_string_usb(registros, 5);                   // Recibimos string y lo guardamos en variable
                  get_string_usb(fechahora, 2);
                  get_string_usb(cadencia, 2);
                  get_string_usb(undCadencia,3);
                  get_string_usb(modoCaptura,2);
                  get_string_usb(direccionMax,7);                 
                  write_ext_eeprom(0x0005, atoi(fechahora));      //  Indica que vamos a grabar (nada, fecha, hora o ambas - 0/1/2/3)
                  iregistros = atol(registros);                   //  Covertimos cadena a numero entero
                  write_ext_eeprom(0x0006, make8(iregistros,1));  //  Numero maximo de registros que tenemos enviados por el PC byte alto
                  write_ext_eeprom(0x0007, iregistros);           //  Numero maximo de registros que tenemos enviados por el PC byte bajo
                  iregistros = atol(registros);                   //  Covertimos cadena a numero entero
                  write_ext_eeprom(0x000A, make8(iregistros,1));  //  Cuantos registros tenemos disponibles en la memoria byte alto
                  write_ext_eeprom(0x000B, iregistros);           //  Cuantos registros tenemos disponibles en la memoria byte bajo
                  write_ext_eeprom(0x0008, atoi(cadencia));       //  cada cuantas Horas o minutos o segundos
                  write_ext_eeprom(0x0009, atoi(undCadencia));    //  Unidades de dias horas minutos etc
                  write_ext_eeprom(0x0002, atoi(modoCaptura));    //  modo captura 0/1
                  iregistros = atol(direccionMax);                //  Covertimos cadena a numero entero
                  write_ext_eeprom(0x000C, make8(iregistros,1));  //  direccion maxima de memoria byte alto
                  write_ext_eeprom(0x000D, iregistros);           //  direccion maxima de memoria byte bajo                                           
                  write_ext_eeprom(0x000E, 0x0000);               //  Grabamos la primera direccion de memoria donde comenzara la grabación
                  write_ext_eeprom(0x000F, PRIMER_BYTE);          //  Grabamos la primera direccion de memoria donde comenzara la grabación
                  ProxGrabacion();
                  recibeDatosCaptura = 0; // para salir del bucle 0 = FALSE
               } // end if
            } //end while
         }             
         if (datosRecibidos=='L'){                 //Solicita configuracion
            iregistros = make16(read_ext_eeprom(0x000A),read_ext_eeprom(0x000B));//Registros disponibles
            if (iregistros == 0){
               iregistros = make16(read_ext_eeprom(0x0006),read_ext_eeprom(0x0007)); //Registros totales segun envio de la aplicacion
               write_ext_eeprom(0x000A, make8(iregistros,1));
               write_ext_eeprom(0x000B, iregistros);
               iregistros = make16(read_ext_eeprom(0x000A),read_ext_eeprom(0x000B)); //Registros disponibles para seguir capturando
            }           
            iregistrosCapturados = make16(read_ext_eeprom(0x0006),read_ext_eeprom(0x0007)) - make16(read_ext_eeprom(0x000A),read_ext_eeprom(0x000B));                       
            printf(usb_cdc_putc,"%d %d %d %02d %04lu %04lu", read_ext_eeprom(0x002),read_ext_eeprom(0x005),read_ext_eeprom(0x008),read_ext_eeprom(0x009),iregistros,iregistrosCapturados);           
         } // END IF "L"
         if (datosRecibidos == 'y'){               // solicita el estado del byte de control
            if (comprobarEEPROM()){
               printf(usb_cdc_putc,"O");           // si el byte de control esta correcto le enviamos una O
            }
            if (!comprobarEEPROM()){
               printf(usb_cdc_putc,"E");           // si el byte de control no esta correcto le enviamos una E
            }           
         } //END IF "y"
         if (datosRecibidos=='Y'){                 //graba el byte de control
            if (SetMemoria()){
               printf(usb_cdc_putc,"O");           //si la direccion es mayor que 0 graba el byte y le enviamos una O
            }
            if (!SetMemoria()){
               printf(usb_cdc_putc,"E");           // si la direccion de memoria es 0 no se graba el byte de control y le enviamos una E
            }               
         } // END IF "Y"
         if (datosRecibidos=='I'){                 //Comienzo de las capturas
            write_ext_eeprom(0x0002, 0x0001);      //Ponemos el byte 0x0002 a 1 --->>>>>    isModo = 1 ; //isCaptura();
            isModo = 1;
         } // END IF "I"
         if (datosRecibidos=='i'){                 //Final de las capturas
            write_ext_eeprom(0x0002, 0x0000);      //Ponemos el byte 0x0002 a 0
            isModo = 0;
         } // END IF "i"         
         if (datosRecibidos=='R'){
            printf(usb_cdc_putc,"%d", read_ext_eeprom(0x003));
         }   //END IF R         
         if (datosRecibidos=='D'){                 //Descargar datos
            short enviando;
            int16 direccion = PRIMER_BYTE;
            float temp;
            lcd_putc('\f');
            printf(lcd_putc, "Descargando...");
            enviando = true;
            while (enviando){               
               if(usb_cdc_kbhit()){
                  datosRecibidos = usb_cdc_getc();
                  if (datosRecibidos=='c'){         // Terminar (para salir del while
                     enviando = false;
                  }
                  if (datosRecibidos=='s'){         // Solicitamos dato, en este caso no será temperatura
                     printf(usb_cdc_putc,"%02d" , read_ext_eeprom(direccion));
                     direccion++;
                  }
                  if (datosRecibidos=='t'){         // Solicitamos dato, en este caso será temperatura (2 bytes)
                     temp = make16(read_ext_eeprom(direccion),read_ext_eeprom(direccion+1)) / 10;
                     printf(usb_cdc_putc,"%03.1f" , temp );
                     direccion+=2;                     
                  }
               }                 
            } // END while
         }   //END IF D         
         lcd_putc('\f');
         printf(lcd_putc, "Modo configuracion");
      } // END IF kbhit
    } //END WHILE
    lcd_putc('\f');
} //END modoConfiguración
void grabarDato(int16 dato){
   output_high(PIN_C6);
   int16 registrosdisponibles;   
   int fechahora;
   fechahora = read_ext_eeprom(0x0005);
   iSiguienteDireccion = make16(read_ext_eeprom(0x000E),read_ext_eeprom(0x000F)); // Ultima direccion grabada
   if ((fechahora == 1) || (fechahora == 3)){
      ds1307_get_date(day,month,yr,dow);
      write_ext_eeprom(iSiguienteDireccion, day);     
      iSiguienteDireccion++;
      write_ext_eeprom(iSiguienteDireccion, month);     
      iSiguienteDireccion++;     
      write_ext_eeprom(iSiguienteDireccion, yr);     
      iSiguienteDireccion++;
   }   
   if (fechahora == 2 || (fechahora == 3)){
      ds1307_get_time(hrs,min,sec);
      write_ext_eeprom(iSiguienteDireccion, hrs);     
      iSiguienteDireccion++;
      write_ext_eeprom(iSiguienteDireccion, min);     
      iSiguienteDireccion++;     
      write_ext_eeprom(iSiguienteDireccion, sec);     
      iSiguienteDireccion++;
   }
   write_ext_eeprom(iSiguienteDireccion, make8(dato,1));   
   iSiguienteDireccion++;
   write_ext_eeprom(iSiguienteDireccion, dato);
   ProxGrabacion();     // para grabar cuando será la proxima captura
   iSiguienteDireccion++;                                   // aumentamos la siguiente direccion. Obvio, si no, se sobreescribirian los datos
   write_ext_eeprom(0x000E, make8(iSiguienteDireccion,1));  // y la grabamos, (byte alto y byte bajo)
   write_ext_eeprom(0x000F, iSiguienteDireccion);     
   ///////////////////////////////////////////////////////////////////////////
   // Vamos a restar un registro a "registros disponibles"
   // Esto es para llevar un control de cuando se nos puede acabar la memoria
   ////////////////////////////////////////////////////////////////////////////
   registrosdisponibles = make16(read_ext_eeprom(0x000A),read_ext_eeprom(0x000B));
   registrosdisponibles--;
   write_ext_eeprom(0x000A, make8(registrosdisponibles,1));   
   write_ext_eeprom(0x000B, registrosdisponibles);   
   if (read_ext_eeprom(0x0003) == 0){
      write_ext_eeprom(0x0003, 1); 
   } //si el byte de control de datos grabados esta a 0 lo ponemos a 1
   output_low(PIN_C6);
} // END grabarDato()
void main(){
   enable_interrupts(GLOBAL);  // Se habilita la interrupción global 
   enable_interrupts(INT_EXT); // Se habilita la  interrupción externa 
   setup_adc_ports(AN0|VSS_VDD);
   setup_adc(ADC_CLOCK_DIV_32);
   setup_spi(SPI_SS_DISABLED);
   setup_wdt(WDT_OFF);
   setup_timer_0(RTCC_INTERNAL);
   setup_timer_1(T1_DISABLED);
   setup_timer_2(T2_DISABLED,0,1);
   setup_comparator(NC_NC_NC_NC);
   setup_vref(FALSE);
   set_adc_channel(0);
   init_ext_eeprom();                                          //inicializamos memoria EEPROM externa
   ds1307_init(DS1307_OUT_ON_DISABLED_HIHG );                   // Inicializamos el ds1307                 
   lcd_init();                                                 // empiezo a usar los comandos de la libreria del lcd
   set_tris_a(255);
   set_tris_b(0b00000001);                                             
   set_tris_c(0);                                              // configurando portc como salida
   SetMemoria();
   ////////////////////////////////////////////////////////
   // Para cuando queramos poner una version en una EEPROM
   //
   //
   write_ext_eeprom(0x001, _version);
   delay_us(10);
   //
   /////////////////////////////////////////////////////////////////
   // Comprobamos que hay una memoria conectada con una "O" al final
   memoriaOk = comprobarEEPROM();
   if (memoriaOk){
      lcd_putc("\f");
      printf(lcd_putc,"Memoria OK.");
      delay_ms(2000);
   }
   if (!memoriaOk){
      lcd_putc("\f");
      printf(lcd_putc,"Memoria");
      printf(lcd_putc,"\n");
      printf(lcd_putc,"desconocida.");
      delay_ms(2000);
   }
   // Vamos a comprobar la version que tiene la version la EEPROM, si es menor la grabamos, despues mostramos en el LCD.
   lcd_putc("\f");
   printf(lcd_putc,"Comprobando");
   printf(lcd_putc,"\n");
   printf(lcd_putc,"Version...");
   delay_ms(300);
   if (read_ext_eeprom(0x001) < _version)
   {
      write_ext_eeprom(0x001, _version);
      lcd_putc("\f");
      printf(lcd_putc,"Guardando ver.");
      delay_ms(1000);
   }
   //convertimos la version xxx en una cadena
   itoa(read_ext_eeprom(0x001),10,version);
   printf(lcd_putc,"\n");
   printf(lcd_putc,"Version: ");
   printf(lcd_putc, "v.%C.%C.%C" , version[0], version[1] , version[2]);
   delay_ms(1000);
   usb_cdc_init();
   usb_init();                            //inicializa el USB
   usb_task();                               
   lcd_putc("\f");   
   lcd_gotoxy(1,1);
   printf(lcd_putc,"Esperando");
   printf(lcd_putc,"\n");
   printf(lcd_putc,"conexion USB....");   
   lcd_gotoxy(1,1);
   printf(lcd_putc,"Termometro");
   lcd_gotoxy(1,2);
   printf(lcd_putc,"Digital by Ale");
   delay_ms(1000);
   lcd_putc('\f');
   isCaptura();                              // vamos a ver si tenemos que poner el dispositivo en modo captura
   while(true)                                  // bucle infinito
   {   
      lcd_gotoxy(1,1);
      ds1307_get_date(day,month,yr,dow);
      ds1307_get_time(hrs,min,sec);
      printf(lcd_putc,"\%02d/\%02d/\%02d ",day,month,yr);
      printf(lcd_putc,"\%02d:\%02d", hrs,min);
      if (intExterna){
         intExterna = 0;
         cambioModo();
         isCaptura();
         ProxGrabacion();
      }   
      for(i=0; i<200;i++)                                   //Tomas 200 muestras y las sumas en grados_temperatura
         {
           adc_valor+= read_adc();
           delay_us(11);                                   //Demos tiempo al ADC para terminar la conversión anterior (TAD)
          }
      adc_valor /= 200;                                    //aqui calculas el promedio de 200 muestras   
      conversion=(float) adc_valor;
      //setup_adc (adc_off);
      conversion=conversion*0.48875;                       //Pasa binario a °C
                                                           //
                                                           //el "0.48875" sale de dividir 5/1023 (10bits) y el resultado de eso multiplicarlo
                                                           //por 100 el 5 sale de los 5 voltios aplicado al voltaje de referencia, los 1023
                                                           //salen de los 10 bit de resolución del conversor analógico digital.
                                                           //Si utilizáramos la resolucion de 8 bist del conversor analógico digital, la
                                                           //formula sería (5/255)*100 ya que con 8 bits el numero máximo posible es de 0-255                                                             
      lcd_gotoxy(1,2);
      printf(lcd_putc,"T: %03.1f \xdfC",conversion);
      if ((isModo) && (iregistros > 1)){
         if (SetGrabacion(hrs,min,sec)) {
            grabarDato(conversion*10);   // Lo multiplicamos por 10 para quitarle el decimal y asi ocupar solo 2 bytes de memoria         
         }
      }       
      if(usb_cdc_kbhit())  //Devuelve 1 se hay un nuevo dato en buffer de recepcion
      {   
          datosRecibidos = usb_cdc_getc();
          if (datosRecibidos=='c'){                   //Vamos a Configuracion
            modoConfiguracion();
          }
          if (datosRecibidos=='t'){                   //Solicitamos la temperatura
            printf(usb_cdc_putc,"%03.1f",conversion);
          }
          if (datosRecibidos=='v'){                   //Solicitamos la version del Hardware
            itoa(read_ext_eeprom(0x001),10,version);
            printf(usb_cdc_putc, "v.%C.%C.%C" , version[0], version[1] , version[2]);
          }
          if (datosRecibidos=='f'){
            printf(usb_cdc_putc,"%02d/%02d/%02d %02d:%02d:%02d",day,month,yr,hrs,min,sec);
          }             
      }
   }  //fin de while
}  //fin de main

Desconectado alperez

  • PIC18
  • ****
  • Mensajes: 255
Re: Duda con RTC ds1307 + 18f2550.
« Respuesta #7 en: 08 de Febrero de 2012, 10:46:00 »
El .h del formulario principal de la aplicación en CPP.
El código está por mejorarlo, cambiando la forma de enviar y recibir los comandos e incluir rutinas de control de errores, pero esto llevaría consigo la implementacion de estas rutinas en el PIC y creo que ya no hay memoria para esto.

Espero que les sea de utilidad.

Desconectado jukinch

  • Colaborador
  • PIC24F
  • *****
  • Mensajes: 608
Re: Duda con RTC ds1307 + 18f2550.
« Respuesta #8 en: 08 de Febrero de 2012, 10:47:19 »
Gracias por compartirlo alperez  :-/
             Saludos.
                  Jukinch
"Divide las dificultades que examinas en tantas partes como sea posible para su mejor solución." -René Descartes

Desconectado alperez

  • PIC18
  • ****
  • Mensajes: 255
Re: Duda con RTC ds1307 + 18f2550.
« Respuesta #9 en: 08 de Febrero de 2012, 10:51:54 »
Gracias por compartirlo alperez  :-/
             Saludos.
                  Jukinch

te va a chocar esto:

Código: [Seleccionar]
Thread::Sleep(10); // 300 si es simulacion. 75 si es fisico
Habría que pulirlo pero aquí está la explicación:
Código: [Seleccionar]
/*
Thread::Sleep(200); // Le damos una suspension del proceso durante 200ms para que al micro le de tiempo a transmitir
// Este problema es continuo por no utilizar el evento de recepcion. Ya veremos en otras versiones.
// 24/07/2011: No vamos a utilizar el evento de recepción, no esta garantizado que se detecte siempre:
// http://msdn.microsoft.com/es-es/library/system.io.ports.serialport.datareceived%28v=VS.100%29.aspx
*/


Desconectado jukinch

  • Colaborador
  • PIC24F
  • *****
  • Mensajes: 608
Re: Duda con RTC ds1307 + 18f2550.
« Respuesta #10 en: 08 de Febrero de 2012, 11:06:11 »
Ok. alperez. Voy a estudiarlo.

"Divide las dificultades que examinas en tantas partes como sea posible para su mejor solución." -René Descartes


 

anything