Continue to Site

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.

[SOLVED] SPI Communication between Atmega32 and Atmega8

Status
Not open for further replies.

ANS HAFEEZ

Advanced Member level 4
Full Member level 1
Joined
Jul 25, 2013
Messages
101
Helped
5
Reputation
10
Reaction score
5
Trophy points
1,298
Location
LAHORE,PAKISTAN
Visit site
Activity points
1,911
SALAM to all
Atmega32 as a Slave
Atmega8 as a Master
Code is Done according to datasheets But Proteus Simulation Not Working
CODE for Master:
Code:
/*
* SPI_8_MASTER.c
*
* Created: 1/8/2015 3:36:36 PM
*  Author: ANCC
*/
#define F_CPU 1000000UL
#include <avr/io.h>
#include <util/delay.h>

#define  MOSI PINB3
#define  SCK PINB5
#define  MISO PINB4
void SPI_MasterInit(void)
{
	/* Set MOSI and SCK output, all others input */
	DDRB = (1<<MOSI)|(1<<SCK);
	DDRB &= ~(1<<MISO);
	/* Enable SPI, Master, set clock rate fck/16 */
	SPCR = (1<<SPE)|(1<<MSTR)|(1<<SPR1);
	SPSR=0x00;
}

void SPI_MasterTransmit(char cData)
{
	/* Start transmission */
	SPDR = cData;
	/* Wait for transmission complete */
	while(!(SPSR & (1<<SPIF)));
}
int main(void)
{
	SPI_MasterInit();
	while(1)
	{
		SPI_MasterTransmit('C');
	}
}



CODE FOR SLAVE:
Code:
/*
* SPI_32.c
*
* Created: 1/8/2015 3:26:11 PM
*  Author: ANCC
*/
#define F_CPU 1000000UL
#include <avr/io.h>
#include <util/delay.h>
#define MISO PINB6
#define MOSI PINB5
#define SCK PINB7
void SPI_SlaveInit(void)
{
	/* Set MISO output, all others input */
	DDRB |= (1<<MISO);
	DDRB &=~(1<<MOSI)|(1<<SCK);
	/* Enable SPI */
	SPCR = (1<<SPE)|(1<<SPR1);
	SPSR=0x00;
}
char SPI_SlaveReceive(void)
{
	/* Wait for reception complete */
	while(!(SPSR & (1<<SPIF)))
	;
	/* Return data register */
	return SPDR;
}
int main(void)
{
	SPI_SlaveInit();
	int data=0;
	DDRD=0xFF;
	while(1)
	{
		data=SPI_SlaveReceive();
		PORTD=data;
	}
}



ANy HElp???:bang:
 

Can you please expand a bit on the "...not working" part of your question?
Does either or both of the code segments not compile?
Are you getting the signals from the master but no signals from the slave?
Are the data lines showing signals but the values received not correct?
(I can see possible reasons for the last 2 anyway.)
Also, I don't have experience with your environment but I have a general distrust of simulators - I've seen too many people waste too many hours and days debugging something only to find that it is a simulator bug. I would recommend that you test your code on the hardware - you will need to have it run there eventually!
Susan
 

Thankx Susan for your reply
but now simulation Works properly but not working in hardware
i am sending 1-5 digits with the delay of 1000ms but
when i check the receivd values on LCD but lcd countinously shows 255 and some time other garbeg values and i am not getting where is problem:roll:
 

