cancel
Showing results for 
Search instead for 
Did you mean: 

converting BCD

Md Mubdiul Hasan
Associate III
Posted on September 26, 2016 at 10:41

Dear All,

I need to make BCD  4 digit in 7-segment display.

My spi recieved data is 14 bit, take a look this sample code in another MCU.

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);

}

1. How can I implement this idea in RTC application?

2. Is it possible to apply this link ..http://embedded-lab.com/blog/stm32s-internal-rtc/

Kindly help me.

Refference code is required.

19 REPLIES 19
Posted on September 26, 2016 at 14:54

Couldn't one just use %10 and /10 to convert an integer into decimal digits? Also itoa() and sprintf()? For BCD digits %16 and /16 to free the individual 4-bit nibbles containing them.

The STM32 should provide a BCD and binary RTC mode.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Md Mubdiul Hasan
Associate III
Posted on September 27, 2016 at 03:04

Dear Sir Clive,

Thank you for your nice hints. 

Do you want me to use following type,

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)); 

or this is also meaningful in case of data buffer selection, 

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)); 

Posted on September 28, 2016 at 23:18

https://ccsinfo.com/forum/viewtopic.php?p=74137#74137

Md Mubdiul Hasan
Associate III
Posted on October 24, 2016 at 04:02

Dear Sir Clive,

I need your kind attention here. In response to your comment ''The STM32 should provide a BCD and binary RTC mode.'' 1. Are you talking aboutAN3371Application note? 2. STM32 has a BCD counter/timer, people using in this way,http://embedded-lab.com/blog/stm32s-internal-rtc/ 3. Dont you think I need to proceed unit32_t spi data to make BCD in this way?

uint32_t dec2bcd(uint16_t dec) { uint32_t result = 0; int shift = 0; while (dec) { result += (dec % 10) << shift; dec = dec / 10; shift += 4; } return result;}/* Recursive one liner because that's fun*/uint32_t dec2bcd_r(uint16_t dec){ return (dec) ? ((dec2bcd_r( dec / 10 ) << 4) + (dec % 10)) : 0;}

Kindly help me.
Posted on October 24, 2016 at 21:08

The RTC library code can handle binary or BCD usage.

Not sure the value if citing whole web pages, what specifically in the page is an issue here? Posting code without supporting subroutines isn't helpful. Let's restate what the real issue is here. Your have 1234 decimal and you want a some BCD representation as either a) 0x1234 b) Two bytes 0x12 and 0x34 c) Four bytes 0x01, 0x02, 0x03, and 0x04 d) Four bytes 0x30, 0x32, 0x33 and 0x34, ie ASCII string ''1234'' Assuming C

int x = 1234; // some 14-bit value
unsigned char c[4]; // 4 digits
c[0] = (x / 1000) % 10;
c[1] = (x / 100) % 10;
c[2] = (x / 10) % 10;
c[3] = x % 10;

I understand the 7-segment implementation, I really don't understand where the RTC request is coming from, or what SPI device is sending what. You're mixing up a bunch of different thoughts here, you need to provide more clarity, stated in your own words/diagrams.
Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Posted on October 24, 2016 at 21:15

This user trying to make UART data to 4 digit display. In case of SPI data, if uint8_t pDataRx[4] is turned to BCD and fed them in 74HC4511 decoder-driver to 4 digit display. It will work? Further translation is needed or not?

 

Present the data you are receiving, and what you want/expect to be displayed, provide multiple examples.

https://www.sparkfun.com/datasheets/IC/74HC4511.pdf

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Posted on October 24, 2016 at 21:20

int y = 0x1234; // some 4 digits in BCD
unsigned char e[4]; // 4 digits
e[0] = (y >> 12) % 16;
e[1] = (y >> 8) % 16;
e[2] = (y >> 4) % 16;
e[3] = (y >> 0) % 16;

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Md Mubdiul Hasan
Associate III
Posted on October 25, 2016 at 04:39

Dear Sir Clive1,

Thank you from my deep corner.

Yes, things may be confusing to me, because many issues are coming at the same time.

In case of Decimal to binary digit your C code is meaningful.

What I mean from RTC and SPI buffer to BCD data is

1. My SPI data buffer need to convert BCD in other output GPIO.(See the diagram)

2. At the same time I need to show time in 4 digit 7 segment.

Take a look my temperature sensor send/receive code( I am not sure its applicable SPI receive only mode or not)

void MAX31855_chipUnselect()

{

HAL_GPIO_WritePin(GPIOB, GPIO_TEMP_/CS);

}

void MAX31855_chipSelect()

{

HAL_GPIO_WritePin(GPIOB,GPIO_TEMP_/CS, GPIO_PIN_RESET);

}

uint32_t MAX31855_readData()

{

uint8_t pDataRx[4] = { };

MAX31855_chipSelect();

HAL_SPI_Receive(&hspi1, (uint8_t*) pDataRx, 4, 1000);

MAX31855_chipUnselect();

return (pDataRx[i] << 24) | (pDataRx[i] << 16) | (pDataRx[i] << 8) | pDataRx[i];

}

________________

Attachments :

7seg_decoder.PNG : https://st--c.eu10.content.force.com/sfc/dist/version/download/?oid=00Db0000000YtG6&ids=0680X000006I1GT&d=%2Fa%2F0X0000000blB%2FJ_cXxeCUnjQ5l5Rw3U798j7rGbFHPvPDKpHSjQabgq0&asPdf=false
troy1818
Senior
Posted on October 26, 2016 at 11:30

Forgive me, but I am curious. Why on earth do you need to use BCD in the 21st century?