Continue to Site

Decimal to Hex Conversion C Code needed

Status
Not open for further replies.

internetuser2k12

Banned
Hello!

I need to convert decimal values 0 to 255 to hex. Can somebody please give me the c code for decimal to hex conversion?

By hex you mean representation of the decimal number using ASCII characters?
Like '0' 'x' 'A' 'F'

I mean I have to represent decimal 89 like 0x59.
I have to convert values from 0 to 153 decimal to 0x00 to 0x99.

Try this

Code C - [expand]1
2
3
4
5
6
7
8
unsigned char decimal_value;
char hex_value[5]="0x00";

hex_value[2]= (decimal_value/16)+48;     // this gives the high nibble and we add 48 to convert 0..9 to '0'..'9'
hex_value[3]= (decimal_value%16)+48;   // this gives the low nibble and we add 48 to convert 0..9 to '0'..'9'

if (hex_value[2]>'9') hex_value[2]+=7;     // if the stored value is > ASCII '9' then it should be 'A'..'F' so we add 7
if (hex_value[3]>'9') hex_value[3]+=7;     // if the stored value is > ASCII '9' then it should be 'A'..'F' so we add 7

Last edited:

Thank you very much. I will try and let you know.

How can I convert decimal 153 to 0x99 with your code. I need the result 0x99 in one piece i.e., in one variable.

Please note the edit I did

Actually I want to give Hex data to ds1307. my variables are decimal type. You can see my post page 5 of https://www.edaboard.com/threads/272381/

I tried giving Dec2Bcd converted value to DS 1307, but it did not work. I feel it takes hex values as input to write to ds1307 registers.

what is hex_value[0] and hex_value[1] in your code? Is it 0 and x?

Last edited:

You can also use sprintf instead of a custom code but it will spend more resources

Code:
sprintf(hex_value, "0x%X", decimal_value);

- - - Updated - - -

You asked from a hex number in ascii so it is '0' 'x' and the converted numbers, it results to "0x00" - "0xFF"

- - - Updated - - -

DS1307 doesn't need hexadecimal in ASCII format but BCD

How can I convert decimal 153 to 0x99 with your code. I need the result 0x99 in one piece i.e., in one variable.
The comment reveals that the question has been and is still unclear.
153 and 0x99 are both string representations of the same numeric value. If you put the value into a single variable, e.g. unsigned char or BYTE, both look the same, nothing to convert.

In which form is the decimal input given, how is the hexadecimal output intended? Please tell both variable types.

P.S.:
DS1307 doesn't need hexadecimal but BCD
That's the point. Why didn't you mention RTC usage in your first post?

bigdogguru

bigdogguru

Points: 2
I am not printing. I am using the result to set a register.

Can I use like this. I modified your code.
Code:
 min = ((min/16) << 4) + (min%16)

eg: decimal 89. min/16 = 89/16 = 5, (min/16) << 4 ) = 5<<4 = 50, 89%16 = 9, 50 + 9 = 59 = 0x59

- - - Updated - - -

Check this link. The problem is mentioned here. http://www.mikroe.com/forum/viewtopic.php?f=147&t=51606&p=201387#p201387

Earlier I thought I needed Dec2Bcd, but now I am sure I need Dec2Hex

Writing RTC registers needs in fact Dec2Bcd(), as you have written it in your posts
Code:
s_sec = (((ssec / 10) << 4) | (ssec % 10));
Besides this thread there are tons of RTC driver code on the internet. You are re-inventing the wheel.

bigdogguru

bigdogguru

Points: 2
But that code is not working. If I use that to set values, I see that if I increment any variable greater than 10, it behave abnormally and there will be a lot of number displaying. You can check my simulation.

- - - Updated - - -

Are you tellin that, I have to use
Code:
 (((ssec / 10) << 4) | (ssec % 10));
for my ds1307 problem and I have to give decimal 59 to get bcd 59 for minutes?

It is doing like this. What is the purpose of it if it converts 59 to 59?

ssec = d59
ssec/10 = d5
5 << 4 = 0x50 or d50
59%10 = 9
0x50 | 9 = 59

decimal 99 = 1001 1001 BCD = 0x99. So I have to give 0x99. Does diving decimal 99 also works with rtc ds1307?

Last edited:

Do you understand what BCD is?

In BCD the low and high nibble gets the value 0-9 (0000-1001)

A decimal like 23 converted to BCD is 2 for the high nibble (0010) and 3 for the low nibble (0011) , this results to 0b00100011 or decimal 35

FvM

FvM

Points: 2
It works for my DS1307, I presume it does for your's to. BCD means that you have to put two decimals into a hexidecimal representation.

There may be many reasons why your code doesn't work, another point why I suggested to use a ready made driver code.

BCD coded numbers are explained in detail in the DS1307 or any other standard RTC datasheet.

@ alexan

decimal 23 is split into 0010 and 0011 so it becomes 00100011 which is becomes 0x23 and decimal 35. Does that mean that decimal 23 becomes decimal 35? or is it 35 BCD?

- - - Updated - - -

@ FvM

Can you give me one working code of rtc ds1307 with time setting functionality using C code.

