Sonsivri
 
*
Welcome, Guest. Please login or register.
Did you miss your activation email?
December 03, 2016, 03:20:56 03:20


Login with username, password and session length


Pages: [1]
Print
Author Topic: AVR SPI problem  (Read 7215 times)
0 Members and 1 Guest are viewing this topic.
deveshsamaiya
Newbie
*
 Muted
Offline Offline

Posts: 28

Thank You
-Given: 15
-Receive: 13


« on: November 14, 2009, 03:40:03 15:40 »

hello all...
I am trying to make a synchronous communication between two ATmega8 as Master and Slave. I using the following code with Fosc=1MHz internal RC. It is not working please help me....Please tell me what is wrong in this code???
SPI master code....
Code:

#include<avr/io.h>
#include<util/delay.h>
#include<compat/deprecated.h>
void SPI_masterinit(void)
{
  DDRB=0x32;    // MOSI, SS and SCK as output
  SPCR=(1<<SPE)|(1<<MSTR)|(1<<SPR0)|(1<<SPR1);  // SPI enable, MASTER device, Fosc/128
  cbi(PORTB,2);
}

void SPI_master_transmit(unsigned char cdata)
{
 SPDR=cdata;
 while(!(SPSR & (1<<SPIF)));
}

int main(void)
{
 
  SPI_masterinit();
 
  while(1)
  {
   
SPI_master_transmit(0x01);


  }


  return 0;
}






SPI Slave code...
Code:

#include<avr/io.h>

void SPI_slave_init(void)
{
  DDRB=0x01;    // MISO as output
  SPCR=(1<<SPE);  // SPI enable, Slave device
}

unsigned char SPI_slave_receive(void)
{
 while(!(SPSR & (1<<SPIF)));
 return SPDR;
}

int main(void)
{
  unsigned char rx_data;
  DDRC=0xFF;
  PORTC=0x00;
  SPI_slave_init();
  while(1)
  {
    rx_data=SPI_slave_receive();
    if(rx_data==0x01)  // If data received is 0x01
PORTC=0xFF;          // LED at PORTC On
if(rx_data==0x02)
PORTC=0x00;
  }


  return 0;
}


Logged

embedded@iit
maduran
Newbie
*
Offline Offline

Posts: 22

Thank You
-Given: 180
-Receive: 9


« Reply #1 on: November 14, 2009, 05:44:41 17:44 »

"When the SPI is configured as a Slave, the Slave Select (SS) pin is always input. When SS is
held low, the SPI is activated, and MISO becomes an output if configured so by the user. All
other pins are inputs. When SS is driven high, all pins are inputs except MISO which can be user
configured as an output, and the SPI is passive, which means that it will not receive incoming
data. Note that the SPI logic will be reset once the SS pin is driven high.
The SS pin is useful for packet/byte synchronization to keep the Slave bit counter synchronous
with the master clock generator. When the SS pin is driven high, the SPI Slave will immediately
reset the send and receive logic, and drop any partially received data in the Shift Register."

The SS pin is driven low or high by the master.
Logged
samir_1982
Junior Member
**
 Muted
Offline Offline

Posts: 45

Thank You
-Given: 30
-Receive: 76


« Reply #2 on: November 15, 2009, 04:41:42 16:41 »

Hi
sample code
http://winavr.kavirelectronic.ir
Logged

Portable software Flow code orcad9 protel99 Proteus ccs And more
http://www.sonsivri.com/forum/index.php?topic=20330.msg72674#msg72674
yasir9909
Active Member
***
Offline Offline

Posts: 153

Thank You
-Given: 7
-Receive: 107


« Reply #3 on: November 15, 2009, 09:14:06 21:14 »

deveshsamaiya

apparently making two microcontrollers communicate with each other through SPI,one configured as master and the other configured as slave is quite simple...

You can simply use the code from data sheet of AVR (ATmega8) microcontroller

I would post the working models simulated in Protues later for you

At the moment you should study SPI port,including master slave configurations and corresponding C codes, from Data sheet of AVR (ATmega8) in detail

Why don't you use external crystal based oscillator?
« Last Edit: November 15, 2009, 09:21:38 21:21 by yasir9909 » Logged

