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 October 26, 2016 at 14:43

In the 21st century it still simplifies external logic.

If output is needed in decimal, it is a lot easier to contain each digit in the 0-9 range than have it as 8 or 16-bit binary and decompose it into decimal digits later. ie avoids division and multiplication, which are complicated/expensive at a gate level.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
torsten23
Associate
Posted on October 26, 2016 at 18:00

If you don't care about run time that's the straight forward way. For a project where the task of converting was time critial I searched and found a nice algo at http://www.oocities.org/v_d_d/gba/Bin2BCD.s.txt. Please note that this Game Boy Advanced code is ARM code, I ported that to to thumb and optimized a little bit more.

With best regards,

Torsten

Posted on October 26, 2016 at 18:46

If you don't care about run time that's the straight forward way.

I was going for brutal clarity, in my opinion this is ''just math'', and the simpler it is to demonstrate the quicker we can get to the more complex and efficient methods.

I do like the example snippet, ARM had a whole cook-book of these types of brutally efficient shortcuts.

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 27, 2016 at 04:47

Dear Sir Clive, 

My company just give me old version code for this project, which has been run/debug/test in coocox IDE.

I found nothing to make binary to BCD here.

I feel this whole device code is most time consuming because,

1. Key driver H and C files.( made for press keys)

2. State files for seven segment, main state and global.

3. There is nothing in SPI data converted to BCD, but in seven segment state file  void sevenseg_val_set(uint32 value) function has been used.

Now, what would be my new work, I dont understand. They did not use DMA, but flash code has made.

Posted on October 27, 2016 at 05:16

I'm not sure what you expect me to do, this isn't my job/responsibility.

This code looks dysfunctional :

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

The variable i isn't set, and presumably you don't want to repeat the same 8-bits throughout a 32-bit word.

Not sure of the endian order of the SPI data here, but something like 0..3 or 3..0 would seem more appropriate.

return (pDataRx[0] << 24) | (pDataRx[1] << 16) | (pDataRx[2] << 8) | pDataRx[3];

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 27, 2016 at 05:29

https://datasheets.maximintegrated.com/en/ds/MAX31855.pdf

Returns 14-bit signed binary number in +8191/-8192 range

So presumably want to take that number in as binary and crack it into 4 digits that you sequence to the display.

The 7-segments are attach to the same GPIO bank, you could presumably cycle the digit display using a circular DMA (memory to GPIO), triggered by a TIM

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 27, 2016 at 06:44

Dear Sir Clive, 

Yes, the SPI protocol of MAX31855 is simple.  Drive CS low and apply a clock signal at SCK to read the results at SO.  Drive CS low to output the first bit on the SO pin.

May be thinking that idea this code is implemented, take a look please, 

#include ''spi.h''

#include ''gpio.h''

SPI_HandleTypeDef hspi1;

/* SPI1 init function */

void MX_SPI1_Init(void)

{

  hspi1.Instance = SPI1;

  hspi1.Init.Mode = SPI_MODE_MASTER;

  hspi1.Init.Direction = SPI_DIRECTION_2LINES_RXONLY;

  hspi1.Init.DataSize = SPI_DATASIZE_14BIT; // 14bit #####

  hspi1.Init.CLKPolarity = SPI_POLARITY_LOW;

  hspi1.Init.CLKPhase = SPI_PHASE_1EDGE;

  hspi1.Init.NSS = SPI_NSS_HARD_OUTPUT;

  //hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_4;

  hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_32;

  hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB;

  hspi1.Init.TIMode = SPI_TIMODE_DISABLE;

  hspi1.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;

  hspi1.Init.CRCPolynomial = 7;

  hspi1.Init.CRCLength = SPI_CRC_LENGTH_DATASIZE;

  hspi1.Init.NSSPMode = SPI_NSS_PULSE_ENABLE;

  if (HAL_SPI_Init(&hspi1) != HAL_OK)

  {

    Error_Handler();

  }

}

void HAL_SPI_MspInit(SPI_HandleTypeDef* spiHandle)

{

  GPIO_InitTypeDef GPIO_InitStruct;

  if(spiHandle->Instance==SPI1)

  {

  /* USER CODE BEGIN SPI1_MspInit 0 */

  /* USER CODE END SPI1_MspInit 0 */

    /* Peripheral clock enable */

    __HAL_RCC_SPI1_CLK_ENABLE();

  

    /**SPI1 GPIO Configuration    

    PA15     ------> SPI1_NSS

    PB3     ------> SPI1_SCK

    PB4     ------> SPI1_MISO 

    */

    GPIO_InitStruct.Pin = TEMP__CS_Pin;

    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;

    GPIO_InitStruct.Pull = GPIO_NOPULL;

    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;

    GPIO_InitStruct.Alternate = GPIO_AF0_SPI1;

    HAL_GPIO_Init(TEMP__CS_GPIO_Port, &GPIO_InitStruct);

    GPIO_InitStruct.Pin = TEMP_SCK_Pin|TEMP_SO_Pin;

    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;

    GPIO_InitStruct.Pull = GPIO_NOPULL;

    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;

    GPIO_InitStruct.Alternate = GPIO_AF0_SPI1;

    HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);

  /* USER CODE BEGIN SPI1_MspInit 1 */

  /* USER CODE END SPI1_MspInit 1 */

  }

}

void HAL_SPI_MspDeInit(SPI_HandleTypeDef* spiHandle)

{

  if(spiHandle->Instance==SPI1)

  {

  /* USER CODE BEGIN SPI1_MspDeInit 0 */

  /* USER CODE END SPI1_MspDeInit 0 */

    /* Peripheral clock disable */

    __HAL_RCC_SPI1_CLK_DISABLE();

  

    /**SPI1 GPIO Configuration    

    PA15     ------> SPI1_NSS

    PB3     ------> SPI1_SCK

    PB4     ------> SPI1_MISO 

    */

    HAL_GPIO_DeInit(TEMP__CS_GPIO_Port, TEMP__CS_Pin);

    HAL_GPIO_DeInit(GPIOB, TEMP_SCK_Pin|TEMP_SO_Pin);

  }

Should I use this code again?

May be in my code you are talking the variable calling, that was 

uint8_t aTxBuffer[] = ''**** SPI Message ****'';

static uint16_t Buffercmp(uint8_t *pBuffer1, uint8_t *pBuffer2, uint16_t BufferLength);

static uint16_t Buffercmp(uint8_t *pBuffer1, uint8_t *pBuffer2, uint16_t BufferLength);

Could you kindly, show me a code that using circular DMA with TIM trigger?

Md Mubdiul Hasan
Associate III
Posted on November 04, 2016 at 08:40

Dear Sir Clive,

May be you are busy on work.

I saw in stm32f0xx_hal_rtc.c, the RTC_ByteToBcd2(uint8_t Value) function solves the byte to bcd problem. So, if I use RTC, my problem will be no more.

While building my old version of project,  I saw they did not use any RTC facility while using a state machine file for seven-segment. 

Do you think, in my new project I can utilize RTC instead of calling state file?

Posted on November 04, 2016 at 16:33

I'm not working with HAL/CubeMX

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 November 07, 2016 at 05:11

Dear Sir,

Besides, HAL library what you would suggest?

Do you want me to use Keli?

Kindly, give me some lesson about using state files in such situation. I mean, utilizing timely activity of 7segment keeping a predetermined code. 

My previous code was open in Coocox.

 

I need your valuable comment here.

Regards

Hasan