bin2bcd AVR :
Код
u32 bin2bcd_u32(u32 data, u8 result_bytes) NAKED;
u32 bin2bcd_u32(u32 data, u8 result_bytes)
{asm volatile(
"push __tmp_reg__ \n push r26 \n push r27 \n push r30 \n push r31 \n"
"mov __tmp_reg__, %A1 \n" /*number of bytes in result*/
"bin2bcd_u32_00: \n" /*correct input number by left shifts*/
"mov r31, %A0 \n"
"mov %A0, %B0 \n"
"mov %B0, %C0 \n"
"mov %C0, %D0 \n"
"mov %D0, r31 \n"
"dec __tmp_reg__ \n"
"brne bin2bcd_u32_00 \n"
"eor r26, r26 \n" /*clear result*/
"eor r27, r27 \n"
"eor r30, r30 \n"
"eor r31, r31 \n"
"mov __tmp_reg__, %A1 \n"
"lsl __tmp_reg__ \n lsl __tmp_reg__ \n lsl __tmp_reg__ \n" /*__tmp_reg__=size in bits*8*/
"bin2bcd_u32_01: \n" /*shift loop*/
"subi r26,-0x33 \n" /*add 0x33*/
"sbrs r26, 3 \n" /*if carry to bit 3,*/
"subi r26, 3 \n" /*subtract 3*/
"sbrs r26, 7 \n" /*if carry to bit 7,*/
"subi r26, 0x30 \n" /*subtract 0x30*/
"subi r27,-0x33 \n" /*add 0x33*/
"sbrs r27, 3 \n" /*if carry to bit 3,*/
"subi r27, 3 \n" /*subtract 3*/
"sbrs r27, 7 \n" /*if carry to bit 7,*/
"subi r27, 0x30 \n" /*subtract 0x30*/
"subi r30,-0x33 \n" /*add 0x33*/
"sbrs r30, 3 \n" /*if carry to bit 3,*/
"subi r30, 3 \n" /*subtract 3*/
"sbrs r30, 7 \n" /*if carry to bit 7,*/
"subi r30, 0x30 \n" /*subtract 0x30*/
"subi r31,-0x33 \n" /*add 0x33*/
"sbrs r31, 3 \n" /*if carry to bit 3,*/
"subi r31, 3 \n" /*subtract 3*/
"sbrs r31, 7 \n" /*if carry to bit 7,*/
"subi r31, 0x30 \n" /*subtract 0x30*/
"lsl r26 \n rol r27 \n rol r30 \n rol r31 \n" /*shift out buffer*/
"sbrc %D0, 7 \n" /*skip if msbit of input =0*/
"ori r26, 1 \n" /*set lsb of output*/
"lsl %A0 \n rol %B0 \n rol %C0 \n rol %D0 \n"/*shift input*/
"dec __tmp_reg__ \n"
"brne bin2bcd_u32_01 \n" /*repeat for all bits*/
"movw r22, r26 \n" /*move result*/
"movw r24, r30 \n"
"pop r31 \n pop r30 \n pop r27 \n pop r26 \n pop __tmp_reg__\n"
"ret \n"
: :"r"(data),"r"(result_bytes):"r0","r26","r27","r30","r31" /*input and output parameters*/
);
bin2bcd C :
Код
u32 bin2bcd_u32(u32 data, u8 result_bytes)
{u32 result = 0; /*result*/
u8 u8_1;
for (u8_1 = (4 - result_bytes); u8_1; u8_1--) data <<= 8; /*adjust input bytes*/
for (u8_1 = (result_bytes << 3); u8_1; u8_1--) /*bit shift loop*/
{u8 u8_2, u8_3;
/*result BCD nibbles correction*/
result += 0x33333333;
/*result correction loop*/
for (u8_3 = 4; u8_3; u8_3--)
{u8_2 = result >> 24;
if (!(u8_2 & 0x08)) u8_2 -= 0x03;
if (!(u8_2 & 0x80)) u8_2 -= 0x30;
result <<= 8; /*shift result*/
result |= u8_2; /*set 8 bits of result*/
}
/*shift next bit of input to result*/
result <<= 1;
if (((u8)(data >> 24)) & 0x80) result |= 1;
data <<= 1;
}
return(result);
}
bcd2bin AVR (GCC) :
Код
u32 bcd2bin_u32(u32 data, u8 result_bytes) NAKED;
u32 bcd2bin_u32(u32 data, u8 result_bytes)
{asm("push __tmp_reg__ \n push r26 \n push r27 \n push r30 \n push r31 \n"
"eor r26, r26 \n" /*clear result*/
"eor r27, r27 \n"
"eor r30, r30 \n"
"eor r31, r31 \n"
"mov __tmp_reg__, %A1 \n"
"lsl __tmp_reg__ \n lsl __tmp_reg__ \n lsl __tmp_reg__ \n" /*__tmp_reg__=input parameter size in bits*/
"bcd2bin_u32_00: \n" /*bits shift loop*/
"lsr r31 \n ror r30 \n ror r27 \n ror r26 \n" /*shift out buffer*/
"sbrc %A0, 0 \n" /*move lowest bit*/
"ori r31, 0x80 \n"
"lsr %D0 \n ror %C0 \n ror %B0 \n ror %A0 \n"
"sbrc %D0, 7 \n" /*if carry to bit 7,*/
"subi %D0, 0x30 \n" /*subtract 0x30*/
"sbrc %D0, 3 \n" /*if carry to bit 3,*/
"subi %D0, 3 \n" /*subtract 3*/
"sbrc %C0, 7 \n" /*if carry to bit 7,*/
"subi %C0, 0x30 \n" /*subtract 0x30*/
"sbrc %C0, 3 \n" /*if carry to bit 3,*/
"subi %C0, 3 \n" /*subtract 0x30*/
"sbrc %B0, 7 \n" /*if carry to bit 7,*/
"subi %B0, 0x30 \n" /*subtract 0x30*/
"sbrc %B0, 3 \n" /*if carry to bit 3,*/
"subi %B0, 3 \n" /*subtract 3*/
"sbrc %A0, 7 \n" /*if carry to bit 7,*/
"subi %A0, 0x30 \n" /*subtract 0x30*/
"sbrc %A0, 3 \n" /*if carry to bit 3,*/
"subi %A0, 3 \n" /*subtract 3*/
"dec __tmp_reg__ \n" /*repeat for all bits*/
"brne bcd2bin_u32_00 \n"
"movw r22, r26 \n" /*adjust result bytes*/
"movw r24, r30 \n"
"bcd2bin_u32_01: \n"
"mov __tmp_reg__,r25 \n"
"mov r25,r24 \n"
"mov r24,r23 \n"
"mov r23,r22 \n"
"mov r22,__tmp_reg__ \n"
"dec %A1 \n"
"brne bcd2bin_u32_01 \n"
"pop r31 \n pop r30 \n pop r27 \n pop r26 \n pop __tmp_reg__ \n"
"ret \n"
: :"r"(data),"r"(result_bytes):"r0","r26","r27","r30","r31" /*input and output parameters*/
);
}
bcd2bin C :
Код
u32 bcd2bin_u32(u32 data, u8 input_bytes)
{u32 result = 0; /*result*/
u8 cnt_bits, cnt_bytes, tmp_byte;
for (cnt_bits = (input_bytes << 3); cnt_bits; cnt_bits--)
{/*shift next bit*/
result >>= 1;
if (((u8)(data)) & 0x01) result |= 0x80000000;
data >>= 1;
{/*BCD correction of result*/
for (cnt_bytes = 4; cnt_bytes; cnt_bytes--)
{tmp_byte = (data >> 24);
if (tmp_byte & 0x80) tmp_byte -= 0x30;
if (tmp_byte & 0x08) tmp_byte -= 0x03;
data <<= 8;
data |= tmp_byte;
}
}
}
/*adjust result bytes*/
for (cnt_bits = (4 - input_bytes); cnt_bits; cnt_bits--) result >>= 8;
return(result);
}
num2asc C - форматированный вывод числа с фикс.запятой в ASCI-буфер (options&7 = общее количество знаков, (options>>4)&7 = положение запятой считая справа, options&8 = 8 - отображать начальные нули, options&80 = 80 - сначала преобразовать в BCD) :
Код
void num2asc_s32(s32 data, u8 *buf, u8 options)
{u8 cnt_chars, point_pos;
cnt_chars = (options & 7); /*number of digits*/
/*convert negative to positive, set '-' flag*/
if (data < 0) {data = -data; options |= 1;} else options &= ~1;
/*if necessary, convert to BCD*/
if (options & 0x80) data = bin2bcd_u32(data, (cnt_chars >> 1) + 1);
cnt_chars++;
/*calculate point position*/
point_pos = cnt_chars - ((options >> 4) & 7);
if (point_pos) point_pos++;
while (cnt_chars) /*digits conversion loop*/
{if ((options & 8) && (data == 0) && (cnt_chars < point_pos))
{if (options & 1) *buf = asc_minus; else *buf = asc_space;
options &= ~1;
} else
{if ((cnt_chars == point_pos) && (options & 0x70)) /*store point*/
{*buf = asc_point;
cnt_chars--;
buf--;
}
*buf = bin2asc_u8(data); /*store ASCII digit*/
}
cnt_chars--;
buf--;
data >>= 4;
}
if (options & 1) *buf = asc_minus;
}