Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

Interfacing ADS8513 ADC with PIC18

jmahatodeep

Newbie level 5
Joined
Jul 21, 2021
Messages
8
Helped
0
Reputation
0
Reaction score
0
Trophy points
1
Activity points
45
I am trying to interface ADS8513 ADC with PIC18 uC. But unable to configure. I'm following the timing diagram to start conversion but on the logic analyzer except for SCLK no other pin is changing.
Here is my code.
ADS8513_pic18.png
ADS8513_pic18_VSM.png
Timing_diagram.png

Code:
sbit Conversion_Select at RC0_bit;
sbit Conversion_Select_Direction at TRISC0_bit;
sbit Chip_Select at RC1_bit;
sbit Chip_Select_Direction at TRISC1_bit;
sbit Busy_Select at RC2_bit;
sbit Busy_Select_Direction at TRISC2_bit;
// LCD module connections (pinout settings)
sbit LCD_RS at RD2_bit;
sbit LCD_EN at RD3_bit;
sbit LCD_D4 at RD4_bit;
sbit LCD_D5 at RD5_bit;
sbit LCD_D6 at RD6_bit;
sbit LCD_D7 at RD7_bit;

// LCD pin direction
sbit LCD_RS_Direction at TRISD2_bit;
sbit LCD_EN_Direction at TRISD3_bit;
sbit LCD_D4_Direction at TRISD4_bit;
sbit LCD_D5_Direction at TRISD5_bit;
sbit LCD_D6_Direction at TRISD6_bit;
sbit LCD_D7_Direction at TRISD7_bit;

unsigned short msb,lsb;
double ADCvalue;
double temp;
char txt[16];
void Init_Main()
{
    Chip_Select=1;                   // CS pin is high at ADC
    Chip_Select_Direction=0;         // RC1 pin's direction is set as output
    Conversion_Select=1;                   // CONV pin is high at ADC
    Conversion_Select_Direction=0;         // RC0 pin's direction is set as output
    //Busy_Select=1;                   // BUSY pin is high at ADC
    Busy_Select_Direction=1;         // RC2 pin's direction is set as input
} 
unsigned char SPI_Read1()
{
    SSPBUF=0xff;                /* Copy flush data in SSBUF */
    while(!PIR1.SSPIF);        /* Wait for complete 1 byte transmission */
    PIR1.SSPIF=0;                /* Clear SSPIF flag */
    return(SSPBUF);                /* Return received data.*/
}
float ADC_Output()
{
    SPI1_Init();
    SPI1_Write(0x20);
    Chip_Select=1;
    Conversion_Select=1;             // Conversion pin is high at ADC
    Conversion_Select=0;
    Conversion_Select=1;
    //SPI1_Init_Advanced(_SPI_MASTER_OSC_DIV16, _SPI_DATA_SAMPLE_MIDDLE, _SPI_CLK_IDLE_LOW, _SPI_LOW_2_HIGH);
    SPI1_Write(0x61);
    msb=SPI_Read1(); //sending out zero as a dummy byte, to receive the answer (the register value) from chip
    lsb=SPI_Read1(); //sending out zero as a dummy byte, to receive the answer (the register value) from chip
    Chip_Select=1;
    ADCvalue = (msb <<8) + (lsb& 0x00FF) ;
    return (ADCvalue);
}
void main() {
    ANSEL = ANSELH = 0; // All I/O pins are configured as digital
    //PORTC=0;
    Init_Main();
    Lcd_Init();
    Lcd_Cmd(_LCD_CLEAR);                     // Clear display
    Lcd_Cmd(_LCD_CURSOR_OFF);                // Cursor off
    Lcd_Out(1,5,"ADC test");
    while(1)
    {
    temp=ADC_Output();
    temp= ((ADCvalue*5)/65536);
    //temp  = ceil(temp * 100) / 100;         
    //IntToStr(ADCvalue,txt);
    FloatToStr(temp,txt);
    //temp=ADCvalue+0x30;
  
    Lcd_Out(2,1,txt);
  
    }
}
 
Last edited by a moderator:

KlausST

Super Moderator
Staff member
Joined
Apr 17, 2014
Messages
20,352
Helped
4,441
Reputation
8,891
Reaction score
4,468
Trophy points
1,393
Activity points
134,557
Hi,

Mind to use CODE tags next time.

you never drive CHIP_SELECT = 0, thus the ADC never is active on the bus.

Klaus
 

danadakk

Advanced Member level 4
Joined
Mar 26, 2018
Messages
1,207
Helped
223
Reputation
458
Reaction score
258
Trophy points
83
Activity points
5,575
For future work you can get processors these days with up to 20 bit DelSig on them.
I want to say I saw one with 24 bits but cannot remember who made it.

Regards, Dana.

