ATtiny202 read I2C 16 bits from MAX6675

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

I ordered MAX6675 Module + K Type Thermocouple Temperature Sensor and I am waiting for its delivery. In the meantime I am working on the I2C ATtiny202 program to read the temperature.

 

Please can you have a look if it should work? Note the program should activate CS and read 16 bits data (no address, or ACK/NACK) according to MAX 6675 Serial Interface Protocol

 

#include <atmel_start.h>

#define TWI0_BAUD(F_SCL, T_RISE) ((((((float)3333333 / (float)F_SCL)) - 10 - ((float)3333333 * T_RISE / 1000000))) / 2)

#define wait_for_completion while(!(TWI0.MSTATUS & (1 << TWI_RIF_bp)));

uint16_t temperature = 0;

int main(void) {
    /* Initializes MCU, drivers and middleware */
    atmel_start_init();

    TWI0.MBAUD = (uint8_t) TWI0_BAUD(100000, 0); /* set MBAUD register */

//    TWI0.MCTRLA = 1 << TWI_ENABLE_bp /* Enable TWI Master: enabled */
//            | 0 << TWI_QCEN_bp /* Quick Command Enable: disabled */
//            | 0 << TWI_RIEN_bp /* Read Interrupt Enable: enabled */
//            | 0 << TWI_SMEN_bp /* Smart Mode Enable: disabled */
//            | TWI_TIMEOUT_DISABLED_gc /* Bus Timeout Disabled */
//            | 0 << TWI_WIEN_bp; /* Write Interrupt Enable: disabled */

    while (1) {
        TWI0.MCTRLA = 0b1000001; // RIEN a ENABLE
        wait_for_completion;
        temperature = (TWI0.MDATA << 8);

        TWI0.MCTRLA = 0b1000001; // RIEN a ENABLE
        wait_for_completion;
        temperature += TWI0.MDATA;

        asm ("nop");
    }
}

 

Last Edited: Thu. Jan 21, 2021 - 08:35 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1

Using SPI 3 wire communication

 

Not I2C (TWI), use the spi peripheral rather then the TWI! 

 

Jim

 

 

(Possum Lodge oath) Quando omni flunkus, moritati.

"I thought growing old would take longer"

 

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

I was inspired by this article "AVR basics: using the I2C bus #4 – receiving data".

To the beggining of my program I added pin settings:
 

    PORTA.DIR |= PIN1_bm;   // SDA Out
    PORTA.DIR |= PIN2_bm;   // SCL Out
    PORTA.OUT &= ~PIN1_bm;  // SDA Lo
    PORTA.OUT &= ~PIN2_bm;  // SCL Lo

 

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


 

Kevil wrote:
I am working on the I2C ATtiny202

Why? It's not an I2C chip:

 

 

EDIT 

 

 

 

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...
Last Edited: Fri. Jan 22, 2021 - 09:13 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I know but it is not a typical SPI communication, no device address, no register address and no ACK/NACK use. To get the data, I just need to set data line to Low, recieve 16 bits driven by clock signal and raise the data line back to Hi.

 

On the other end I don't have a problem to use SPI communication, but how to set it up?

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


 

Kevil wrote:
I know but it is not a typical SPI communication, no device address, no register address and no ACK/NACK use.

You seem to be confusing SPI with I2C: device address, register address and ACK/NACK are all I2C things - they would not be expected on SPI

 

 

I don't have a problem to use SPI communication, but how to set it up?

Please clarify what you mean here - surely, setting it up is key to using it?

 

If you want to know how to use the SPI on an ATtiny202, check out the resources on its Product Page:

 

 

 

 

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...
Last Edited: Fri. Jan 22, 2021 - 12:50 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

@awneil

Thank you for the link. I didn't know about that.

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

You're welcome.

 

The Product Page should always be your first port of call for any new chip:

 

https://www.avrfreaks.net/commen...

https://www.avrfreaks.net/commen...

 

and not just for Microchip or microcontrollers - as #4 shows.

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

awneil wrote:
You seem to be confusing SPI with I2C:
You do indeed seem to have the two switched!

 

If I simply google "MA6675 AVR" then among the many projects it provides links to I find things like:

 

https://github.com/andrewsmallbo...

 

where it's clearly SPI that is being used.

 

A result a little closer to home:

 

https://www.avrfreaks.net/forum/...

 

Again, the use of SPI is unequivocal.

 

