TODOPIC

Microcontroladores PIC => Lenguaje C para microcontroladores PIC => Mensaje iniciado por: Medusa en 07 de Agosto de 2009, 18:06:39

Título: multiplicacion de nueros hexadecimales
Publicado por: Medusa en 07 de Agosto de 2009, 18:06:39
hola, cual es el problema e este codigo?

Código: [Seleccionar]
int16 New_number ;

New_number = ((0x017 * 0x0E10) );

No puedo obtener el resultado corresto el cual es : 0x14370 pero obtengo este valor: 17264, cual es mi error????
Título: Re: multiplicacion de nueros hexadecimales
Publicado por: RedPic en 07 de Agosto de 2009, 18:26:08
Medusa, 0x14370 en decimal es 82800 y en binario es 10100001101110000 ... o sea 17 bits para una variable de 16 bits, que solo alcanza hasta 65536 valores.

De hecho 82800 - 65536 = 17264 que es el número que tu obtienes tras haber alcanzado el límite de la variable New_number, la has desbordado y te muestra el resto tras ello.

Utiliza int32 New_number; y veras como funciona correctamente.  :mrgreen:
Título: Re: multiplicacion de nueros hexadecimales
Publicado por: Medusa en 07 de Agosto de 2009, 18:50:41
Hola RedPic, hay algo que esta mal por que el resultado es el mismo a pesar de que he variado el formato.

Código: [Seleccionar]
int32 New_number ;

New_number = ((0x017 * 0x0E10) );
Título: Re: multiplicacion de nueros hexadecimales
Publicado por: RedPic en 07 de Agosto de 2009, 19:52:16
Escríbelo así a ver si te funciona:

Código: C#
  1. int32 New_number;
  2. New_number = (int32) (0x0017 * 0x0E10);
  3. printf("%LX",New_number);

Nota: ¿Como ves el valor del resultado?
Título: Re: multiplicacion de nueros hexadecimales
Publicado por: Medusa en 07 de Agosto de 2009, 20:27:48
Citar
Escríbelo así a ver si te funciona:


Código
int32 New_number;New_number = (int32) (0x0017 * 0x0E10); printf("%LX",New_number);
Nota: ¿Como ves el valor del resultado?

El resultado se imprime correctamente, estoy usando el UART para leer esto,
Pero dime para leer este valor tu lo estas formateando con "%LX" pero como puedo hacer para que este valor con este formato pase a una variable ???
Título: Re: multiplicacion de nueros hexadecimales
Publicado por: gera en 07 de Agosto de 2009, 21:04:01
Medusa, la pregunta q te hizo red pic es que como haces para ver el resultado. Q funcion usas? printf?
Si queres poner el resultado en ese formato, tendrias q ponerlo en un string de la siguiente manera:
sprintf(string,"%LX",New_number);
Donde string es un puntero a un arreglo de chars.
saludos!
Título: Re: multiplicacion de nueros hexadecimales
Publicado por: MLO__ en 07 de Agosto de 2009, 21:35:35
.. pero como puedo hacer para que este valor con este formato pase a una variable ???

Pues ... con un = !!!!!

El valor no se esta formateando, lo que se hace es asignar el tipo de salida:

para la funcion printf():

Citar
c Character
s String or character
u Unsigned int
d Signed int
Lu Long unsigned int
Ld Long signed int
x Hex int (lower case)
X Hex int (upper case)
Lx Hex long int (lower case)
LX Hex long int (upper case)
f Float with truncated decimal
g Float with rounded decimal
e Float in exponential format
w Unsigned int with decimal place inserted. Specify two numbers for n. The first is a total field width. The second is the desired number of decimal places.

Saludos
Título: Re: multiplicacion de nueros hexadecimales
Publicado por: BrunoF en 07 de Agosto de 2009, 23:06:38
MLO me parece que a lo que se refiere medusa es que quiere guardar el valor TEXTUAL en hexadecimal.

Es decir, no quiere guardar el valor 0x14370. Quiere guardar "0x14370"...así que lo que te propone gera es la solución más fácil.
Título: Re: multiplicacion de nueros hexadecimales
Publicado por: Suky en 07 de Agosto de 2009, 23:16:39
Si es pasar de un string al valor numérico se usa:

8bitsValue=atoi(String)
16bitsValue=atol(String)
32bitsValue=atoi32(String)


String puede ser decimal o hexadecimal.

Saludos!
Título: Re: multiplicacion de nueros hexadecimales
Publicado por: MLO__ en 08 de Agosto de 2009, 01:09:07
Ah!!!

Es que no especifica que la variable es del tipo string jeje.

Y si, es recomendable usar sprintf() para pasarlo a una variable tipo string.

Título: Re: multiplicacion de nueros hexadecimales
Publicado por: Medusa en 10 de Agosto de 2009, 14:13:56
Hola a todos, y gracias por toda su ayuda pero realmente estoy mas confundida ahora.