PS : 24 bits Analog Devices.
 

Aussie Susan

Advanced Member level 4
Joined
Jan 5, 2015
Messages
1,314
Helped
386
Reputation
772
Reaction score
392
Trophy points
83
Activity points
14,182
While it may not apply at the moment, I can't see where you set the LCD pins to output (TRISbits.XXX = 0 or whatever your compiler syntax is). The default is input.
Susan
 

jmahatodeep

Newbie level 5
Joined
Jul 21, 2021
Messages
8
Helped
0
Reputation
0
Reaction score
0
Trophy points
1
Activity points
45
Hi,

Mind to use CODE tags next time.

you never drive CHIP_SELECT = 0, thus the ADC never is active on the bus.

Klaus
I have driven the Chip_Select=0, still its not working.
from the datasheet, I have doubts regarding these lines. there is no SDI pin in ADS8513. then how can control byte can be sent
 

Attachments

  • datasheet_issue_ADS8513.png
    datasheet_issue_ADS8513.png
    88.5 KB · Views: 32

Aussie Susan

Advanced Member level 4
Joined
Jan 5, 2015
Messages
1,314
Helped
386
Reputation
772
Reaction score
392
Trophy points
83
Activity points
14,182
What 'control byte'? The timing diagram in your first post shows that the conversion is triggered by the \CONV\ line going low. That sets the \BUSY\ pin low until teh data is ready. You then start ther SPI exchange which triggers the SCK signal that will make the ADS8315 starts to shift out the value to the DATA pin (conneted to the MCUs SDI pin).
One 'guess' is that you are not leaving thre \CONV\ signal low for long enough. The data sheet says that it must be low for between 0.04 and 12uS. Personally I would go for the longer end of that range to be on the safe side. Have you read the paragraphs at the stop of Page 13 of the datasheet about kee ing the \CONV\ signal low for the entire conversion?
Susan
 

jmahatodeep

Newbie level 5
Joined
Jul 21, 2021
Messages
8
Helped
0
Reputation
0
Reaction score
0
Trophy points
1
Activity points
45
What 'control byte'? The timing diagram in your first post shows that the conversion is triggered by the \CONV\ line going low. That sets the \BUSY\ pin low until teh data is ready. You then start ther SPI exchange which triggers the SCK signal that will make the ADS8315 starts to shift out the value to the DATA pin (conneted to the MCUs SDI pin).
One 'guess' is that you are not leaving thre \CONV\ signal low for long enough. The data sheet says that it must be low for between 0.04 and 12uS. Personally I would go for the longer end of that range to be on the safe side. Have you read the paragraphs at the stop of Page 13 of the datasheet about kee ing the \CONV\ signal low for the entire conversion?
Susan
I have tried with that option too, keeping the \CONV\ bit low till \BUSY\ gets high. But still, in the logical analyzer, it keeps showing that the \CONV\ and \BUSY\ remain low while \CS\ is always high.
here is the dited code:
Code:
float ADC_Output()
{
    SPI1_Init_Advanced(_SPI_MASTER_OSC_DIV4, _SPI_DATA_SAMPLE_MIDDLE, _SPI_CLK_IDLE_LOW, _SPI_LOW_2_HIGH);
    Chip_Select=1;                    //Chip_Select is high
    Conversion_Select=1;             // Conversion pin is high at ADC
    Delay_us(1);
    Conversion_Select=0;             // Conversion pin is low at ADC
    Delay_us(19);
    Chip_Select=0;                   // Chip_Select goes low
    SPI1_Init_Advanced(_SPI_MASTER_OSC_DIV16, _SPI_DATA_SAMPLE_MIDDLE, _SPI_CLK_IDLE_LOW, _SPI_LOW_2_HIGH);
    Chip_Select=0;                   // Chip_Select remains low
    msb=SPI_Read1(); //sending out zero as a dummy byte, to receive the answer (the register value) from chip
    lsb=SPI_Read1(); //sending out zero as a dummy byte, to receive the answer (the register value) from chip
    Chip_Select=1;
    Conversion_Select=1;             // Conversion pin is high
    ADCvalue = (msb <<8) + (lsb& 0x00FF) ;
    return (ADCvalue);
}

please check
 
Last edited by a moderator:

Aussie Susan

