2

I am using SPI communication with between a Model B+ and an external ADC of 10 bit resolution, the MCP3008. I have wired it with accordance to the data sheet. I am also using the bcm2835 library and using Geany as an IDE. Referring to this image, There should be a '1' sent, then '0x80' which would correspond to a single ended input on channel 0 according to the previous image along with this. The return byte has the two most significant bits at the end. Then a dummy byte is sent with the rest of the output on the return byte. My code is as follows:

#include <stdio.h>
#include <bcm2835.h>
int main(int argc, char **argv)
{

  if (!bcm2835_init()){
    return 1;
  }
  bcm2835_spi_begin();
  bcm2835_spi_setBitOrder(BCM2835_SPI_BIT_ORDER_MSBFIRST);      
  bcm2835_spi_setDataMode(BCM2835_SPI_MODE0); //Data comes in on falling edge                
  bcm2835_spi_setClockDivider(BCM2835_SPI_CLOCK_DIVIDER_256); //250MHz / 256 = 976.5kHz 
  bcm2835_spi_chipSelect(BCM2835_SPI_CS0); //Slave Select on CS0                    
  bcm2835_spi_setChipSelectPolarity(BCM2835_SPI_CS0, LOW);   

  uint8_t send_data = 0x01;
  uint8_t dumData = bcm2835_spi_transfer(send_data);

  send_data = 0x80;
  uint8_t msb = bcm2835_spi_transfer(send_data);
  int msbRead = msb & 0b00000011

  send_data = 0;    
  uint8_t lsb = bcm2835_spi_transfer(send_data);

  int adcRead = (msbRead << 8) | lsb;

  printf("%d\n", adcRead);
  printf("%d\n", msb);
  printf("%d\n", msbRead);
  printf("%d\n", lsb);
  printf("%d\n", dumbData);

  bcm2835_spi_end();
  bcm2835_close();
  return 0;

}

When putting Channel 0 at VCC, the output is:

511 for adcRead

129 for msb (includes dummy bits)

1 for msbRead (the corrected value after ignoring dummy bits)

255 for lsb

1 for dumbData (If its diagnostically relevant)

The data isn't correct, and even when put at other voltages, the reading isn't correct, only when at GND will it read 0.

1 Answer 1

2

You need to transfer all three bytes in one SPI transaction, i.e. assert slave select, transfer 3 bytes, deassert slave select.

The above code is doing three separate transactions which will be ignored by the ADC.

Instead of the three bcm2835_spi_transfer calls change the code to make a single call to bcm2835_spi_transfernb.

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.