SPI problems

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

Hey guys, Im trying to setup a simple SPI from AVR to AVR, and I cannot get the two to communicate, but mainly I cannot get my master (an atmega32) to send!

Here is my master code:

#include 
#include 
#include 
#include 
#include 

#include 
#include 

void long_delay(unsigned int times, unsigned int dly);
void spi_init(void);
uint8_t SPI_Transmit(uint8_t cData);

int main (void)
{
	DDRD = BIT(PD6);
	PORTD = 0;
	spi_init();
	uint8_t tsend = 1;
	sei();

	while(1)
	{
		SETBIT(PORTD,PD6);
		SPI_Transmit(tsend);
		tsend++;
		long_delay(100,10);
		CLEARBIT(PORTD,PD6);
		long_delay(100,10);
		long_delay(100,10);
	}
    return (0);
}

void long_delay(unsigned int times, unsigned int dly)
{
	unsigned int i;
	for(i=0;i

so basically just to test, its counting an number on a uint8_t then sending it threw spi, but when I connect my oscope to SCK its dead, there is no clock signal that I can see, same with miso, no information I can see being sent.

here is my receiver code: its an atmega168

void boot(void);
void long_delay(unsigned int times, unsigned int dly);
void spi_init(void);

int main (void)
{
	uart_init();
	spi_init();
	sei();
	boot();

	while(1)
	{
		//interrupts handle the rest.
	}
    return (0);
}


void long_delay(unsigned int times, unsigned int dly)
{
	unsigned int i;
	for(i=0;i

I haven't really gotten to test this because my master is not sending like he should!

I have tried all sorts of misc codes all over the net, and it is just not working! any ideas?

also when I do connect the avrs is it:
master slave
miso -> mosi
or
miso -> miso

?? I tried them both but of course no luck.

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

MOSI stands for Master Out Slave In.
MISO stands for Master In Slave Out.
so clearly you connect MOSI to MOSI and MISO to MISO
the basic problem with SPI is its just a shift register really with no mechanism for the slave to insert wait states ,so it isnt really an interprocessor communications bus, it is possible to use it as such as long as you are aware that the slave has to be always ready with a byte to send back to the master in the time it takes the master to send a byte to the slave and restart the clock which is a slight problem if yor slave is doing something at the time that the master is expecting a reply.I would suggest the TWI is a much easier, albeit slower, way to interface two devices.
I forgot to mention you need to make sure SS is set as an output with a pull-up enabled on the master device because if its set as an input and gets pulled low then the master will switch into slave mode.

Last Edited: Tue. Apr 10, 2007 - 06:37 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

MISO-MISO and MOSI-MOSI. The master uses the MOSI pin, and the slave controls the MISO pin (which device is the master and which is the slave is software-selectable).

Make sure you've got the correct pin numbers for MOSI/MISO/SCK/SS in your initialization code. If /SS is an input and it is pulled low, the AVR will switch to Slave mode. Make sure both it, SCK and MOSI are outputs, and MISO is an input with pullup enabled.

Other than that, I can't see any other obvious reason why your master AVR is not sending out SCK pulses.

- Dean :twisted:

Make Atmel Studio better with my free extensions. Open source and feedback welcome!

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

I assume you use PORTD(6) as the chip select for the slave, but you set it high and I think AVRs SS is active low. Try this on the master (yes, I know it's half pseudo-code, so don't use it directly =)

Init:
    char dummyByte;

    DDRB |= MOSI | SCK | SS;
    PORTB |= SS; // Set SS as input with pullup
    SPCR = SPE | MSTR | CPHA | CPOL | SPR0;
      
    dummyByte = SPSR;
    dummyByte = SPDR;


Transfer:
    char dummyByte, mySendByte, myRecvByte;
    dummyByte = SPSR;
    dummyByte = SPDR;

    PORTD &= ~PIN6;
    SPDR = mySendByte;
    while ( ! (SPSR & (1<<SPIF)) ) {};
    myRecvByte = SPDR;

Reading the SPCR and SPDR bytes before transactions seemed to clear up some issues I was having.

On the slave do you also need to set the CPHA/CPOL bits?

Clancy _________________ Step 1: RTFM Step 2: RTFF (Forums) Step 3: RTFG (Google) Step 4: Post