Technical Support

C51: OPTIMUM CODE FOR BIT TO BYTE CONVERSION


Information in this article applies to:

  • C51 All Versions
  • CX51 All Versions
  • C251 All Versions

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

Last Reviewed: Friday, July 15, 2005


Did this article provide the answer you needed?
 
Yes
No
Not Sure