Using the definition of the ASCII characters leads to an extremely time- and code saving solution. The ASCII-table shows that
values 0... 9 <=> figures '0'...'9' <=> 0x30...0x39 in ASCII code;
values 10...15 <=> figures 'A'...'F' <=> 0x41...0x46 in ASCII code;
or 'a'...'f' <=> 0x61...0x66 in ASCII code;
Sometimes lower case letters are used for 'a' to 'f'.
So if the value of our nibble is below 10 (0000b to 1001b) the character representation would be 0x30 + n or, in c-syntax '0'+n.
If n is between 10 and 15 (1010b to 1111b) 0x41 + n - 10 or 'A'+n-10.
Using unsigned int 8bit instead of type char:
uint8_t nibble2char( uint8_t n ) {
// make sure that n e {0x00,...,0x0F}
if( n<10 ) return '0'+n;
else return 'A'+n-10;
}
or shorter:
uint8_t nibble2char( uint8_t n ) {
// make sure that n e {0x00,...,0x0F}
return n<10 ? '0'+n : 'A'+n-10;
}
or as a macro (thanks to chqrlie for the (n) ):
#define NIBBLE_TO_CHAR(n) ((n)<10 ? '0'+(n) : 'A'+(n)0) // n <= 15 !
If lower case letters should be used replace 'A' by 'a'.
Converting a byte with 2 nibbles to a 2-byte 0-terminated string you could use:
void byte2str( uint8_t* s, uint8_t n ) {
// s points to a string of at least 3 Bytes length !
uint8_t hi = ( n >> 4 ) & 0x0F ;
uint8_t lo = n & 0x0F ;
s[0] = NIBBLE_TO_CHAR( hi ); // high byte
s[1] = NIBBLE_TO_CHAR( lo ); // low byte
s[2] = 0;
}
EDIT:
With correction of chqrlie to the macro, the function becomes more compact:
void byte2str( uint8_t* s, uint8_t n ) {
// s points to a string of at least 3 Bytes length !
s[0] = NIBBLE_TO_CHAR( ( n >> 4 ) & 0x0F ); // high byte
s[1] = NIBBLE_TO_CHAR( n & 0x0F ); // low byte
s[2] = 0;
}