Finally tell me what decimal value should I use if I have to get hex 99 or bcd 99 to write year 99 to rtc. should I give decimal 153 to rtc register for 0x99 or 99 bcd

Please somebody have a look at my project here http://www.mikroe.com/forum/viewtopic.php?f=147&t=51606&p=201387#p201387
There is an attachment with latest code. please tell me what i am doing wrong with writing values to rtc.

Last edited:

From your previous posts, I gather you are utilized MikroC with a PIC microcontroller.

If this is correct, the following is such an example of DS1307 app with BCD to Character routines:

DS1307 + PIC16F877A

Code:
//Sample code for
//DS1307 RTC Ineterfacing with PIC16F877A
//Coded by Pynn Pynn
//Compiler: mikroC 8.0.0
//http://picnote.blogspot.com
//07/06/2008
//Use with your own risk

unsigned short sec;
unsigned short minute;
unsigned short hour;
unsigned short day;
unsigned short date;
unsigned short month;
unsigned short year;
unsigned short data;
char time[9];
char ddate[11];

unsigned char BCD2UpperCh(unsigned char bcd);
unsigned char BCD2LowerCh(unsigned char bcd);

void main(){

I2C_Init(100000); //DS1307 I2C is running at 100KHz
PORTB = 0;
TRISB = 0; // Configure PORTB as output
TRISC = 0xFF;
Lcd_Init(&PORTB); // Initialize LCD connected to PORTB
Lcd_Cmd(Lcd_CLEAR); // Clear display
Lcd_Cmd(Lcd_CURSOR_OFF); // Turn cursor off
Lcd_Out(1, 1, "TIME:");
Lcd_Out(2, 1, "DATE:");

while(1)
{

time[0] = BCD2UpperCh(hour);
time[1] = BCD2LowerCh(hour);
time[2] = ':';
time[3] = BCD2UpperCh(minute);
time[4] = BCD2LowerCh(minute);
time[5] = ':';
time[6] = BCD2UpperCh(sec);
time[7] = BCD2LowerCh(sec);
time[8] = '\0';

ddate[0] = BCD2UpperCh(date);
ddate[1] = BCD2LowerCh(date);
ddate[2] ='/';
ddate[3] = BCD2UpperCh(month);
ddate[4] = BCD2LowerCh(month);
ddate[5] ='/';
ddate[6] = '2';
ddate[7] = '0';
ddate[8] = BCD2UpperCh(year);
ddate[9] = BCD2LowerCh(year);
ddate[10] = '\0';

Lcd_Out(1,6,time);
Lcd_Out(2,6,ddate);
Delay_ms(500);
}
}

{
I2C_Start();
I2C_Wr(0xd0); //address 0x68 followed by direction bit (0 for write, 1 for read) 0x68 followed by 0 --> 0xD0
I2C_Repeated_Start();
I2C_Wr(0xd1); //0x68 followed by 1 --> 0xD1
data=I2C_Rd(0);
I2C_Stop();
return(data);
}

unsigned char BCD2UpperCh(unsigned char bcd)
{
return ((bcd >> 4) + '0');
}

unsigned char BCD2LowerCh(unsigned char bcd)
{
return ((bcd & 0x0F) + '0');
}

BigDog

FvM

FvM

Points: 2
if you have

Code:
unsigned char my_decimal=23;
unsigned char my_bcd;

//and use

my_bcd = DEC2BCD(my_decimal);

// now my_bcd equals 35 because that represent the BCD value 23

Thanks bigdogguru. But where is the code which sets the ds1307 to some time?

- - - Updated - - -

@ alexan

So you are saying that I have to conver my decimal 23 to bcd 35 and write that 0x35 to hours register to set it to 23 hours. So after it is set and again read and transformed using bcd2dec I get my 23 back. Am I right?

Add the following routines:

DS1307 : Setting Time

Code:
void write_ds1307(unsigned short address,unsigned short w_data)
{
I2C_Start(); // issue I2C start signal
//address 0x68 followed by direction bit (0 for write, 1 for read) 0x68 followed by 0 --> 0xD0
I2C_Wr(0xD0); // send byte via I2C (device address + W)
I2C_Wr(address); // send byte (address of DS1307 location)
I2C_Wr(w_data); // send data (data to be written)
I2C_Stop(); // issue I2C stop signal
}

//Set Time
write_ds1307(0,0x80); //Reset second to 0 sec. and stop Oscillator
write_ds1307(1,0x27); //write min 27
write_ds1307(2,0x14); //write hour 14
write_ds1307(3,0x02); //write day of week 2:Monday
write_ds1307(4,0x17); // write date 17
write_ds1307(5,0x06); // write month 6 June
write_ds1307(6,0x08); // write year 8 --> 2008
write_ds1307(7,0x10); //SQWE output at 1 Hz
write_ds1307(0,0x00); //Reset second to 0 sec. and start Oscillator

BigDog

So you are saying that I have to conver my decimal 23 to bcd 35 and write that 0x35 to hours register to set it to 23 hours. So after it is set and again read and transformed using bcd2dec I get my 23 back. Am I right?
Not particularly.

Lean back, relax!

You'll write 0x23 (or decimal 35) to the RTC register to write a time value of 23.

bigdogguru

Points: 2