NerdKits - electronics education for a digital generation

You are not logged in. [log in]

NEW: Learning electronics? Ask your questions on the new Electronics Questions & Answers site hosted by CircuitLab.

Microcontroller Programming » SPI Problem!

May 17, 2012
by kemil
kemil's Avatar

Hi Everyone,

Im having problems sending a string from one mcu to another via spi master/slave communication.

Brief description: The code below attempts to send a string from the master mcu to the slave mcu. the reason for the time over flow interrupts was that i originally wanted the sting to be sent when the interrupt was activated but i could not get that to work so i tried to simplify it by just send one string before the while loop.

I have managed to send one byte at a time when i get rid of the SendString() function and just put a value straight into the SPIMaster function but now with the added layer of complexity this no longer works!

on the slave side of things ive tried to keep things simple and just see if the byte ive just received is 'h' but its not. ive tried more complicated data receiving code such as the code directly below but that doesnt work either... even though it works when receiving data from the pc.

Can someone please help!

Cheers kemil


Better data reception code: (which goes into the spi interrupt

  uint8_t ReceptionBuffer[10];
  uint8_t BytesReceived;
  volatile bool NewCommandReady;
  {
  char ReceivedByte;
  ReceivedByte = UDR0;

 // Check if end of command character has been received, or buffer is full
 if ((ReceivedByte == '\n') || (BytesReceived == (sizeof(ReceptionBuffer)     - 1)))
 {
    // Null terminate the buffer so that it can be processed as a string
    ReceptionBuffer[BytesReceived] = 0x00;

    // Reset buffer size
    BytesReceived   = 0;

    // Indicate new command ready
    NewCommandReady = true;
 }
 else
 {
    // Store received byte into the next position in the buffer
    ReceptionBuffer[BytesReceived++] = ReceivedByte;
 }
 }

Master Code:

 #define F_CPU 14745600
 #include <stdio.h>
 #include <avr/io.h>
 #include <avr/interrupt.h>
 #include <math.h>
 #include <inttypes.h>
 #include <avr/pgmspace.h>
 #include <stdbool.h>
 #include <string.h>
 #include <stdlib.h>
 #include "../libnerdkits/uart.h"
 #define USART_BAUDRATE 115200
 #define BAUD_PRESCALE (((F_CPU / (USART_BAUDRATE * 16UL))) - 1)
 int count = 0;
 volatile int on = 0; 
 char IncommingData[] = "h";

void SPIMasterInit(void)
{
//set MOSI, SCK and SS as output
DDRB |= (1<<PB3)|(1<<PB5)|(1<<PB2);
//set SS to high
PORTB |= (1<<PB2);
//enable master SPI at clock rate Fck/16
SPCR = (1<<SPE)|(1<<MSTR)|(1<<SPR0);
}

//master send function
void SPIMasterSend(char data)
{
//select slave
PORTB &= ~(1<<PB2);
//send data
SPDR=data;
//wait for transmition complete
while (!(SPSR &(1<<SPIF)));
//SS to high
PORTB |= (1<<PB2);
}

void SendString(char string[])
{
uint8_t length;
uint8_t i;

length = strlen(string);
for(i=0; i < length; i++)
{
   SPIMasterSend(string[i]);
}
return;
}

int main (void) 
{ 
  DDRC |= (1 << 0); // Set LED as output

  TIMSK1 |= (1 << TOIE1); // Enable overflow interrupt 
  sei(); // Enable global interrupts 
  ICR1 =18432;
  TCCR1A = (1<<COM1A1)|(1<<COM1B1) | (1<<WGM11);//16bit pwm
  TCCR1B = (1<<WGM13) | (1<<WGM12) | (1<<CS11);//16bit pwm

  //initialize master SPI
  SPIMasterInit();

 SendString(IncommingData);

 while(1)
  { 
   if (on ==1)
{
   DDRC |= (1<<PC3);
   PORTC |= (1<<PC3);
on = 0;
}
if (on ==2)
{
DDRC |= (1<<PC3);
    PORTC &= ~(1<<PC3);
on = 0;
}
    } 
    }

 ISR(TIMER1_OVF_vect) 
 { 
  if (count == 100)
 {
 count = 0;
 }

 if (count == 0)
 {
//turn on heating element
 on = 1;

 }
if (count == 50)
 {
 on = 2;
//turn off Heating element

 }
 count++;

 }

Slave Code:

#define F_CPU 14745600

#include <stdio.h>

#include <avr/io.h>
#include <avr/interrupt.h>
#include <math.h>
#include <inttypes.h>
#include <avr/pgmspace.h>
#include <stdbool.h>
#include <string.h>
#include <stdlib.h>

#include "../libnerdkits/uart.h"

#define USART_BAUDRATE 115200
#define BAUD_PRESCALE (((F_CPU / (USART_BAUDRATE * 16UL))) - 1)

uint8_t ReceptionBuffer[10];
uint8_t BytesReceived;
volatile bool NewCommandReady;
volatile char ReceivedByte;
void SPISlaveInit(void)
{
//set MISO as output
DDRB |= (1<<PB4);
//enable SPI and enable SPI interrupt
SPCR = (1<<SPE)|(1<<SPIE);
}
void InitPort(void)
{
//set PD6 (OC0A) as output
DDRC|=(1<<PC3);
}

ISR(SPI_STC_vect)
{

ReceivedByte = SPDR;
if (ReceivedByte == 'h')
{

DDRC |= (1<<PC3);
PORTC |= (1<<PC3);  
}
}

int main(void)
{
//initialize slave SPI
SPISlaveInit();
InitPort();
sei();

while (1)
{

}
}

Post a Reply

Please log in to post a reply.

Did you know that using an alternating excitation voltage can reduce the noise in many sensor measurements? Learn more...