hi everyone...
i am facing a problem in my college project...
i have a 16bit unsigned integer variable and i need to store it in the 24C02 EEPROM, but that saves 8bit variable at a time...
the number i need to save is in the form of a decimal integer, how do i split it into 2 unsigned char variables..
i am using the following method
unsigned int val; unsigned char a,b; a= (val & 0xFF00)>>8; b=(val * 0x00FF);
is this code right?
and when i read it back i read it like this
unsigned int val; val= (((a & 0x00FF)<<8) | (b & 0x00FF));
is this code right? or is there any other way?
note: i obtain val initially from the user input by using this routine
unsigned int Temp2=0; Temp2*=10; Temp2+=Keypress-'0';
Keypress is the input obtained from the keyboard which is ASCII and in the range '0' to '9' and Temp2 is stored in the EEPROM using the Routine i tried
Error:
i tried saving 1234 and when i read it back i got 1024 6666 was read back as 6656 5555 was read back as 5376 1600 was read back as 1536
"the number i need to save is in the form of a decimal integer"
Not at all. The processor variables don't store any decimal integers. They just store numbers - it's when you present the number that you decide what numeric base to present it with.
b=(val * 0x00FF);
You have val (a 16-bit number) and you multiply with 255.
Take a suitable number - like 12345. Convert to binary. Perform a multiply by 255 and then try to convert that value to binary. Does it seem like it does what you want it to?
Doing the above is called debugging or validating. Proving if the line does what you hope it should do. You would quickly come to a conclusion - answering your question "is this code right?".
And you would then also be able to figure out an answer to: "or is there any other way?"
sorry it was a typo when i was writing it in the forum it is not
b=val*0x00FF;
its
b=val&0x00ff
the '*' and '&' are pretty close on keyboard
And have we then learned to not type code when only a copy from your source code editor will guarantee that you get exactly the code you are using?
1234 -> 1024 0000 0100 1101 0010 -> 0000 0100 0000 0000 6666 -> 6656 0001 1010 0000 1010 -> 0001 1010 0000 0000 5555 -> 5376 0001 0101 1011 0011 -> 0001 0101 0000 0000 1600 -> 1536 0000 0110 0100 0000 -> 0000 0110 0000 0000
See a pattern?
Where is your low byte?
What happens if you shift an 8-bit variable more than 8 bits? Where will the data go if you haven't first made sure there is room for 16 bits?
sorry it was a typo when i was writing it in the forum it is not NEVER DO THAT, ALWAYS use cut-and-paste
there has been several threads that went on for ages with no resolution because the posted code was not the code with the peoblem.
re your original question; have you heard of shift have you heard of union either will work
He has shifted - just that Keil don't do integer promotion...
yes i have heard of shift and would be using that method..
but how do i use a union in this scenario... can you explain with an example
what is integer promotion?
i wanted to know if i was splitting them right
ubit_8 unsigned char ubit_16 unsigned int
bit EEPROM24C02_Save_Data_8Bit(ubit_8 Data, ubit_8 Addr); //Data is 8bit and Addr is a 8bit adress, return 1 when sucessful
bit EEPROM24C02_Read_Data_8Bit(ubit_8 Addr); // Adress to be read, return 1 when sucessfull
what i am trying to do is split the integer into two Character bytes and place them at location ADDR and ADDR+0x01, like Big Endian method, (higher order at first and lower order at last)
/*------------------------------------------------------------------*/ bit EEPROM24C02_Save_Data_16Bit(ubit_16 Data,ubit_8 ADDR) { while(!(EEPROM24C02_Save_Data_8Bit(((Data & 0xFF00)>>8),ADDR)) && (EEPROM24C02_Save_Data_8Bit((Data & 0x00FF),ADDR+0x01))); return 1; } /*------------------------------------------------------------------*/ ubit_16 EEPROM24C02_Read_Data_16Bit(ubit_8 ADDR) { ubit_16 Temp2=0; Temp2|= EEPROM24C02_Read_Data_8Bit(ADDR); Temp2<<=8; Temp2|=EEPROM24C02_Read_Data_8Bit(ADDR+0x01); return Temp2; }
my main function is as follows to check these two functions
void main() { LCD_Initialize(); EEPROM24C02_Save_Data_16Bit(1600,Load1_Page_SL); Convert_Num_Display_16bit(EEPROM24C02_Read_Data_16Bit(Load1_Page_SL)); while(1); }
1600(dummy value) is being shown as 1536 on the LCD, The function Convert_Num_Display_16bit(ubit_16); is correct, i have double checked it.. What is wrong with the code? any corrections
With debugging, you would be able to take the value 0x1234 and split and see yourself if you get 0x12 in one byte and 0x34 in another byte.
Then you would know if you have an issue splitting, or if you have an issue merging.
I'm not joking when I say you have to figure out how to verify issues yourself. First when you do know something doesn't work and can't figure out why is it meaningful to ask on a forum. But your progress will be much higher if you do try to verify statements yourself.
Integer promotion is that a 8-bit char is converted to "int" first, before performing arithmetic on it. This is a requirement in the C language. Cheap to do for a 16-bit or 32-bit processor, but costly for an 8-bit processor where "int" is larger than any register.
So Keil have optioned to generate non-standard code with C51 depending on compiler flags. This means that when you do a shift with your 8-bit char, you shift out real bits into air. You not to explicitly typecast to (unsigned int) before you do the shift, so you have room to store your 8 "high" bits after the shift.
but how do i use a union in this scenario
He has never heard about Google, so the only way to get forward is by asking on the net.
That the answers have already been written and published, making Google searches a must faster route to progression, haven't sunk in yet...