Autor Tema: Problema conversion numeros a BCD con una funcion.  (Leído 1713 veces)

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

Desconectado Arkaedus

  • PIC10
  • *
  • Mensajes: 25
Problema conversion numeros a BCD con una funcion.
« en: 23 de Junio de 2015, 18:19:55 »
Hola  pues  he introducido un ds1302 que coge la hora y el dia actual del ordenador

Pido ayuda porque soy nuevo en este mundo y esto de las conversiones me trae un poco loco


Pero me fallan 3 funciones:

la que realiza la conversion BCD e imprime los valores en pantalla

y las funciones de decrementar e incrementar que hace que el DS1302 tenga valores que no pueden ser, pero esto quizas sea por el  fallo de la fincion de conversion, asi que primero se debería abordar la funcion de conversion e impresion de los valores en la pantalla, asi que vamos a ello.

Adjunto una captura de pantalla:



Los datos del DS1302 son los buenos y lo que se imprime en la pantalla en la primera linea deberia coincidir con lo del DS1302

La funcion que imprime en pantalla los dos numero en bcd es la siguiente:

Código: [Seleccionar]
//-----------------------------------------------------------------------------
void lcd_print_2num_bcd(int num_bcd)
{
   lcd_putc1((num_bcd >> 4)    + 0x30);      //DECENAS
   lcd_putc1((num_bcd &  0x0F) + 0x30);      //UNIDADES
}
//-----------------------------------------------------------------------------

Y estas son las funciones que incrementan y decrementan los numeros:

Código: [Seleccionar]
//-----------------------------------------------------------------------------
short inc_2bcd(int* num_bcd, int bcd_limite = 0x9A, short digito = 0)
//Significado de los parametros:
//    num_bcd:    numero de 2 cifras en BCD que queremos incrementar
//    bcd_limite: valor una vez incrementado el numero BCD que se considera que
//                ha habido un desbordamiento, volviendo al valor 0. Los unicos
//                valores no BCD aceptables son desde 0x9A hasta 0xA0 que
//                equivalen a 100 BCD.
//    digito:     especifica si se ha de incrementar la cifra de las unidades(0)
//                o la de las decenas (1)
//
//Devuelve 1 si desborda por el limite
{
   switch (digito)
   {
      //Incrementar unidades
      case 0:
         *num_bcd +=1;              //Unidades + 1
         if ((*num_bcd & 0x0F) > 9) //Unidades > 9?
         {
            *num_bcd &= 0xF0;          //Unidades = 0
            *num_bcd += 0x10;          //Decenas + 1
         }
         if (*num_bcd >= bcd_limite)//Desbordamiento?
         {
            *num_bcd = 0x00;           //Numero BCD = 00
            return 1;                  //Devolver desbordamiento
         }
         break;
      //Incrementar decenas         
      case 1:
         *num_bcd += 0x10;          //Decenas + 1
         if (*num_bcd >= bcd_limite)//Desbordamiento?
         {
            *num_bcd &= 0x0F;          //Decenas = 0
            return 1;                  //Devolver desbordamiento
         }         
         break;
   }
   return 0;
}
//-----------------------------------------------------------------------------

short dec_2bcd(int* num_bcd, int bcd_limite = 0x99, short digito = 0)
//Significado de los parametros:
//    num_bcd:    numero de 2 cifras en BCD que queremos decrementar
//    bcd_limite: valor que tomará el numero BCD si se ha llegado a numeros
//                negativos (desbordamiento).
//    digito:     especifica si se ha de decrementar la cifra de las unidades(0)
//                o la de las decenas (1)
//
//Devuelve 1 si desborda por debajo de 0
{
   switch (digito)
   {
      //Decrementar unidades
      case 0:
         *num_bcd -= 1;                //Unidades - 1
         
         if (*num_bcd == 0xFF)           //Desbordamiento?
         {
            *num_bcd = bcd_limite;        //Numero BCD = limite
            return 1;                     //Devolver desbordamiento
         }

         if ((*num_bcd & 0x0F) == 0x0F)//Desbordamiento de Unidades?           
         {                                //Automaticamente -> Decenas - 1
            *num_bcd &= 0xF9;//0b11111001;//Unidades = 9         
         }
         break;
         
      //Decrementar decenas         
      case 1:
         *num_bcd -= 0x10;             //Decenas - 1

         if ((*num_bcd & 0xF0) == 0xF0)//Desbordamiento?
         {
            *num_bcd = (*num_bcd & 0x0F) | (bcd_limite & 0xF0); //Decenas = Decenas de limite
            if (*num_bcd > bcd_limite){   //Al restaurar las decenas, el numBCD es > limite?
               *num_bcd -= 0x10;               //Decenas - 1
            }
            return 1;                     //Devolver desbordamiento
         }       
         break;
   }
   return 0;
}

Codigo para definir de hora y sus limites:

Código: [Seleccionar]
//CONSTANTES GENERALES/////////////////////////////////////////////////////////
#define LIMIT_HORAS_INC      0x24
#define LIMIT_HORAS_DEC      0x23

int hora = 0;

Este es el codigo que uso en la pantalla de configuracion de reloj por ejemplo para poner los numeros de la hora, hay que decir que hora esta definido como un entero al inicio del programa:

Código: [Seleccionar]
//CURSOR EN DECENAS HORA INICIO                 
               case 1:
                  if (puls_up_fs)
                  {
                     inc_2bcd(&config_hora_inicio[config_dia_actual],
                              LIMIT_HORAS_INC, 1);
                  }
                  if (puls_down_fs)
                  {
                     dec_2bcd(&config_hora_inicio[config_dia_actual],
                              LIMIT_HORAS_DEC, 1);
                  }
               //-------------------------
                  break;
                 
               //CURSOR EN UNIDADES HORA INICIO               
               case 2:   
                  if (puls_up_fs)
                  {
                     inc_2bcd(&config_hora_inicio[config_dia_actual],
                              LIMIT_HORAS_INC, 0);
                  }
                  if (puls_down_fs)
                  {
                     dec_2bcd(&config_hora_inicio[config_dia_actual],
                              LIMIT_HORAS_DEC, 0);
                  }               
               //-------------------------
                  break;

La pantalla cuando le doy a los pulsadores los numeros en pantalla se ponen bien y van con los valores que toca y se cambian los del DS1302, por eso creo que primero habría que abordar la primera funcion (void lcd_print_2num_bcd(int))

Espero que alguien pueda ayudarme

Gracias y un saludo


Desconectado xxopiumxx

  • PIC12
  • **
  • Mensajes: 82
Re: Problema conversion numeros a BCD con una funcion.
« Respuesta #1 en: 29 de Junio de 2015, 14:49:06 »
hola Arkaedus.
te dejo dos funciones que uso siempre para convertir los datos de los rtc, tal vez te sirva.
disculpa que no me pongo con mas detalle, pero la oficina esta como loca :P

Código: [Seleccionar]
1:  uint8_t bcdtodecimal(uint8_t bcd) {  
2:    return ((bcd >>= 4)*10 + (bcd & (~0xF0)));  
3:  }  
4:
5:  uint8_t decimaltobcd(uint8_t decimal) {  
6:    uint8_t aux;  
7:    aux = decimal / 10;  
8:    decimal -= (aux * 10);  
9:    return (decimal |= (aux <<= 4));  
10:  }

Desconectado Arkaedus

  • PIC10
  • *
  • Mensajes: 25
Re: Problema conversion numeros a BCD con una funcion.
« Respuesta #2 en: 01 de Julio de 2015, 15:54:33 »
Gracais por las funciones, pero como se deberian usar?

De todas maneras lo de los interogantes lo arregle, cambiando el DS1307 pr el DS1302, el problema creo que era del driver

Ahora lo que quiero hacer es esto, pero no se si esto podria servirme para algo:

http://www.todopic.com.ar/foros/index.php?topic=44490.msg371558#msg371558

Es un proyecto casero que estoy haciendo, mi primer proyecto :)

Pero me falta lo de los PWM y no se como coger los datos para cambair los PWM, porque lo que queireo es que cambie de tono el acuario segun las horas de iluminacion y esto es controlado por los PWM

« Última modificación: 01 de Julio de 2015, 16:13:40 por Arkaedus »