| 
	
	|  |  |  
	
		| View previous topic :: View next topic |  
		| Author | Message |  
		| w2drz 
 
 
 Joined: 27 Dec 2006
 Posts: 55
 Location: Western New York - USA
 
 
			      
 
 | 
			
				| 16 bit binary to bcd C++ conversion program |  
				|  Posted: Wed Dec 27, 2006 5:01 am |   |  
				| 
 |  
				|   
 After a week of not haveing a working program so I ask here.
 
 Need a C++ pgm for the CCS compiler of a 16bit binary to 5  BCD routine.
 I am using a 18F4580 20 MHz, have 50% pgm. mem left.
 
 As in 7th decade don't need to spend more time in frustration trying.
 
 Thank You
 
 Tom
 |  |  
		|  |  
		| PCM programmer 
 
 
 Joined: 06 Sep 2003
 Posts: 21708
 
 
 
			    
 
 | 
			
				|  |  
				|  Posted: Wed Dec 27, 2006 12:56 pm |   |  
				| 
 |  
				| The answer is in the forum archives.  Go to the search page, here: http://www.ccsinfo.com/forum/search.php
 Type in these keywords:  binary BCD
 Then set it to "Search for all terms" and click the Search button.
 
 Also search for this keyword:   bin2bcd
 
 -------
 
 The CCS compiler is not C++.  It's just C.
 |  |  
		|  |  
		| w2drz 
 
 
 Joined: 27 Dec 2006
 Posts: 55
 Location: Western New York - USA
 
 
			      
 
 | 
			
				| 16 bit binary to bcd C++ conversion or 16 bin to 5 bcd |  
				|  Posted: Wed Dec 27, 2006 3:00 pm |   |  
				| 
 |  
				|  	  | PCM programmer wrote: |  	  | The answer is in the forum archives.  Go to the search page, here: http://www.ccsinfo.com/forum/search.php
 Type in these keywords:  binary BCD
 Then set it to "Search for all terms" and click the Search button.
 
 Also search for this keyword:   bin2bcd
 
 -------
 
 The CCS compiler is not C++.  It's just C.
 | 
 
 
   
 Thanks for the answer, BUT have tried that routine, it is 8 bit binary conversion to 2 byts BCD, resule is not what is needed,
 
 what am asking for is a routine that use a LONG (16) bit binary to produce the result of 5 bytes BCD.
 
 I am not that great of a programmer and it eludes me how to do the 16 binary to 5 byte BCD.
 Here is a sample of what I now need to do Also bin to BCD of x .
 
 void NEWbinary_MATH (float az, float el)
 {
 long	bin, x;
 // VK3UM is "0" to "F" or HEX DATA 12/26/06
 x = bin = tobinary (az);					// do binary math
 
 AZCountMSB = bin >> 8;					// make ready to send out
 AZCountLSB = bin & 0xff;				// make ready to
 
 Thanks for some help
 
 tom
 |  |  
		|  |  
		| PCM programmer 
 
 
 Joined: 06 Sep 2003
 Posts: 21708
 
 
 
			    
 
 | 
			
				|  |  
				|  Posted: Wed Dec 27, 2006 3:24 pm |   |  
				| 
 |  
				| But if you did the first search that I suggested, you will find Humberto's code in this thread:
 http://www.ccsinfo.com/forum/viewtopic.php?t=25835&highlight=binary+bcd
 
 He doesn't pack the results.   Each BCD digit is stored in a 16-bit
 global variable.   But it does work, as the test program below shows.
 
 
 
  	  | Code: |  	  | #include <18F452.h> #fuses XT, NOWDT, PUT, BROWNOUT, NOLVP
 #use delay(clock=4000000)
 #use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, ERRORS)
 
 long Dig_0, Dig_1, Dig_2, Dig_3, Dig_4;
 
 void bin_to_Dig(long bin_inp)
 {
 long temp;
 
 temp  = bin_inp;
 Dig_4 = temp/10000;
 temp  = temp - (Dig_4 * 10000);
 
 Dig_3 = temp/1000;
 temp  = temp - (Dig_3 * 1000);
 
 Dig_2 = temp/100;
 temp  = temp - (Dig_2 * 100);
 
 Dig_1 = temp/10;
 temp  = temp - (Dig_1 * 10);
 
 Dig_0 = temp;
 }
 
 //============================
 void main()
 {
 bin_to_dig(0x7E);
 printf("%ld%ld%ld%ld%ld\n\r", Dig_4, Dig_3, Dig_2, Dig_1, Dig_0);
 
 bin_to_dig(0x8000);
 printf("%ld%ld%ld%ld%ld\n\r", Dig_4, Dig_3, Dig_2, Dig_1, Dig_0);
 
 bin_to_dig(0xFFFF);
 printf("%ld%ld%ld%ld%ld\n\r", Dig_4, Dig_3, Dig_2, Dig_1, Dig_0);
 
 while(1);
 
 }
 | 
 |  |  
		|  |  
		| w2drz 
 
 
 Joined: 27 Dec 2006
 Posts: 55
 Location: Western New York - USA
 
 
			      
 
 | 
			
				|  |  
				|  Posted: Wed Dec 27, 2006 3:38 pm |   |  
				| 
 |  
				|  	  | PCM programmer wrote: |  	  | But if you did the first search that I suggested, you will find Humberto's code in this thread:
 http://www.ccsinfo.com/forum/viewtopic.php?t=25835&highlight=binary+bcd
 
 He doesn't pack the results.   Each BCD digit is stored in a 16-bit
 global variable.   But it does work, as the test program below shows.
 
 
 
  	  | Code: |  	  | #include <18F452.h> #fuses XT, NOWDT, PUT, BROWNOUT, NOLVP
 #use delay(clock=4000000)
 #use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, ERRORS)
 
 long Dig_0, Dig_1, Dig_2, Dig_3, Dig_4;
 
 void bin_to_Dig(long bin_inp)
 {
 long temp;
 
 temp  = bin_inp;
 Dig_4 = temp/10000;
 temp  = temp - (Dig_4 * 10000);
 
 Dig_3 = temp/1000;
 temp  = temp - (Dig_3 * 1000);
 
 Dig_2 = temp/100;
 temp  = temp - (Dig_2 * 100);
 
 Dig_1 = temp/10;
 temp  = temp - (Dig_1 * 10);
 
 Dig_0 = temp;
 }
 
 //============================
 void main()
 {
 bin_to_dig(0x7E);
 printf("%ld%ld%ld%ld%ld\n\r", Dig_4, Dig_3, Dig_2, Dig_1, Dig_0);
 
 bin_to_dig(0x8000);
 printf("%ld%ld%ld%ld%ld\n\r", Dig_4, Dig_3, Dig_2, Dig_1, Dig_0);
 
 bin_to_dig(0xFFFF);
 printf("%ld%ld%ld%ld%ld\n\r", Dig_4, Dig_3, Dig_2, Dig_1, Dig_0);
 
 while(1);
 
 }
 | 
 | 
 
 
 Hmmmm,
 I had looked at that code several days ago but did not try it??? wo be me....
 
 Thanks, hope this is the answer to the problem.
 
 Will add that routine and see how all works when finished.
 
 Thank You much,
 
 tom
  |  |  
		|  |  
		| w2drz 
 
 
 Joined: 27 Dec 2006
 Posts: 55
 Location: Western New York - USA
 
 
			      
 
 | 
			
				|  |  
				|  Posted: Fri Dec 29, 2006 5:40 am |   |  
				| 
 |  
				| Hi, Wish to thank for the help here.
 It was of great help.
 So I am posting the code results if it would be of help to others.
 
 Thank You
 tom
 
  	  | Code: |  	  | long Dig_0, Dig_1, Dig_2, Dig_3, Dig_4;
 
 void bin_to_Dig(long bin_inp)
 {                        // This is for VK3UM program
 long temp;      //   16 bit binary to BCD 5 byte
 int nibh;
 int nibl;
 
 temp = bin_inp / 18.2041667;   // make into binary degrees  value
 
 Dig_4 = temp/10000;
 temp  = temp - (Dig_4 * 10000);
 
 Dig_3 = temp/1000;
 
 temp  = temp - (Dig_3 * 1000);
 
 Dig_2 = temp/100;
 temp  = temp - (Dig_2 * 100);
 
 nibh = Dig_3;
 nibl = Dig_2;
 CountMSB = (nibl|(nibh<<4));
 
 Dig_1 = temp/10;
 temp  = temp - (Dig_1 * 10);
 
 Dig_0 = temp;
 
 nibh = Dig_1;   // MSB BYTE make ready to send out This is the 2nd digit
 nibl = Dig_2;   // LSB BYTE make ready to send out This is the 1st digit
 CountMSB = (nibl|(nibh<<4));
 
 nibh = Dig_3;   // MSB BYTE make ready to send out This is the 3rd digit
 nibl = Dig_0;   // LSB BYTE make ready to send out is .1 value
 CountLSB = (nibl|(nibh<<4));
 
 }
 | 
 
    |  |  
		|  |  
		| Ttelmah Guest
 
 
 
 
 
 
 
			
			
			
			
			
			
			
			
			
 
 | 
			
				|  |  
				|  Posted: Fri Dec 29, 2006 8:52 am |   |  
				| 
 |  
				| As an 'aside', to anyone looking at this, there is a much more efficient algorithm available. The problem is that division, takes a lot of work. Performing the five divisions, and five multiplications involved in the simple algorithm posted, uses perhaps the best part of 2000 instruction cycles, even on a PIC18. On chips without the hardware multiplier, the time goes up by perhaps another 500 cycles. the alternative, produces 'packed' BCD (where the digits are returned 2 to the byte), and just for information, a simple version is posted here: 
  	  | Code: |  	  | void toBCD(int16 val,int8 * buff) {
 //converts 16bit value, to five BCD digits. Tries to do it fairly
 //efficiently, both in size, and speed.
 int1 temp_bit;
 int8 nibctr;
 buff[0]=buff[1]=buff[2]=0;
 do {
 if ((buff[0] & 0xF)>=5) buff[0]+=3;
 if ((buff[0] & 0xF0)>=0x50) buff[0]+=0X30;
 if ((buff[1] & 0xF)>=5) buff[1]+=3;
 if ((buff[1] & 0xF0)>=0x50) buff[1]+=0X30;
 if ((buff[2] & 0xF)>=5) buff[2]+=3;
 temp_bit=shift_left(&val,2,0);
 shift_left(buff,3,temp_bit);
 } while (val!=0);
 }
 
 void main() {
 int16 val;
 //three bytes for packed BCD result
 int8 buff[3];
 setup_adc_ports(NO_ANALOGS);
 setup_adc(ADC_OFF);
 setup_psp(PSP_DISABLED);
 setup_spi(FALSE);
 setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
 setup_timer_1(T1_DISABLED);
 setup_timer_2(T2_DISABLED,0,1);
 val=12345;
 toBCD(val,buff);
 //At this point, the three bytes will contain:
 // 45
 // 23
 // 01
 while (true);
 }
 
 | 
 This approach produces the 'packed' bytes, required b many devices, and only uses about 100 instructions (depends on the processor), executing in about 1000 cycles.
 
 Best Wishes
 |  |  
		|  |  
		| w2drz 
 
 
 Joined: 27 Dec 2006
 Posts: 55
 Location: Western New York - USA
 
 
			      
 
 | 
			
				|  |  
				|  Posted: Fri Dec 29, 2006 5:36 pm |   |  
				| 
 |  
				| Hi to whom ever on the fast BCD program posted, 
 The progam posted as "better",
 I can not make it run witout crashing the PICC
 after it does several new conversions.
 As I said in the earler post on this subject of BCD,
 Im not the most swift programmer going.
 At this time in life don't expect to become much better,
 but I'll try with a bit of help.
 So a bit of explaining in the remarks as to what is occuring in the programm would be nice.
 the 3 buffers being used, I understand that the result shoud be:
 buffer 0 is least nibble #1 on the right, left nibble is #2
 buffer 1 is #3 right,  #4 is left
 buffer is most signifant #5 nibble to the right.
 
 Thank You,
 tom
  |  |  
		|  |  
		| w2drz 
 
 
 Joined: 27 Dec 2006
 Posts: 55
 Location: Western New York - USA
 
 
			      
 
 | 
			
				|  |  
				|  Posted: Sat Dec 30, 2006 3:46 am |   |  
				| 
 |  
				| Hi, 
 Just realized that the I/O rtn is not normal results for the byte output!!
 This is do a requirement of the outside software program.
 
 Here is the "special" output of the low 4 digits in the special mode I use:
 
  	  | Code: |  	  | nibh = Dig_1; // MSB BYTE make ready to send out This is the 2nd digit
 nibl = Dig_2; // LSB BYTE make ready to send out This is the 1st digit
 CountMSB = (nibl|(nibh<<4));
 
 nibh = Dig_3; // MSB BYTE make ready to send out This is the 3rd digit
 nibl = Dig_0; // LSB BYTE make ready to send out is .1 value
 CountLSB = (nibl|(nibh<<4));
 | 
 Here is the "normal" output of the low 4 digits in the normal mode:
 
  	  | Code: |  	  | nibh = Dig_1; // MSB BYTE make ready to send out This is the 2nd digit
 nibl = Dig_0; // LSB BYTE make ready to send out This is the 1st digit
 CountMSB = (nibl|(nibh<<4));
 
 nibh = Dig_3; // MSB BYTE make ready to send out This is the 3rd digit
 nibl = Dig_2; // LSB BYTE make ready to send out is .1 value
 CountLSB = (nibl|(nibh<<4));
 | 
   
 tom
 |  |  
		|  |  
		| w2drz 
 
 
 Joined: 27 Dec 2006
 Posts: 55
 Location: Western New York - USA
 
 
			      
 
 | 
			
				| 16 bit BCD BYTE output "normal" this is the correc |  
				|  Posted: Sat Dec 30, 2006 3:54 am |   |  
				| 
 |  
				| Hi, 
 Messed that post up as to be correct,
 here is the correct output for the 2 bytes, think I need sleep!!!!
 
 Here is the "normal" output of the low 4 digits in the normal mode:
 
  	  | Code: |  	  | nibh = Dig_1; // MSB BYTE make ready to send out This is the 2nd digit
 nibl = Dig_0; // LSB BYTE make ready to send out This is the 1st digit
 CountLSB = (nibl|(nibh<<4));
 
 nibh = Dig_3; // MSB BYTE make ready to send out This is the 3rd digit
 nibl = Dig_2; // LSB BYTE make ready to send out is .1 value
 CountMSB = (nibl|(nibh<<4));
 | 
   
 tom
  |  |  
		|  |  
		| Ttelmah Guest
 
 
 
 
 
 
 
			
			
			
			
			
			
			
			
			
 
 | 
			
				|  |  
				|  Posted: Sun Dec 31, 2006 10:25 am |   |  
				| 
 |  
				|  	  | tom wrote: |  	  | Hi to whom ever on the fast BCD program posted, 
 The progam posted as "better",
 I can not make it run witout crashing the PICC
 after it does several new conversions.
 As I said in the earler post on this subject of BCD,
 Im not the most swift programmer going.
 At this time in life don't expect to become much better,
 but I'll try with a bit of help.
 So a bit of explaining in the remarks as to what is occuring in the programm would be nice.
 the 3 buffers being used, I understand that the result shoud be:
 buffer 0 is least nibble #1 on the right, left nibble is #2
 buffer 1 is #3 right,  #4 is left
 buffer is most signifant #5 nibble to the right.
 
 Thank You,
 tom
  | 
 Have just run it through 3500 conversions, without a 'crash'. There is nothing in the code to cause a problem (think about what it is doing...). The only problems would be if it is not called as shown, or the buffer sizes were not right (when it could overwrite adjacent memory cells). The only fault as posted, is that I declare 'nibctr', and never use it. This was because I tried a version using a union to access the nibbles, and this was slower than using the multiple accesses shown.
 
 Best Wishes
 |  |  
		|  |  
		| w2drz 
 
 
 Joined: 27 Dec 2006
 Posts: 55
 Location: Western New York - USA
 
 
			      
 
 | 
			
				| 16 bit binary to BCD, and a thank you |  
				|  Posted: Sun Dec 31, 2006 11:53 am |   |  
				| 
 |  
				| Hi, 
 What the conversion as I coded it was not true BCD in what I finally found.
 The results in my use of your program had the conversion to be 0-F.
 
 As I need the results to be 0-9 for each nibble.
 
 As I found in the debug was memory over write as sending data back to the rest of  my program.
 
 I am not that swift of programmer here as a self learned C code,
 a (old, 70 yrs) person that have only been using "C" for 4 years.
 So I need much help for this type of problem.
 If there is a answer to use your program with a conversion of the BUFF's to  2 byte's, would greatly thank you.
 Only need the 4 low nibbles, as the 5th high in buff 2 will always be zero as I devide the incoming binary 16 bit with:
 
 temp = bin_inp / 18.2041667;	// make into binary degrees  value
 
 This is 16 bit in to binary 360 degrees of a compleat circle.
 
 Then with the new code interface to outside tracking program requires:
 0000 -  3600 decimal out put to it.
 here is the program that works fine in my program,
 would much prefer to be able to use the one you provided if possilble.
 "MY PROGRM" next and yours at the bottom.
 Also note that part of the problem is that the output nibbles are mixed in the values of each byte with also the MSB byte and the LSB byte's are not normal as to the decimal value in each.
 
 Thank you for your time and effort.
 tom
 ........
 
  	  | Code: |  	  | long Dig_0, Dig_1, Dig_2, Dig_3, Dig_4;
 
 void bin_to_Dig(long bin_inp)
 {                        // This is for VK3UM program
 long temp;      //   16 bit binary to BCD 5 byte
 int nibh;
 int nibl;
 
 temp = bin_inp / 18.2041667;   // make into binary degrees  value
 
 //Dig_4 = temp/10000;            // This is not needed as just 4 digits
 //temp  = temp - (Dig_4 * 10000);   // this will always be zero
 
 Dig_3 = temp/1000;
 
 temp  = temp - (Dig_3 * 1000);
 
 Dig_2 = temp/100;
 temp  = temp - (Dig_2 * 100);
 
 Dig_1 = temp/10;
 temp  = temp - (Dig_1 * 10);
 
 Dig_0 = temp;
 
 nibh = Dig_1;   // MSB BYTE  This is the 2nd digit
 nibl = Dig_2;   // LSB BYTE  This is the 1st digit
 CountMSB = (nibl|(nibh<<4));
 
 nibh = Dig_3;   // MSB BYTE  This is the 3rd digit
 nibl = Dig_0;   // LSB BYTEs This is the 0rd digit, .1 value
 CountLSB = (nibl|(nibh<<4));
 
 | 
 what are the values in each buff ???
 
  
 Last edited by w2drz on Sun Dec 31, 2006 4:00 pm; edited 2 times in total
 |  |  
		|  |  
		| w2drz 
 
 
 Joined: 27 Dec 2006
 Posts: 55
 Location: Western New York - USA
 
 
			      
 
 | 
			
				| 16 bit to BCD the paste is still messed up 2nd post |  
				|  Posted: Sun Dec 31, 2006 12:24 pm |   |  
				| 
 |  
				| here is what I coded using your pgm. 
  	  | Code: |  	  | void bin_to_Dig(int16 bin_inp,int8 * buff){
 //converts 16bit value, to five BCD digits. Tries to do it fairly
 //efficiently, both in size, and speed.
 int8 nibh;
 int8 nibl;
 int1 temp_bit;
 int8 nibctr;
 buff[0]=buff[1]=buff[2]=0;
 
 do {
 if ((buff[0] & 0xF)>=5) buff[0]+=3;
 if ((buff[0] & 0xF0)>=0x50) buff[0]+=0X30;
 if ((buff[1] & 0xF)>=5) buff[1]+=3;
 if ((buff[1] & 0xF0)>=0x50) buff[1]+=0X30;
 if ((buff[2] & 0xF)>=5) buff[2]+=3;
 temp_bit=shift_left(&bin_inp,2,0);
 shift_left(buff,3,temp_bit);
 } while (bin_inp!=0);
 
 nibh = 0;    //buff[0] >> 4;   // buff 0 (1) msnibble = 2nd digit
 nibl = 0;     //buff[1] & 0x04;   // buff 1 (2) lsnibble = 1st digit
 CountMSB = (nibl|(nibh<<4; // buff 1 (1) msnibble = 3nd digit
 nibl = 0;    //buff[0] & 0x04;   // buff 0 (0) lsnibble = 0 digit
 CountLSB = (nibl|(nibh<<4));
 
 | 
 The output shown only does the one nibble out as a test,
 this did up  to "F" out in my interface to the outside tracking program
 
 tom
  
 Last edited by w2drz on Sun Dec 31, 2006 5:01 pm; edited 4 times in total
 |  |  
		|  |  
		| w2drz 
 
 
 Joined: 27 Dec 2006
 Posts: 55
 Location: Western New York - USA
 
 
			      
 
 | 
			
				| 16 bit and this is the right code for your pgm end |  
				|  Posted: Sun Dec 31, 2006 12:44 pm |   |  
				| 
 |  
				| Hi. This is the correct code to your program end.
 
 I had a test to determine what the value's were and did not correct the code I sent prior of your program
 
  	  | Code: |  	  | nibh = buff[0] >> 4;
 nibl = buff[1] & 0x04;
 CountMSB = (nibl|(nibh<<4>> 4;
 nibl = buff[0] & 0x04;
 CountLSB = (nibl|(nibh<<4));
 }
 | 
 
 tom
  |  |  
		|  |  
		| haqamar 
 
 
 Joined: 26 Dec 2011
 Posts: 3
 
 
 
			    
 
 | 
			
				|  |  
				|  Posted: Sat Apr 13, 2013 2:33 pm |   |  
				| 
 |  
				| Hi Ttelmah, 
 I tested your earlier posted code but with strange results.
 
 if int16 = 12345, output  01 23 45
 if int16 = 1234, output 00 06 17
 if int16 = 10, output 00 00 05
 if int16 = 2, output 00 00 01
 
 Why its so ?
 
 
 
 hammad
 |  |  
		|  |  
		|  |  
  
	| 
 
 | You cannot post new topics in this forum You cannot reply to topics in this forum
 You cannot edit your posts in this forum
 You cannot delete your posts in this forum
 You cannot vote in polls in this forum
 
 |  
 Powered by phpBB © 2001, 2005 phpBB Group
 
 |