SPI is the one where it is just back to back shift registers. The micro writes to its register, this triggers 8 clocks and at the end its content have moved to the distant device while the value that was waiting there have come back to the micro. The only "addressing" is that if the micro is connected to multiple SPI devices it might have to assert just one active chip select line at a time to say which one it wants to communicate with.

 

I2C/TWI on the other hand is the one with "in band" addressing. There are just clock and data lines but the first thing that happens is that the master puts out a 7 bit address value on the wires to say which device it would like to communicate with and when the link is established (acknowledged) then further bytes travel between master and the active device.

 

Bottom line, you picked the wrong interface. MAX6675 is SPI (which actually makes things a whole lot simpler!)

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

Based on the Microchip TB3215-Getting-Started-with-SPI-90003215A I was able to test sending byte over SPI successfully.

 

// Example 7-1. Sending Data as a Master SPI Device Full Code Example (TB3215)

#define F_CPU 3333333

#include <xc.h>             // F_CPU
#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>  // For sei(), cli()

void SPI0_init(void);
void slaveSelect(void);
void slaveDeselect(void);
void SPI0_WriteData(uint8_t data);

void SPI0_init(void) {
    PORTA.DIR |= PIN1_bm; /* Set MOSI pin direction to output */
    PORTA.DIR &= ~PIN2_bm; /* Set MISO pin direction to input */
    PORTA.DIR |= PIN3_bm; /* Set SCK pin direction to output */
    PORTA.DIR |= PIN7_bm; /* Set SS pin direction to output */
    PORTA.OUT |= PIN7_bm; // Set SS pin value to HIGH

    SPI0.CTRLA = SPI_CLK2X_bm /* Enable double-speed */
            | SPI_DORD_bm /* LSB is transmitted first */
            | SPI_ENABLE_bm /* Enable module */
            | SPI_MASTER_bm /* SPI module in Master mode */
            | SPI_PRESC_DIV64_gc; /* System Clock divided by 64*/

    //    sei();  // Enable global interrupts
    //    SPI0.INTCTRL |= SPI_IE_bm;  // Enable SPI interrupt
}

void SPI0_WriteData(uint8_t data) {
    SPI0.DATA = data;
    while (!(SPI0.INTFLAGS & SPI_IF_bm)) /* waits until data is exchanged*/ {
        ;
    }
}

void slaveSelect(void) {
    PORTA.OUT &= ~PIN7_bm; // Set SS pin value to LOW
}

void slaveDeselect(void) {
    PORTA.OUT |= PIN7_bm; // Set SS pin value to HIGH
}

int main(void) {
    uint8_t data = 0b10011001;

    SPI0_init();

    while (1) {
        slaveSelect();
        asm("nop");
        SPI0_WriteData(data);
        slaveDeselect();
        _delay_ms(1);
    }
}

 

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

Kevil wrote:

        asm("nop");

FYI, avr-libc provides NOP() - so you don't need the "asm()": https://www.nongnu.org/avr-libc/user-manual/group__avr__cpufunc.html 

 

EDIT

 

There should be a leading underscore: _NOP()

 

blush

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...
Last Edited: Sat. Jan 23, 2021 - 11:47 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

@awneil

 

Thank you.  _NOP() works with #include <avr/cpufunc.h>

 

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

Back to my first question. How to read data from the slave (thermocouple value) as master ? That means if I select slave by seting LO on SS, it start to send me 16 bit temperature value. I need to read these 16 bits and then set SS back to HI.

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

For each byte you send via spi, you get a byte back. Change your write spi function to return the byte you got back.

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

Perhaps you need to review the basics of how SPI works?

 

see: https://www.avrfreaks.net/commen...

 

https://www.avrfreaks.net/commen...

 

https://www.avrfreaks.net/commen...

 

 

Kevil wrote:
How to read data from the slave (thermocouple value) as master ? That means if I select slave by seting LO on SS, it start to send me 16 bit temperature value.

Did you study the documents shown in #6 ?

 

EDIT

 

And, of course, you will also need to study the documentation for the Slave - that will show you what it requires from the master, and how it responds to the master.

 

See the Maxim Product Page  - as shown in #4

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...
Last Edited: Sun. Jan 24, 2021 - 09:07 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I won't send any data to the slave, I just need to receive 16 bits.

 

Last Edited: Sun. Jan 24, 2021 - 09:34 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

awneil wrote:
Did you study the documents shown in #6 ?

Yes, but there is not mentioned how to receive data from the slave on master. The master will initialize the transmission of data from the slave by seting SS to LOW. See picture above.

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

Kevil wrote:
The master will initialize the transmission of data

As noted in this thread, and the linked threads, SPI is always full-duplex - as the Master "pushes" out data to the Slave, it simultaneously "pulls" in data from the Slave.

 

This is basic SPI stuff. There's a nifty animation illustrating this in the linked threads.

 

EDIT

 

So, when the Slave doesn't require anything from the Master, MOSI is just ignored. But it's the transmission operation at the Master which causes the clock to be generated.

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...
Last Edited: Sun. Jan 24, 2021 - 09:45 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

awneil wrote:
So, when the Slave doesn't require anything from the Master, MOSI is just ignored. But it's the transmission operation at the Master which causes the clock to be generated.

Does it means I have to write any data to DATA register to start a new transfer, generating the clock on the line without actually using the MOSI wire? Or can I use the following code assuming the receive will start when the slave start to send data on MISO line:
 

#define F_CPU 3333333

#include <stdint.h>
#include <xc.h>             // F_CPU
#include <avr/io.h>
#include <util/delay.h>

void SPI0_init(void);
void SPI0_ReadTemp(void);

uint16_t temperature;

void SPI0_init(void) {
    //    PORTA.DIR |= PIN1_bm; /* Set MOSI pin direction to output */
    PORTA.DIR &= ~PIN2_bm; /* Set MISO pin direction to input */
    PORTA.DIR |= PIN3_bm; /* Set SCK pin direction to output */
    PORTA.DIR |= PIN7_bm; /* Set SS pin direction to output */
    PORTA.OUT |= PIN7_bm; // Set SS pin value to HIGH

    SPI0.CTRLA = SPI_CLK2X_bm /* Enable double-speed */
            | SPI_DORD_bm /* LSB is transmitted first */
            | SPI_ENABLE_bm /* Enable module */
            | SPI_MASTER_bm /* SPI module in Master mode */
            | SPI_PRESC_DIV64_gc; /* System Clock divided by 64*/

    //    ei();  // Enable global interrupts, XC8 function
    //    SPI0.INTCTRL |= SPI_IE_bm;  // Enable SPI interrupt
}

void SPI0_ReadTemp(void) {
    temperature = 0;
    while (!(SPI0.INTFLAGS & SPI_IF_bm)) /* waits until data is exchanged*/ {
        ;
    }
    temperature = (unsigned int) SPI0.DATA << 8; // First Hi byte, cast uint8_t to uint16_t

    while (!(SPI0.INTFLAGS & SPI_IF_bm)) /* waits until data is exchanged*/ {
        ;
    }
    temperature += SPI0.DATA; // Second Lo byte, automatically cast to uint16_t
}

int main(void) {

    SPI0_init();

    while (1) {
        PORTA.OUT &= ~PIN7_bm; // Set SS pin value to LOW
        SPI0_ReadTemp();
        PORTA.OUT |= PIN7_bm; // Set SS pin value to HI
        _delay_ms(500);
    }
}

 

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

Kevil wrote:
Does it means I have to write any data to DATA register to start a new transfer

Yes.

 

Or can I use the following code

No.

 

assuming the receive will start when the slave start to send data on MISO line:

Again, the clock is only generated when the Master is sending.

 

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

OK. I need to use not used MOSI pin of the ATtiny202 for other purpose - for IRQ sensing of incoming pulses. Can I still "send" data (i.e. SPI0.DATA = data;) over SPI to start the clock and receive data from the slave?

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

 

Kartman wrote:
For each byte you send via spi, you get a byte back

awneil wrote:
SPI is always full-duplex - as the Master "pushes" out data to the Slave, it simultaneously "pulls" in data from the Slave.

You can see this in the example code in the TB3215 "Getting Started with SPI" document:

 

uint8_t SPI0_exchangeData(uint8_t data)
{
   SPI0.DATA = data;                    // Starts the data transfer

   while (!(SPI0.INTFLAGS & SPI_IF_bm)) // waits until data is exchanged
   {
      ;                                 // As each Tx bit is shifted out to MOSI,
                                        // one bit is shifted in from MISO
   }

                                        // When all 8 output bits have been transmitted,
                                        // 8 inputs bits have been received

   return SPI0.DATA;                    // return the received byte
}

 

Note how the function is called exchange data - because it is always both a transmit & a receive.

 

EDIT

 

THe animation I mentioned:

 

 

individual steps separated-out here: https://www.avrfreaks.net/commen...

 

EDIT 2

 

So copy-and-paste just does a single frame of the animation frown

 

 

 

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...
Last Edited: Mon. Jan 25, 2021 - 01:22 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Unfortunately the Microchip description "TB3215 Getting Started with SPI" is not very understable for anyone working with SPI for the first time:

 

3. Sending Data as a Master SPI Device

This use case follows the steps:
• Configure the location of the SPI pins
• Initialize the peripheral
• Configure the direction of the pins
• Control slave devices
• Send data as a master device

 

How to Send Data as a Master Device

Once the user writes new data into the DATA register the hardware starts a new transfer, generating the clock on the line and shifting out the bits.

 

SPI0.DATA = data;

 

No information what to do if you need to receive data as the master without sending any data to slave although there are just 4 possibilities:

 

  1. Send data as master to slave
  2. Receive data as master from slave
  3. Receive data on slave from master
  4. Send data from slave to master
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

The act of writing data to the spi initiates the transfer. If MOSI is not connected, it makes no difference. The value that you write makes no difference.

Simply write a byte to the spi peripheral. Wait until it is sent. Read the returned value. Rinse and repeat for the required number of bytes you want to read.

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

Thank you to all which helped me understand how to control the SPI.

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

 

Kevil wrote:
Unfortunately the Microchip description "TB3215 Getting Started with SPI" is not very understandable for anyone working with SPI for the first time:

That's to be expected:  it is telling you how to use the microcontroller's features - not teaching you the basics of SPI.

 

SPI is a very well-established and widely-used connections - there are plenty of references available to explain the basics of how SPI works.

 

See #15 - did you follow those links?

 

Application Notes also have to be read in conjunction with the datasheet:

 



 

 

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...
Last Edited: Tue. Jan 26, 2021 - 12:36 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

awneil wrote:

SPI is always full-duplex

And it's for this reason that you don't usually have SPI_send() and SPI_receive() functions as everything can always be done with a single function:

uint8_t SPI_exchange(uint8_t data) {
    SPDR = data;
    while(SPI int flag not set);
    return SPDR;
}

That can be used in one of three ways:

(void) SPI_exchange(value_to_send); // send only
result = SPI_exchange(dont_care_value); // send any rubbish as only interested in receive
result = SPI_exchange(value_to_send); // both send and receive

The middle one is just like the last in fact but you know that the SPI device is not interested in what you send - you are only sending it because the AVR is master and the only way to get the exchange process started is to write something, (anything!), into the data register. The byte you send in this case is often called the "stuffing byte" or "filler byte". While you can send anything you like (no one will use it) habit suggests that 0x00 or 0xFF are most often used for stuffing.

 

Of course if you really wanted to you could make up SPI_send() and SPI_receive() functions but they would just be:

void SPI_send(uint8_t data) {
    (void)SPI_exchange(data); // ignore the return
}
uint8_t SPI_receive(void) {
    return SPI_exchange(0xFF); // send FF as stuffing to start transfer
}

BTW when a function returns a value but you are not interested you can prefix the function call with "(void)" to say "I'm ignoring the return value". This keeps things like MISRA, Lint, Klockwork, QAC, etc happy so they don't moan about "ignoring return value" ;-)

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

clawson wrote:
you are only sending it because the AVR is master and the only way to get the exchange process started is to write something, (anything!)

Indeed.

@Kevil: just to hammer it home, this applies to any SPI Master; it is inherent to the way SPI works - it is not specific to AVR.

 

EDIT

 

For example,

 

The Wikipedia article linked above wrote:

To begin communication, the bus master configures the clock, using a frequency supported by the slave device, typically up to a few MHz.

The master then selects the slave device with a logic level 0 on the select line.

If a waiting period is required, such as for an analog-to-digital conversion, the master must wait for at least that period of time before issuing clock cycles.

During each SPI clock cycle, a full-duplex data transmission occurs. The master sends a bit on the MOSI line and the slave reads it, while the slave sends a bit on the MISO line and the master reads it.

This sequence is maintained even when only one-directional data transfer is intended.

 

https://en.wikipedia.org/wiki/Serial_Peripheral_Interface#Data_transmission

(my emphasis)

 

#SPIFullDuplex

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...
Last Edited: Tue. Jan 26, 2021 - 02:25 PM