Back up a step or 2.
Make sure the hardware is working correctly and the clock is stable. Have you got all of the bypass capacitors in place? Is the PSU delivering a ripple-free and steady voltage? Not sure about the Atmega devices themselves but do they have things such as internal regulators that need external capacitors and are they all working correctly?
If both devices are working, then forget the LCD part for the moment and make sure that the slave is receiving the correct value form the master. You will need to check with a scope that the clock line is correct and that the correct data is begin sent.
If that is correct, make sure that the slave is ready BEFORE the master sends its value and that the slave stays in sync with the master. I can't see if you are using a 'slave select' line, but if you are not then I strongly recommend that you do.
The problem you might be getting (and I'm guessing a bit here but this is a common issue) is that the slave becomes ready to exchange a value while the master is sending. Alternatively, there is a bit of noise or other pulse on the clock line that the slave interprets as the first clock pulse.
Because the slave relies totally on the master for the clock pulses, it really does not care if they are seconds apart - it will simply count 8 (or 16 or whatever) of them and use whatever is in the shift register when it gets what it thinks is the last clock pulse.
The way to get around this is to use the 'slave select' line as that resets the slave so that it will ignore everything until it is selected. Therefore the master will select the slave and then start sending the clock pulses which the slave will interpret but in sync with the master.
Once you know the slave is getting the correct values form the master, then you can move on to pass those values to the LCD as there may be quite separate problems with that step.
(After typing that, I looked up the Atmega32 data sheet - it looks like the slave requires the use of the 'slave select' line - at least that is how I interpret the section at the top of page 136 on'\SS\ Pin Functionality' and the following subsection on slave mode. This may well be a situation where the simulator has not correctly mimicked the hardware correctly - another reason to be wary of simulators.)
Susan
 
but now simulation Works properly

you mean simulation works with lcd display but not at real hardware?

just a thought why spi direct UART is easy to implement.and you can check the spi logic with logic analyzer.
 

Thankx Susan it looks great Now i try it

- - - Updated - - -

you mean simulation works with lcd display but not at real hardware?

just a thought why spi direct UART is easy to implement.and you can check the spi logic with logic analyzer.

yes i mean Proteus Simulation Works properly but not work on real Hardware
 

Which device - master or slave?
I am getting a bit out of my area of experience with the Atmega devices but data overrun typically means either that the master is being asked to initiate a new exchange before the last one has completed or the slave has completed an new exchange before the previous data value was read.
Either way it means that you are not controlling the SPI peripheral correctly.
However, as I've said before, don't spend too much time trying to debug things on the simulator, especially when they involve interactions with the "outside world". Applying stimulus signals to the simulator can be a very error prone exercise. I find that my time is better spent chasing down real problems in the real code on real hardware.
Susan
 

Slave Device Says data overrun
i have some experience in AVR from 2013 but i am not getting this problem
Now on Hardware side when i turn on and turn off switch countinously it some times work and some time not i ahve checked all the connections
Really Thankx for your suggestions it help me alot :D
 

It certainly sounds like you are not detecting the completion of the exchange on the slave side fast enough to read the value before the next one arrives.
However I am a bit confused about your setup.
You say that it is the Proteus simulator that is displaying the data overrun error, but then you say that you are turning the hardware on and off.
I would say that it is time you showed us your slave-side code and let others who know the environment better than I do look to see if there is an issue.
By the way, have you used a scope to look at the signals from the master to make sure that they are as expected, and in particular that the timing between values being exchanged is what you expect?
Susan
 

Sorry for confusion
First i simulate it on Proteus Simulator and after Simulation i implement it on hardware on PCB boards
Here is a new updated code
header file for SPI:
.H file
Code:
#define MISO PB6
#define MOSI PB5
#define SCK PB7
void SPI_SLAVE_INIT(void)
{
	DDRB |= (1<<MISO);//|(1<<PINB3);
	SPCR = (1<<SPE)|(1<<SPIE);//|(1<<CPHA);//|(1<<SPR1)|(1<<SPR0);
}
char SPI_RECEIVE(void)
{
	while(!(SPSR & (1<<SPIF)));
	return SPDR;
}

C file
Code:
/*
* CENTRAL_MEGA32_CODE.c
*
* Created: 10/22/2014 7:41:55
*  Author: ANCC
*/
#define F_CPU 16000000UL
#include <avr/io.h>
#include <util/delay.h>
#include <compat/twi.h>
#include <math.h>
#include <avr/interrupt.h>
#include "LCD.h"
#include "MPU_6050.h"
#include "UART.h"
#include "MOTOR.h"
#include "SPI.h"
void DISABLE_JTAG()
{
	MCUCSR |=1<<JTD;
	MCUCSR |=1<<JTD;
}
void START_SPI()
{
	int CHK=0;
	CMD(LINE1_1);
	display("STARTING SPI FOR");
	CMD(LINE2_1);
	display("OBSTACLES DATA");
	_delay_ms(1000);
	SPI_SLAVE_INIT();
	CHK=SPI_RECEIVE();
	LCD_CLS();
	if(CHK==1 || CHK==2 || CHK==3 || CHK==4 || CHK==5 || CHK==6 || CHK==7) display("SPI OK! (Y)");
	else display("ERROR IN SPI :(");
	_delay_ms(1000);
	LCD_CLS();
	_delay_ms(1);
}
int main(void)
{
	DDRD=0x00; // SAVE H-Bridge
	DISABLE_JTAG();
	START_SPI();
	while(1)
	{
		SPI_RECEIVE();
		LCD_DisplayNumber(SPDR);
	}
}

No i m not checking the Signal from Master
actually i hav to collect data from different devices to ATMEGA32 using UART, I2C and SPI i successfully run UART and I2C but stuck at SPI
do you think is there any issue if i use all these protocoles to collect data??
 

I am still confused: if you are running on the hardware, where is that error message you mentioned (about the 'data overrrun') coming from? I can't see anything in your code that would generate that message.
When I mentioned scoping the signals, I mean that you should be able to see the master lower the \SS\ line and then send the clock pulses. If you are not seeing that then the problem is in the master end. If you are seeing them but the slave is not responding to the to them , then you need to verify your hardware connections (including the power supply etc.).
Also, it is a very bad idea to put code in your header files. If you include that header in several source files then you end up with duplicate definitions. The header file is for declarations and the c file is for definitions or implementations.
Susan
 

Susan
Thankx for ur suggestion ru posts are very helping
But my code is very large if i put all my code in .C file then lines are more than 2000 and it is difficult to debug the code thats why i made header files
i am also thinking that problem is in selecting slave

i have to collect data from GPS,Sonar sensors,motion sensor and drive a autonoumus robot
'data overrrun' error occur in Proteus
check it
where U1 is my receiver
SPI.png

- - - Updated - - -

- - - Updated - - -

yes milan i already visit maxembedded.com
 
Last edited:

I think you have (at least!) 2 separate problems occurring here. It seems to me that you are NOT using hardware but ONLY the proteus simulator for the Atmega32 slave system. I do not have any experience with the Proteus simulator but with other simulators I have used, they do not connect to real hardware and rely on simulation of the I/O signals. If that is the case and you are simulating the SPI signals coming in to the simulated processor, I would say you need to look very carefully at the timing of the simulated SPI signals.
I really need it leave it to others to help you with this aspect.
Your other problems is with your understanding of that header files are for in a C program. You say you are needing code to interact with a number of different peripherals - that is an ideal situation where you would write the code to interact with each peripheral in a separate C code file and then use the corresponding header files to let the other code modules about the externally callable functions that each contains.
I recommend that you get a good book on how to structure C code across multiple files and do, as it would seem that you are doing, try to put it all into a simple compilation unit.
Susan
 
Have you connected SPI debugger in Proteus and checked the simulation ? Does SPI lines have pull down or pull up resistors as required ?
 

Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top