Code: Select all
char Dec_Bcd(char c) {
//R0 is a 'freely usable' (char type) working register in mikroC.
for ( R0 = 0 ; c > 9 ; R0 += 16, c -= 10 );
return R0 + c;
}
First here is the pure C version "bcd2dec2", only to demonstrate a fast mul_10 algorithm for all 8bit non-p18 chips:
10*c = c+c+(c<<3)
Code: Select all
char bcd2dec2(char c) {
#ifdef P18 //hw mult will be used
return Swap(c & 0xF0) * 10 + (c & 15); // 10*NoT + number of ones;
#else
char NoT; //Number of Tens
char tens;//'tens' digit
NoT = Swap(c & 0xF0);
//calculate NoT*10 using 'add' and 'rotate' (NoT < 16)
NoT = NoT + NoT; //2*
tens = NoT + (NoT << 2); // 2* + 8* = (2+8)* = 10*
//calculate the return value
return tens + (c & 15); // 10*NoT + number of ones
#endif
}
The following comparison table contains the asm optimized version too. The table is based on the original functions with the same parameters (the 100% size and speed):
Bcd2Dec(0x99); //result = 99
Dec2Bcd(99); //result = 153 = 0x99
Code: Select all
Dec_Bcd bcd2dec2 Bcd_Dec
size speed size speed size speed
p16: 27% 231% 65% 275% 37% 463%
p16e: 28% 208% 65% 290% 40% 457%
p18: 23% 253% 90% 100% 55% 156%
A PIC16F887 example (measured in the mikroC IDE Debugger):
the new Dec_Bcd(99) is 15 bytes long and 'eats' 106 cycles ( 1/speed )
while Dec2Bcd(99) is 39+17 bytes long and 'eats' 246 cycles
IstvanK