SPI between two different microcontrollers problem

Status
Not open for further replies.

foxbrain

Full Member level 2
Joined
Feb 1, 2010
Messages
142
Helped
5
Reputation
10
Reaction score
4
Trophy points
1,298
Location
Damas
Visit site
Activity points
2,322
Hi
i'm working on spi communication between atmega168(master) and atmega16(slave)
the problem is that the slave receives what the master send but the master can't read what the slave sends.here r the codes:
Atmega 16:
Code:
#include <avr/io.h>
#include <util/delay.h>

#define SETBIT(ADDRESS,BIT) (ADDRESS |= (1<<BIT))
#define CLEARBIT(ADDRESS,BIT) (ADDRESS &= ~(1<<BIT))
#define CHECKBIT(ADDRESS,BIT) (ADDRESS & (1<<BIT))

#define RF_PORT	PORTB				// SPI Port
#define RF_DDR	DDRB
#define RF_PIN	PINB

#define SDI		5					// MOSI Pinnummer
#define SCK		7					// SCK Pinnummer
#define CS		4					// CS Pinnummer
#define SDO		6					// MISO Pinnummer
//unsigned int d=0;
// Initialize SPI Slave Device
void del (unsigned int dela)
{
	for (int i=0;i<dela;i++)
	{
		asm("NOP");
	}
	
}
void spi_init_slave (void)
{

	RF_DDR&=~((1<<SDO));
	RF_DDR&=~((1<<SCK));
	RF_DDR&=~((1<<CS));
	RF_DDR|=(1<<SDI);
    SPCR = (1<<SPE)|(1<<CPOL)|(1<<CPHA)|(1<<DORD);   //Enable SPI
}

unsigned char spi_tranceiver (unsigned char data)
{
	asm("NOP");

	/////////
    SPDR = data; 
	 
	while(!(SPSR & (1<<SPIF)));
	asm("NOP");
    return(SPDR);                      //Return received data
}
int main(void)
{
	unsigned char a=6;
	unsigned char b;
	asm("NOP");asm("NOP");asm("NOP");asm("NOP");asm("NOP");asm("NOP");
	DDRD=0xFF;
	spi_init_slave();
    while(1)
    {
		SETBIT(PORTD,0);
		_delay_ms(500);
		CLEARBIT(PORTD,0);
		_delay_ms(500);
        b=spi_tranceiver(a);
		if (b==5)
		{
			PORTD=0xFF;
			_delay_ms(500);
			PORTD=0x00;_delay_ms(500);
		}
    }
}
Atmega 168:

Code:
#include <avr/io.h>
#include <util/delay.h>
#define SETBIT(ADDRESS,BIT) (ADDRESS |= (1<<BIT))
#define CLEARBIT(ADDRESS,BIT) (ADDRESS &= ~(1<<BIT))
#define CHECKBIT(ADDRESS,BIT) (ADDRESS & (1<<BIT))

#ifndef cbi
#define cbi(sfr, bit)     (_SFR_BYTE(sfr) &= ~_BV(bit)) 
#endif
#ifndef sbi
#define sbi(sfr, bit)     (_SFR_BYTE(sfr) |= _BV(bit))  
#endif
#define RF_PORT	PORTB				// SPI Port
#define RF_DDR	DDRB
#define RF_PIN	PINB
#define SDI		3					// MOSI Pinnummer
#define SCK		5					// SCK Pinnummer
#define CS		2					// CS Pinnummer
#define SDO		4					// MISO Pinnummer

void spi_init_master (void)
{
  	//RF_PORT=(1<<CS);
	RF_DDR&=~((1<<SDO));
	RF_DDR|=(1<<SDI)|(1<<SCK)|(1<<CS);
	SPCR=(1<<SPE)|(1<<MSTR)|(1<<CPOL)|(1<<CPHA)|(1<<DORD);
//	SPSR |= (1<<SPI2X);
}

unsigned char spi_tranceiver (unsigned char data)
{
	cbi(RF_PORT, CS);
    SPDR = data;                       //Load data into the buffer
	while(!(SPSR & (1<<SPIF)));
	
	sbi(RF_PORT, CS);
    return(SPDR);                   //Return received data
}

int main(void)
{
	unsigned char a=5;
	unsigned char b;
		CLKPR=(1<<CLKPCE);
		CLKPR=(0<<CLKPS0);
		CLKPR=(0<<CLKPS1);
		CLKPR=(1<<CLKPS2);
		CLKPR=(0<<CLKPS3);
	DDRD=0xFF;
	DDRC=0xFF;
	spi_init_master();
	asm("NOP");asm("NOP");
    while(1)
    {

		SETBIT(PORTC,0);
		_delay_ms(500);
		CLEARBIT(PORTC,0);
		_delay_ms(500);
        b=spi_tranceiver(a);
	
		if (b==6)
		{
			PORTD=0xFF;
			_delay_ms(500);
			PORTD=0x00;_delay_ms(500);
		}
		
    }
}
Please Help!!!!
Thanks
 

Atmega168..............atmega16
MOSI----------->MISO
MISO----------->MOSI
SS-------------->SS
SCK------------->SCK
and the vcc and gnd connected
each microcontroller is connected to crystal 3.5MHZ with 2 capacitors to the ground
 

I think it might be a mismatch of baud rate(s)...The baud rate for the operation of slave sending data to master,and the baud rate when the master sends data to slave...you have kept them the same,right?
Can you please explain the code for both master and slave units..The functions part,after defining the pins and header files?
 

well the first part is the initialization which is for the master to set the pins mosi and ss and sck as output and miso as input , in the slave the opposite and also selecting the slave and master
the commands : CLKPR=(1<<CLKPCE);
to make at168 works at the same clock speed of at16
the function spi_tranceiver for transmitting and receiving data since i put the data in the SPDR register then wait until transmission is done then it returns what i had received.
i made a blinking led on port D,0 to make sure the micro controller don't fall into a finite loop
when i get what i had sent all pins in port d are ones.
how can i make the synchronization?
 

Status
Not open for further replies.

Similar threads

Cookies are required to use this site. You must accept them to continue using the site. Learn more…