Partiendo del trabajo de RedPic sombre el DS1307 (http://picmania.garcia-cuervo.net/proyectos_aux_rtc.php) lo que pretendo es comparar la lectura que me entrega el RTC (hrs, min, sec) cada segundo con otros valor de hrs, min, sec que se encuentran alamcenado en una region de la memoria EEprom (apartir de la direccion 200),  para hecer esto he tratado de convertir todos estos valores a segundos:

RTC = ((hrs *3600)+(min*60)+sec)
Código: [Seleccionar]
RTC = ((hrs * 0x0E10) + (min * 0x03C) + (sec * 0X01))
Código: [Seleccionar]
Alarma = ((Alar_hrs * 0x0E10) + (Alar_min * 0x03C) + (Alar_sec * 0X01))

El problema es que no puedo obtener los valores corectos de RTC ni de Alarma para hacer la comparacion.
Alguien me podria dar una sugerencia de como solucionar esto

He modificado el #include <DS1307x.h> para tener acceso solamente la los valores de tiempo.

Aqui esta mi codigo:
Código: [Seleccionar]
#include <18F452.h>
#include <string.h>
#include <stdlib.h>

#fuses HS,NOWDT,NOPROTECT,NOLVP
#use delay(clock=20000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7)

#define RTC_SDA     PIN_C4
#define RTC_SCL     PIN_C3

#define SIRENA    PIN_D0
#define Alarma_ON  output_high
#define Alarma_OFF output_low

#include <DS1307x.h>

char Alarma_Seg[] = "00";
char Alarma_Min[] = "30";
char Alarma_Hrs[] = "23";
int i;
int8 sec ;
int8 min ;
int8 hrs ;

int16 Alar_sec;
int16 Alar_min;
int16 Alar_hrs;

int32 Alarma;
int32 RTC;
int32 var1;
int32 var2;

char Buffer_Seg[3];
char Buffer_Min[3];
char Buffer_Hrs[3];

#INT_EXT
void IntRB0()
{
      ds1307_get_time(hrs,min,sec);
}

void Init_Alarma_EEprom(){

       for (i = 0; i< 2; i++) write_eeprom( 210+i, Alarma_Seg[i]);
       for (i = 0; i< 2; i++) write_eeprom( 212+i, Alarma_Min[i]);
       for (i = 0; i< 2; i++) write_eeprom( 214+i, Alarma_Hrs[i]);
}

void Compara_RTC_Alarma(){

       for (i = 0; i< 2; i++){ Buffer_Seg[i] = read_eeprom(210+i);
            Alar_sec = atoi(Buffer_Seg);}
       for (i = 0; i< 2; i++){ Buffer_Min[i] = read_eeprom(212+i);
            Alar_min = atoi(Buffer_Min);}
       for (i = 0; i< 2; i++){ Buffer_Hrs[i] = read_eeprom(214+i);
            Alar_hrs = atoi(Buffer_Hrs);}

       RTC = ((hrs * 0x0E10) + (min * 0x03C) + (sec * 0X01));
       var1 = printf("%lx \n\r ", RTC);

       Alarma = ((Alar_hrs * 0x0E10) + (Alar_min * 0x03C) + (Alar_sec * 0X01));
       var2 = printf("%lx \n\r ", Alarma);

       if (var2 >= var1)
          Alarma_ON(SIRENA);
       else
          Alarma_OFF(SIRENA);

}
   
void main() {

      enable_interrupts(int_ext);
      ext_int_edge(H_TO_L);
      enable_interrupts(GLOBAL);
      Init_Alarma_EEprom();

      ds1307_init();
      Delay_ms(300);

while (TRUE){

       Compara_RTC_Alarma();

    }   
}

Este es el include

Código: [Seleccionar]
/********************************************************************************
*                               DS1307.C                                        *
*                   Driver para el Time Clock DS1307                      *
*********************************************************************************/

#define RTC_SDA  PIN_C4
#define RTC_SCL  PIN_C3

#use i2c(master, sda=RTC_SDA, scl=RTC_SCL)

BYTE bin2bcd(BYTE binary_value);
BYTE bcd2bin(BYTE bcd_value);

void ds1307_init(void)
{
   BYTE seconds = 0;

   i2c_start();
   i2c_write(0xD0);      // WR to RTC
   i2c_write(0x00);      // REG 0
   i2c_start();
   i2c_stop();

   delay_us(3);

   i2c_start();
   i2c_write(0xD0);      // WR to RTC
   i2c_write(0x00);      // REG 0
   i2c_write(0x00);
   i2c_write(0x00);      // WR to RTC
   i2c_write(0x00);      // WR to RTC
   i2c_write(0x00);      // WR to RTC
   i2c_write(0x00);      // WR to RTC
   i2c_write(0x00);      // WR to RTC
   i2c_write(0x00);      // Control Register
   i2c_write(0x10);      // Disable squarewave output pin
   i2c_stop();

}

void ds1307_set_time(BYTE hr, BYTE min, BYTE sec)
{
  sec &= 0x7F;
  hr &= 0x3F;

  i2c_start();
  i2c_write(0xD0);            // I2C write address
  i2c_write(0x00);            // Start at REG 0 - Seconds
  i2c_write(bin2bcd(sec));      // REG 0
  i2c_write(bin2bcd(min));      // REG 1
  i2c_write(bin2bcd(hr));      // REG 2
  i2c_stop();
}

void ds1307_get_time(BYTE &hr, BYTE &min, BYTE &sec)
{
  i2c_start();
  i2c_write(0xD0);
  i2c_write(0x00);            // Start at REG 0 - Seconds
  i2c_start();
  i2c_write(0xD1);
  sec = bcd2bin(i2c_read() & 0x7f);
  min = bcd2bin(i2c_read() & 0x7f);
  hr  = bcd2bin(i2c_read(0) & 0x3f);
  i2c_stop();

}

BYTE bin2bcd(BYTE binary_value)
{
  BYTE temp;
  BYTE retval;

  temp = binary_value;
  retval = 0;

  while(1)
  {
    // Get the tens digit by doing multiple subtraction
    // of 10 from the binary value.
    if(temp >= 10)
    {
      temp -= 10;
      retval += 0x10;
    }
    else // Get the ones digit by adding the remainder.
    {
      retval += temp;
      break;
    }
  }

  return(retval);
}


// Input range - 00 to 99.
BYTE bcd2bin(BYTE bcd_value)
{
  BYTE temp;

  temp = bcd_value;
  // Shifting upper digit right by 1 is same as multiplying by 8.
  temp >>= 1;
  // Isolate the bits for the upper digit.
  temp &= 0x78;

  // Now return: (Tens * 8) + (Tens * 2) + Ones

  return(temp + (temp >> 2) + (bcd_value & 0x0f));
}
Título: Re: multiplicacion de nueros hexadecimales
Publicado por: BrunoF en 10 de Agosto de 2009, 16:09:37
Mal:

for (i = 0; i< 2; i++){ Buffer_Seg = read_eeprom(210+i);
            Alar_sec = atoi(Buffer_Seg);}
       for (i = 0; i< 2; i++){ Buffer_Min = read_eeprom(212+i);
            Alar_min = atoi(Buffer_Min);}
       for (i = 0; i< 2; i++){ Buffer_Hrs = read_eeprom(214+i);
            Alar_hrs = atoi(Buffer_Hrs);}

Bien:

for (i = 0; i< 2; i++){ Buffer_Seg = read_eeprom(210+i);}
            Alar_sec = atoi(Buffer_Seg);
       for (i = 0; i< 2; i++){ Buffer_Min = read_eeprom(212+i);}
            Alar_min = atoi(Buffer_Min);
       for (i = 0; i< 2; i++){ Buffer_Hrs = read_eeprom(214+i);}
            Alar_hrs = atoi(Buffer_Hrs);

Mal:
    RTC = ((hrs * 0x0E10) + (min * 0x03C) + (sec * 0X01));
    Alarma = ((Alar_hrs * 0x0E10) + (Alar_min * 0x03C) + (Alar_sec * 0X01))    

Bien:
    RTC = (((int32)hrs * 0x0E10) + (min * 0x03C) + (sec * 0X01));
    Alarma = (((int32)Alar_hrs * 0x0E10) + (Alar_min * 0x03C) + (Alar_sec * 0X01));

Mejor:
    RTC = (int32)hrs*3600+min*60+sec;
    Alarma = (int32)Alar_hrs*3600+ Alar_min*60+Alar_sec;

Tendrías que leer un poco más cómo hace los casting implícitos el CCS

No miré el resto...Saludos
Título: Re: multiplicacion de nueros hexadecimales
Publicado por: MLO__ en 10 de Agosto de 2009, 16:43:30
Hola.

Yo creo que la opcion mas facil es cargar todo a un buffer (horas, minutos y segundos leidos del RTC) y hacer la comparacion completa con strncmp(), el otro string seria con los valores que tienes almacenados en la memoria EEPROM.

Citar
strncmp  (s1, s2, n) Compare s1 to s2 (n bytes)

Saludos
Título: Re: multiplicacion de nueros hexadecimales
Publicado por: Medusa en 10 de Agosto de 2009, 17:39:48
   :-/   :-/   :-/ hola, gracias a todos por toda la ayuda, ya resolvi el problem,   :mrgreen:
Título: Re: multiplicacion de nueros hexadecimales
Publicado por: RedPic en 10 de Agosto de 2009, 18:41:03
¿Como?
Título: Re: multiplicacion de nueros hexadecimales
Publicado por: Medusa en 10 de Agosto de 2009, 21:53:39
Con las correciones que me hizo BrunoF  :mrgreen: