SPI reading external ADC

Go To Last Post
10 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi,all,

I just wrote a code for data reading of external ADC.
However,I'm not sure if my hardware configuration is okay.
To read data from external ADC, I defined the microcontroller to be master device, and connected MISO pin to ADC output,SCK pin to ADC clock, however MOSI is not connected because ADC doesn't have a register I don't where to connect MOSI pin. Is it okay to leave MOSI unconnected?

By the way, the codes I wrote is:


#include #include

void SPI_masterinit(void);
unsigned int SPI_transmit(void);

void main(void){
SPI_masterinit();
unsigned int SPI_transmit();
return 0;

}

void SPI_masterinit(void){
/*Set MOSI,SS and SCK to be output, MISO to be input, and all others are output*/
DDRB= 0xbf; // DDRB=0b10111111
/*Enable SPI,Master*/
SPCR=(1< /*Set clcok rate fck/2*/
SPSR=(1< }

unsigned int SPI_transmit(void){
unsigned ADC_data=0,sum_data=0,final_data;

/*Start transmission*/
SPDR=0x00; //0x00 will be shifted out from MOSI pin, the data will be shifted
// into SPDR register
/*wait for complete*/
while (!(SPSR&(1< ADC_data=SPDR; // save the high 8- bit data
ADC_data<<=8; // left shit the data

/*Continue transmission*/
SPDR=0x00; // transmit low 6-bit data

while (!(SPSR&(1<>=2; // right shift the data

return ADC_data; // return 14-bit data
}

Becaus the ADC is 14-bit, I read the data twice and shifted them.
At the begining of the transmission,I assigned 0x00 to SPDR, after that, this data will be shifted out and the ADC data will be shifted into SPDR. So we can take use of the data in SPDR then. In the end, the final data is returned. Is it okay? Since MOSI is not connected to anywhere.

PS: I have attached a simple plot of the hardware configuration, please have a look at it. Thank you for your help.

Attachment(s): 

Last Edited: Thu. Nov 25, 2021 - 10:52 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

It would be nice to know what ADC chip you're using. I have used the ADS1286, which has no connection for data in. It has just the data clock, chip select, and data out.

I didn't use the AVR SPI interface. Instead, I used three general-purpose I/O pins and manipulated the with my code to follow the timing diagram in the ADC data sheet. It worked perfectly. You might call this a "bit banging" solution, but I think it is easier than using SPI, as long as you're not trying to read in the data very fast and also doing maximum amount of processing with the microcontroller.

Why choose? Be there *and* be square!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

sagenepal wrote:
It would be nice to know what ADC chip you're using. I have used the ADS1286, which has no connection for data in. It has just the data clock, chip select, and data out. I didn't use the AVR SPI interface. Instead, I used three general-purpose I/O pins and manipulated the with my code to follow the timing diagram in the ADC data sheet. It worked perfectly. You might call this a "bit banging" solution, but I think it is easier than using SPI, as long as you're not trying to read in the data very fast and also doing maximum amount of processing with the microcontroller.

 

Hi,

How did you implement the "bit banging"? I got it that you used three I/O pins, but how did you define the clock for the I/O pin? Thanks.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

 

How did you implement the "bit banging"? I got it that you used three I/O pins, but how did you define the clock for the I/O pin? Thanks.

By using normal methods.  Why are you asking on an 11 year old thread---that guy has not been around since 2009?  Just go look up bit banging, there are plenty of examples.

When in the dark remember-the future looks brighter than ever.   I look forward to being able to predict the future!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

mgdosreis wrote:
How did you implement the "bit banging"? 

"bit banging" just means that your code directly sets pins high, and low, and does the timing between them

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

sagenepal wrote:
You might call this a "bit banging" solution, but I think it is easier than using SPI 

I think you mean, "easier than using the microcontroller's hardware SPI unit"?

 

It's all SPI - whether you implement it by so-called "bit-banging", or use the microcontroller's hardware peripherals.

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi all, 

I have been reading a lot about bit banging, but I am still lacking confidence on the implemantation. I am using the SAMV71 with the serial ADC LTC2344-16. The SAMV71 from Microchip includes a 3-bit pause between byte transfers, but this ADC needs 96 clock cycles without pause for me to get all the information from its buffer.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

mgdosreis wrote:
SAMV71

That's not an AVR - the SAM forums (ARM Cortex-M) are here: https://community.atmel.com/atmel-smart-arm-based-mcus

 

But, again, bit-banging is just about setting pins high & low, and timing - so start by just blinking an LED ...

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0


If you look at a typical SPI sequence:

 

 

The it's just 3 wires (well four if you include the chip select) that are switching between 0 and 1 over time. In the case of a master (and ignoring CS for now) it's basically just two pins/wires that you control. Regularly you have a "clock" line switching between o and 1 while a transfer is occurring then, synchronised to that, you have a data out line (MOSI) that switches o/1 depending on the 8 bits of data to be transferred against the clock pulses. In effect it is something like:

void SPI_send(uint8_t data) {
    for(int i = 0; i < 8; i++) {
        clock_hi();
        if (data & 1) {
            data_hi();
        }
        else {
            data_low();
        }
        clock_low();
        data >>= 1;
    }
}

clock_hi()/clock_low()/data_hi()/data_low() are simply placeholders for the code to make some chosen IO line go to 1 or 0. One acting as clock and one for the outbound data.

 

You may need to slow things down a bit so perhaps:

void SPI_send(uint8_t data) {
    for(int i = 0; i < 8; i++) {
        clock_hi();
        short_delay();

        if (data & 1) {
            data_hi();
        }
        else {
            data_low();
        }
        short_delay();

        clock_low();
        short_delay();
        data >>= 1;
    }
}

Then you may want to read back the data line coming in at the same time (this is, after all, how SPI exchanges work!) so this could be "fleshed out" further to be something like:

uint8_t SPI_send(uint8_t data) {
    uint8_t rxd;
    
    for(int i = 0; i < 8; i++) {
        clock_hi();
        short_delay();

        if (data & 1) {
            data_hi();
        }
        else {
            data_low();
        }
        short_delay();

        if (check_input()) {
            rxd |= 1;
        }
        rxd <<= 1;

        clock_low();
        short_delay();
        data >>= 1;
    }
    return rxd;
}

And that is basically "bit banging".

 

Of course there are considerations like for bits 76543210 so you want to send out in 0, 1, 2, 3,.. order or in 7, 6, 5, 4... order. Same for the inbound - do you receive 7 first or 0 first. So the way you test and shift out the data or receive and build up the incoming data which way do you shift things ? (are you operating on bit 7 (0x80) or bit 0 (0x01 or just 1) ?)

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

mgdosreis wrote:
The SAMV71 from Microchip includes a 3-bit pause between byte transfers

Is that a hardware limitation, or to do with the way your software is driving it?

 

What if you do it via DMA ?

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...