Mi pregunta parece simple, pero aún así perdí mi camino para resolver el problema. La discusión podría mostrarme el camino.
Estoy usando el microcontrolador Pic16f877A para escribir EEPROM usando I2C (1 byte a la vez). Necesito escribir un valor entero de 4 bytes (digamos 4284967295 ~ 0xFF67697F). Quiero escribir este valor en la EEPROM y leer este valor de la EEPROM cuando sea necesario. No puedo encontrar las mejores formas posibles de escribir/leer este valor.
Intenté acercarme de la siguiente manera:
unsigned int a = 4284967295;
unsigned int result1, result2, result3, result4;
result1 = (( a & 0x000000FF ) ); \\ result1 = 127
result2 = (( a & 0x0000FF00 ) ); \\ result2 = 26880
result3 = (( a & 0x00FF0000 ) ); \\ result3 = 6750208
result4 = (( a & 0xFF000000 ) ); \\ result4 = 4278190080
pero perdí el camino. Y la referencia, el enlace y su orientación serán apreciados.
¡¡¡¡¡¡¡Gracias de antemano!!!!!!!
Un problema es que no está cambiando los bits a medida que los lee en el resultado y, dependiendo del compilador, es unsigned int
posible que no sea lo suficientemente grande para un valor de 32 bits. El siguiente código es de un proyecto que no es de Microchip, pero debería mostrarle una idea. Usar el stdint.h
encabezado en sus proyectos generalmente es una buena idea porque puede ver fácilmente el tamaño de los tipos de datos y no confiar en los tamaños dependientes del compilador.
#include <stdint.h>
void write_eeprom_int32(uint16_t addr, uint32_t data)
{
write_eeprom(addr, data & 0xFF);
write_eeprom(addr + 1, data >> 8 & 0xFF);
write_eeprom(addr + 2, data >> 16 & 0xFF);
write_eeprom(addr + 3, data >> 24 & 0xFF);
}
uint32_t read_eeprom_int32(uint16_t addr)
{
uint32_t result;
result = read_eeprom(addr + 3);
result <<= 8;
result += read_eeprom(addr + 2);
result <<= 8;
result += read_eeprom(addr + 1);
result <<= 8;
result += read_eeprom(addr);
return result;
}
Una solución simple es usar a union
para redefinir su unsigned long
a 4 bytes (tenga en cuenta que unsigned int
solo tiene 2 bytes en XC8):
union
{
uint32_t uNumber; // exactly 4 bytes, no larger
unsigned char uByte[4];
} myUnion;
// write to eeprom ...
myUnion.uNumber = 4284967295;
for (unsigned char i = 0; i < 4; ++i)
{
// write myUnion.uByte[i] to eeprom here
}
// read from eeprom ...
for (unsigned char i = 0; i < 4; ++i)
{
// read myUnion.uByte[i] from eeprom here
}
unsigned long uNumberRead = myUnion.uNumber;
unsigned long int a = 4284967295;
unsigned char result[4];
result[0]=a;
result[1]=a>>8;
result[2]=a>>16;
result[3]=a>>24;
j=0;
for(i=*starting_address* ; i<= *starting_address + 4* ; i++)
{
write_eeprom(i,result[j]);
j++;
}
Linards