regards
m.yasir
deveshsamaiya
Newbie
*
 Muted
Offline Offline

Posts: 28

Thank You
-Given: 15
-Receive: 13


« Reply #4 on: November 16, 2009, 08:57:03 08:57 »

@yasir question...why dont you use external crystal based oscillator.??

Ya actually i can use that no problem at all. Is that can be a problem?? i studied the data sheet example codes also. that code wasnt working for slave side so i decided to use interrupt for SPI.
Logged

embedded@iit
yasir9909
Active Member
***
Offline Offline

Posts: 153

Thank You
-Given: 7
-Receive: 107


« Reply #5 on: November 16, 2009, 10:42:22 10:42 »

deveshsamaiya

well,i cannot be sure about SPI,however as far as i know about serial communication through UART,internal oscillator poses problems and is not considered as reliable as external stable crystal oscillator for serial communication...

may be internal oscillator could also pose such issues of stability and reliability for spi to spi communication...

Any ways,i have got the code for spi to spi communication between two ATmega32 microcontrollers and it has been compiled in ICC AVR compiler

Posted on: 16-11-2009, 10:26:47 - Automerged

here is the code for data transmission from master spi :

Code:
//ICC-AVR application builder : 4/16/2009 6:56:37 PM
// Target : M32
// Crystal: 11.059Mhz

#include <iom32v.h>
#include <macros.h>

#define cs 0x10

unsigned int timer0_counter=0,j=0;

void port_init(void)
{
  PORTA = 0x00;
  DDRA  = 0x03;
  PORTB = 0x00;
  DDRB  = 0x00;
  PORTC = 0x00;
  DDRC  = 0x00;
  PORTD = 0x00;
  DDRD  = 0x00;
}

//TIMER0 initialize - prescale:1024
// WGM: Normal
// desired value: 100Hz
// actual value: 100.933Hz (0.9%)
void timer0_init(void)
{
     TCCR0 = 0x00; //stop
  TCNT0 = 0x95; //set count
  OCR0  = 0x6B;  //set compare
  TCCR0 = 0x05; //start timer
}

#pragma interrupt_handler timer0_ovf_isr:iv_TIM0_OVF
void timer0_ovf_isr(void)
{
  TCNT0 = 0x95; //reload counter value

timer0_counter++;
if(timer0_counter==2)
{
    PORTA^=0x03;
timer0_counter=0;
     
}
}

//SPI initialize
// clock rate: 2764749hz
void spi_init(void)
{
  SPCR = 0x50; //setup SPI - SPE,MSTR,
  SPSR = 0x00; //setup SPI

//PORTB=(1<<PORTB4)|(1<<PORTB5)|(1<<PORTB7);
PORTB=(1<<PB4)|(1<<PB5)|(1<<PB7);
DDRB=(1<<DDB4)|(1<<DDB5)|(1<<DDB7);
}

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


//UART0 initialize
// desired baud rate: 57600
// actual: baud rate:57599 (0.0%)
void uart0_init(void)
{
  UCSRB = 0x00; //disable while setting baud rate
  UCSRA = 0x00;
  UCSRC = BIT(URSEL) | 0x06;
  UBRRL = 0x0B; //set baud rate lo
  UBRRH = 0x00; //set baud rate hi
  UCSRB = 0x18;
}

//call this routine to initialize all peripherals
void init_devices(void)
{
  //stop errant interrupts until set up
  CLI(); //disable all interrupts
  port_init();
  timer0_init();
  spi_init();
  uart0_init();

  MCUCR = 0x00;
  GICR  = 0x00;
  TIMSK = 0x01; //timer interrupt sources
  SEI(); //re-enable interrupts
  //all peripherals are now initialized
}

//
void main(void)
{
     init_devices();
  //insert your functional code here...
while(1)
{
       PORTB &=~cs;
       SPI_MasterTransmit( 'a' );
       PORTB |=cs;
   
   
}
}




And this is the code SPI slave:

Code:

//ICC-AVR application builder : 3/31/2009 1:09:34 PM
// Target : M32
// Crystal: 11.059Mhz

#include <iom32v.h>
#include <macros.h>

unsigned char spiData;

unsigned int k=0;

void port_init(void)
{
  PORTA = 0x00;
  DDRA  = 0x00;
  PORTB = 0x00;
  DDRB  = 0x00;
  PORTC = 0x00;
  DDRC  = 0x03;
  PORTD = 0x00;
  DDRD  = 0x00;
}

//TIMER0 initialize - prescale:1024
// WGM: Normal
// desired value: 100Hz
// actual value: 100.933Hz (0.9%)
void timer0_init(void)
{
  TCCR0 = 0x00; //stop
  TCNT0 = 0x95; //set count
  OCR0  = 0x6B;  //set compare
  TCCR0 = 0x05; //start timer
}

#pragma interrupt_handler timer0_ovf_isr:iv_TIM0_OVF
void timer0_ovf_isr(void)
{
  TCNT0 = 0x95; //reload counter value
}

//SPI initialize
// clock rate: 2764749hz
void SPI_SlaveInit(void)
{
PORTB=(1<<PB6);
  SPCR = 0x40; //setup SPI
  SPSR = 0x00; //setup SPI
}

char SPI_SlaveReceive(void)
{
  /* Wait for reception complete */
while(!(SPSR & (1<<SPIF)))
;
/* Return data register */
return SPDR;
}

//UART0 initialize
// desired baud rate: 57600
// actual: baud rate:57599 (0.0%)
void uart0_init(void)
{
  UCSRB = 0x00; //disable while setting baud rate
  UCSRA = 0x00;
  UCSRC = BIT(URSEL) | 0x06;
  UBRRL = 0x0B; //set baud rate lo
  UBRRH = 0x00; //set baud rate hi
  UCSRB = 0x18;
}

//call this routine to initialize all peripherals
void init_devices(void)
{
  //stop errant interrupts until set up
  CLI(); //disable all interrupts
  port_init();
  timer0_init();
  SPI_SlaveInit();
  uart0_init();

  MCUCR = 0x00;
  GICR  = 0x00;
  TIMSK = 0x01; //timer interrupt sources
  SEI(); //re-enable interrupts
  //all peripherals are now initialized
}


void USART_Transmit( unsigned char data )
{
  /* Wait for empty transmit buffer */
while ( !( UCSRA & (1<<UDRE)) )
;
/* Put data into buffer, sends the data */
UDR = data;
}

//
void main(void)
{
  init_devices();
  //insert your functional code here...
  while(1)
{
         spiData=SPI_SlaveReceive();
       
       
   if( (k%32)==0 )
   {
        USART_Transmit( '\r' );USART_Transmit( '\n' );
   }
   k++;
   
   USART_Transmit( spiData );
   
   //USART_Transmit( 70 );
}
}



This is quite simple code set,one microcontroller (master) sends a character 'a' continuously to the other microcontroller (slave) through SPI.The microcontroller which receives data from master displays it on virtual terminal through serial port

This is just tom give an idea how you can do spi-to-spi communication in master-slave mode



Posted on: 16-11-2009, 10:38:37 - Automerged

Here is the proteus simulation file named 'SPI32SPI32', for the above codes,attached with this post
Logged

regards
m.yasir
wellnerson1
Active Member
***
Offline Offline

Posts: 101

Thank You
-Given: 23
-Receive: 94



« Reply #6 on: November 17, 2009, 05:15:57 05:15 »

Hai deveshsamaiya,
 The problem in your coding is resolved. There is no much problem in your code. Only problem is you have to set the data direction register of port B (DDRB) properly in master mode coding. The modification is DDRB=0x2C;. Also ihave added the following code snippet in the while loop for blinking the leds._delay_ms(1);SPI_master_transmit(0x02);. The entire coding is attached in this message. Also check the fuse bit for atmega8 reset pin, otherwise the led connected in this pin will not blink.
With regards.
Logged
Pages: [1]
Print
Jump to:  


DISCLAIMER
WE DONT HOST ANY ILLEGAL FILES ON THE SERVER
USE CONTACT US TO REPORT ILLEGAL FILES
ADMINISTRATORS CANNOT BE HELD RESPONSIBLE FOR USERS POSTS AND LINKS

... Copyright 2003-2999 Sonsivri.to ...
Powered by SMF 1.1.18 | SMF © 2006-2009, Simple Machines LLC | HarzeM Dilber MC