ARM Technical Support Knowledge Articles

OPTIMUM CODE FOR BIT TO BYTE CONVERSION

Applies to: C51 C Compiler

Answer


Information in this article applies to:


QUESTION

I have a very time-critical routine that accesses an SPI Bus. It needs to shift in 8 bits from one single pin to a register. Normally this would be done in a loop, but I must optimize it to consume minimum time.

The construction below works OK, but still does not give me the performance that I would like to have. Is there a better way to code this?

  unsigned char Read_SPI_Byte (void)  {
  unsigned char result;

  result = 0;
  SCLK = 0;
  if (MISO) result |= 0x80;
  SCLK = 1;
  SCLK = 0;
  if (MISO) result |= 0x40;
  SCLK = 1;
  SCLK = 0;
  if (MISO) result |= 0x20;
  SCLK = 1;
  SCLK = 0;
  if (MISO) result |= 0x10;
  SCLK = 1;
  SCLK = 0;
  if (MISO) result |= 0x08;
  SCLK = 1;
  SCLK = 0;
  if (MISO) result |= 0x04;
  SCLK = 1;
  SCLK = 0;
  if (MISO) result |= 0x02;
  SCLK = 1;
  SCLK = 0;
  if (MISO) result |= 0x01;
  SCLK = 1;
  return (result);
}

ANSWER

Yes. You may use bdata variables (or in this case even misuse the SFR register B to reduce the data overhead. The following code will give you the optimum performance:

sfr B=0xF0;     // usually this is included in the CPU register header file
sbit B0=B^0;    // define indivitual bits in the B register
sbit B1=B^1;
sbit B2=B^2;
sbit B3=B^3;
sbit B4=B^4;
sbit B5=B^5;
sbit B6=B^6;
sbit B7=B^7;

unsigned char Read_SPI_Byte (void)  {
  SCLK = 0;
  B7 = MISO;    // NOTE: SFR B can be used, since the code does not
  SCLK = 1;     //       affect other statements. However, you
  SCLK = 0;     //       should carefully check the assembler code
  B6 = MISO;    //       listing when you are using this CPU register.
  SCLK = 1;     //       Typically the B register is used for multiplication,
  SCLK = 0;     //       division, pointer access, and math routines.
  B5 = MISO;
  SCLK = 1;
  SCLK = 0;
  B4 = MISO;
  SCLK = 1;
  SCLK = 0;
  B3 = MISO;
  SCLK = 1;
  SCLK = 0;
  B2 = MISO;
  SCLK = 1;
  SCLK = 0;
  B1 = MISO;
  SCLK = 1;
  SCLK = 0;
  B0 = MISO;
  SCLK = 1;
  return (B);
}

MORE INFORMATION

SEE ALSO

Article last edited on: 2005-07-15 09:53:19

Rate this article

[Bad]
|
|
[Good]
Disagree? Move your mouse over the bar and click

Did you find this article helpful? Yes No

How can we improve this article?

Link to this article
Copyright © 2011 ARM Limited. All rights reserved. External (Open), Non-Confidential