Advanced Member level 4
Joined
Jan 5, 2015
Messages
1,314
Helped
386
Reputation
772
Reaction score
392
Trophy points
83
Activity points
14,182
Don't use floating point in these small(er) family MCUs - they don;t have the hardware and everything is done in the library software which is slow and takes up the limited space. Scaled integers are the way to do if you need fractional values from the (already integer) ADC value.
You start the conversion but why do you rely on the delay when you already have a line to the \BUSY\ signal - just ewait until that goers high again. However for that signal to be non-tristated, you will need \CS\ to be low (there is no harm in pulling that low at the start anyway).
Why are you initialising SPI1 twice - but with different clocks. The SPI is not used for the conversion but (as we can't see what the initialisation function does) it *might* cause some glitches that might interfere with the ADC. Initialise the SPI module as part of the startup of the app and then leave it alone after that.
You also duplicate the 'Chip_Select=0;' line which makes me thing that you are simply copying code from all over th eplace without erwally understnading what it is doing.
Be careful with making assumptions about implicit type conversions with embedded systems. You have 'msb' as unsigned short (8-bit). Expressions such as 'msb<<8' could well be performed in 8-bit arithmetic (which is the native size of these MCUs) - if you want the use 16-bit arithmetic then use explicit type casts. This is the source an MANY errors by beginners.
Susan
 

jmahatodeep

Newbie level 5
Joined
Jul 21, 2021
Messages
8
Helped
0
Reputation
0
Reaction score
0
Trophy points
1
Activity points
45
Don't use floating point in these small(er) family MCUs - they don;t have the hardware and everything is done in the library software which is slow and takes up the limited space. Scaled integers are the way to do if you need fractional values from the (already integer) ADC value.
You start the conversion but why do you rely on the delay when you already have a line to the \BUSY\ signal - just ewait until that goers high again. However for that signal to be non-tristated, you will need \CS\ to be low (there is no harm in pulling that low at the start anyway).
Why are you initialising SPI1 twice - but with different clocks. The SPI is not used for the conversion but (as we can't see what the initialisation function does) it *might* cause some glitches that might interfere with the ADC. Initialise the SPI module as part of the startup of the app and then leave it alone after that.
You also duplicate the 'Chip_Select=0;' line which makes me thing that you are simply copying code from all over th eplace without erwally understnading what it is doing.
Be careful with making assumptions about implicit type conversions with embedded systems. You have 'msb' as unsigned short (8-bit). Expressions such as 'msb<<8' could well be performed in 8-bit arithmetic (which is the native size of these MCUs) - if you want the use 16-bit arithmetic then use explicit type casts. This is the source an MANY errors by beginners.
Susan
If you can see the attached file, there it's been said that for 8bit transfer the control byte should be 20h and for 16bit transfer control byte should be 61h..I thought this is somehow related to sspcon1 reg..that's why I've initialise two times..
And from the attached file also you can see for 8bit transfer \CS\ goes low and for 16bit transfer again \CS\ is low..that's why I used Chip_Select=0 twice.
 

Aussie Susan

Advanced Member level 4
Joined
Jan 5, 2015
Messages
1,314
Helped
386
Reputation
772
Reaction score
392
Trophy points
83
Activity points
14,182
For a start, you are NOT dealing with a QSPI interface - there is only 1 data line and so this is a standard SPI interface.
What they are describing is a way to have the MCU automatically generate the \CONV\ pulse using a second pin of the QSPI interface. The PIC18F45K20 you are using does not have a QSPI module, the MSSP is a simply SPI module only with 1 SDO and 1 SDI line.
Also remember that you have the 'EXT\INT\' pin held high so that the only clock pulses (and therefore the only data exchanges) are those generated by the MCU. Your MCU will only generate SCK pulses when it is in 'master' mode (which you have set yours) and when you place a value into the SSPBUF register.
Therefore just intiialise the MSSP module once and leave it alone after that.
You need to control the \CONV\ line to initialse a conversion which you are doing by taking it from '1' to '0'. AS long as you have the \CS\ line low (which enables the \BUSY\ line output, and the DATA line), you can then monitor the \BUSY\ line until it goes '0' to '1' to show that the conversion is complete.
You then perform 2 8-bit exchanges via the SPI module (very much as you do) and then raise the \CS\ line.
The pseudo code will be someing like:
Code:
#Initialise the MSSP module to master mode ands whatever speed you like
CONV line = 1
CS line = 1

#loop
CS line = 0
CONV line = 0
while( BUSY==0);
topByte = SPI_read()
bottomByte = SPI_read()
CONV line = 1
CS line = 1
final value = ((uint16_t)topByte << 8) + bottomByte
#done
Susan
 

FvM

Super Moderator
Staff member
Joined
Jan 22, 2008
Messages
48,749
Helped
14,307
Reputation
28,877
Reaction score
13,035
Trophy points
1,393
Location
Bochum, Germany
Activity points
281,548
ADS8513 uses an SPI-like synchronous serial interface, but it's not strictly SPI. nCS has no synchronizing function, it's just an output enable for DATA and nBUSY and a gate signal for DATACLK. Respectively you can pull it permanently low in a single ADC setup, one signal less that may me operated inappropriately.
 

LaTeX Commands Quick-Menu:

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Top