KP64F MCP3001 SPI interfacing

Read procedure

To read MCP3001 ADC value (10 bits) first set CS to 0 and wait at least 100ns for ADC to measure VIN+/VIN-. After this read 3x 8 bits (3 bytes) by SPI. While reading from SPI, CS must be set to 0 all the time. After you finished reading you have to set CS to 1. You get 24 bits which are composed as following:

  byte1    byte2    byte3
00000000 00000000 00000000
sszmmmmm mmmmmlll llllllss

s ... sample bit (not used)
z ... zero bit (always zero)
m ... most significant first bits (our adc value)
l ... least significant first bits (our upside down adc value)

So for our correct ADC value we only need the first and second byte (the third byte only contains least significant first bits and sample bits)

Byte 1

Bit 7, bit 6 and bit 5 in byte 1 are always 0. Our value starts at bit 4.

Byte 2

Bit 3 to Bit 0 are least significant bits of ADC value (we do not need). From byte 2 we need bit 7 to bit 4.

Value composition

So our ADC value is composed by:

adc_value = (byte1<<5) | (byte2>>3);

SPI format

Format is 8 bits and clocking is CPOL=0, CPHA=0 (0, 0; 0). Maximum SPI clock is 2.8 MHz (datasheet).

Datasheet

http://ww1.microchip.com/downloads/en/DeviceDoc/21293C.pdf

Test code

#include "mbed.h"

Serial pc(USBTX, USBRX);
SPI spi(PTD2, PTD3, PTD1);
DigitalOut cs(PTC5);

int main() {
    int ret1=-1, ret2=-1, ret3=-1;
    int i = 0;

    pc.baud(115200);

    cs = 1;
    spi.format(8, 0);
    spi.frequency(1500000UL);

    printf("### program start ###\r\n");

    while (true) {
        cs = 0;
        //wait(0.5f);
    
        ret1 = spi.write(0xFF);
        ret2 = spi.write(0xFF);
        ret3 = spi.write(0xFF);
        //wait(0.5f);
        cs = 1;

        printf("ret=%d\r\n", (ret1 << 5) | (ret2 >> 3));//, ret2);
        wait(0.1f);
    }
}


Please log in to post comments.