MCP3901 (ADC) using SPI: configuration and reading

General discussion on mikroC PRO for dsPIC30/33 and PIC24.
Post Reply
Author
Message
1101
Posts: 19
Joined: 11 Mar 2010 14:56

MCP3901 (ADC) using SPI: configuration and reading

#1 Post by 1101 » 02 Dec 2010 17:34

Good day

I'm a bit stuck with this device and SPI in general. I've never used SPI before, though I've read as much literature as I can find.

I'm paring the MCP3901 (ADC) with a dsPIC33FJ256MC710 by using the 2nd SPI module on the chip. In addition, I'm using channel 0 on the MCP3901. I'm trying to do this with the built in SPI library routines (also, I'm not using interrupts).

Ok, so the first byte sent to the ADC is the control byte, laid out as follows:
First 2 bits - Device address bits
Next 5 bits - Internal register address bits
Last bit - Read/Write bit.

So for instance a control byte looking like 0b00010010 would be a control byte stating that the device address is 00, 01001 would be the stat/comm address, and 0 would indicate that the next byte sent would be written to that register (the stat/comm register that is). Thats my understanding of it, so far.

Thereafter, the next bytes written to the ADC would be to the registers as they appear in sequence (every time after you write to the device, the address shifts to that of the next register so that the next write is to the following register).

So, first of all, will the ADC be the slave or the master of this pairing?

I've now configured it as follows (only applicable part of code):

//Set inputs to digital IO
AD1PCFGH = 0xFFFF;
AD1PCFGL = 0xFFFF;
AD2PCFGL = 0xFFFF;

//------------------------ADC CONFIGURATION------------------------
SPI2_Init_Advanced(_SPI_MASTER, _SPI_8_BIT, _SPI_PRESCALE_SEC_4,_SPI_PRESCALE_PRI_1, _SPI_SS_DISABLE, _SPI_DATA_SAMPLE_END, _SPI_CLK_IDLE_LOW,_SPI_ACTIVE_2_IDLE);

ADC_CS = 0; //Define in code not shown
//note: these written bytes are defines not shown here
SPI2_Write(INIT_CTR_BYTE); //Control byte - start at phase address, writing
SPI2_Write(PHASE_BYTE); //PHASE No phase delay - only one channel
SPI2_Write(GAIN_BYTE); //GAIN, BOOST = 0
SPI2_Write(STAT_COMM); //Read GROUP, wait for settled data, DR high Z when data not ready
SPI2_Write(CONFIG1); //Pre 8, OSR 356, width 16, mod off,
SPI2_Write(CONFIG2); //RST 0, ch1 off, dith 0 on, ext Vref on, ext clk on
ADC_CS = 1; //Deselct ADC, to start with new control byte

//Channel read setup
ADC_CS = 0;
SPI2_Write(READSET_CTR_BYTE); //Set ADC register address to the stat/com register, writing
SPI2_Write(STAT_COMM_READ); //Set address loop to only loop on DATCH0 group
ADC_CS = 1;

//Start reading from ADC channel 0 after intial control byte
ADC_CS = 0;
SPI2_Write(READ_CTR_BYTE); //Start reading from channel 1

//------------------------ADC READ------------------------
for (count = 0; count <= 9; count++) {
data_out[count] = SPI2_Read(buffer);
}

ADC_cs = 1;

I'm still reading 0 though in the data_out array. I'm obviously doing something very wrong here... :? Any ideas?

Sobrietytest
Posts: 619
Joined: 05 Jul 2008 06:05
Location: Thailand

Re: MCP3901 (ADC) using SPI: configuration and reading

#2 Post by Sobrietytest » 04 Dec 2010 10:42

Firstly, I can't find any datasheet for 'MPC3901', are you sure you have given us the correct device name? Maybe you could link to it in you next post.

Anyway, without the datasheet it's a bit difficult to understand all those configuration bytes and whether you have initialised the SPI correctly. My main concern is that the ADC supports SPI framing, in this case you would have to switch the ADC_CS for every byte as opposed to each set of bytes. If you were to use the CS pin from the SPI module this would be done automatically and there would be no need to define your own CS.

Sobrietytest
Posts: 619
Joined: 05 Jul 2008 06:05
Location: Thailand

Re: MCP3901 (ADC) using SPI: configuration and reading

#3 Post by Sobrietytest » 04 Dec 2010 10:51

Okay, I've found the datasheet, that was my lysdexia having a good day!

Sobrietytest
Posts: 619
Joined: 05 Jul 2008 06:05
Location: Thailand

Re: MCP3901 (ADC) using SPI: configuration and reading

#4 Post by Sobrietytest » 04 Dec 2010 11:39

It's a bit clearer now I've read the datasheet! Please ignore my earlier comment about framing, this device clearly doesn't use it. Refering back to your code it seems that you have done everything in the right sequence, however, without seeing the actual data bytes you are sending to each register, I can't be sure if you have done it correctly. I'm sure it's just a typo but look at these three lines...

SPI2_Write(CONFIG2); //RST 0, ch1 off, dith 0 on, ext Vref on, ext clk on
...
SPI2_Write(STAT_COMM_READ); //Set address loop to only loop on DATCH0 group
...
SPI2_Write(READ_CTR_BYTE); //Start reading from channel 1


As you can see, you have disabled channel 1 and then your comment indicates that you are trying to read from channel 1. Maybe you need to check this.

1101
Posts: 19
Joined: 11 Mar 2010 14:56

Re: MCP3901 (ADC) using SPI: configuration and reading

#5 Post by 1101 » 06 Dec 2010 22:30

Many thanks for the replies. I did indeed set the wrong channel as well as a few other minor mistakes. Silly silly silly.... :roll:

emcconnell
Posts: 1
Joined: 06 Mar 2013 17:19

Re: MCP3901 (ADC) using SPI: configuration and reading

#6 Post by emcconnell » 06 Mar 2013 17:28

Hi,
I am having difficulty reading from the MCP3901,
can you please send a copy of the code

Christos1024
Posts: 1
Joined: 18 Jul 2013 10:29

Re: MCP3901 (ADC) using SPI: configuration and reading

#7 Post by Christos1024 » 18 Jul 2013 10:35

Hi! Sorry for a delayed post.

I'm currently doing a project using MCP3903 for three phase metering.

Would you please be kind enough to send me your source code for your project because currently the datasheet is confusing me and I'm an amateur when it comes to C programming.

Thanks in advance

lpmsr
Posts: 117
Joined: 17 Jul 2009 02:10

Re: MCP3901 (ADC) using SPI: configuration and reading

#8 Post by lpmsr » 05 Aug 2013 06:32

I would also be interested in your code if you don't mind.

Thanks...

Post Reply

Return to “mikroC PRO for dsPIC30/33 and PIC24 General”