Arduino ATmega328P上的错误SPI

时间:2018-07-06 16:18:07

标签: arduino avr spi

我在ATmega328上使用带有原始代码的SPI,数据已正确传输,但第二次返回的值恰好正确。我不知道为什么我认为当我按下按钮时,数据缓冲寄存器不会立即更新(这是视频,左为黄色LED,右为红色LED:https://drive.google.com/open?id=1bf2XlxRBGCaUo0j2ezB2XFxfSItUmChN和下面的代码)

我使用Arduino Uno是发送数据并获得响应的大师。 Arduino Nano是一个从设备,用于接收数据并响应主设备。

Arduino Uno(主)代码:

#define DDR_SPI DDRB
#define PORT_SPI PORTB
#define MOSI 3
#define SCK 5
#define SS 2
#define red 2
#define cbi(port, bits)      (port) &= ~(1 << (bits))
#define sbi(port, bits)     (port) |=  (1 << (bits))

volatile uint8_t Data1;
volatile uint8_t Data2;
void setup()
{
  Serial.begin(9600);   //debug by UART
  SPCR = 0;             // Reset SPCR = 0

  DDR_SPI |= (1<<MOSI)|(1<<SCK)|(1<<SS);// MOSI,SCK,SS - OUTPUT , MISO - INPUT
  SPCR |= (1<<SPE)|(1<<MSTR)|(1<<SPR0); // Enable spi , Set master , div/16

  pinMode(red,OUTPUT);   // led output at pin 2
  pinMode(6,INPUT_PULLUP);    // internal res input at pin6
  pinMode(7,INPUT_PULLUP);    // internal res input at pin7

  sbi(PORT_SPI,SS);   // disable slave
}

uint8_t SPI_MasterTransmit(uint8_t cData)
{
  SPDR = cData;                   // Start transmission 
  delay(50);
  while(bit_is_clear(SPSR,SPIF)); //Wait for transmission complete
  return SPDR;
}

void loop()
{
   if(bit_is_clear(PIND,6))       // if i push button at pin 6
  {
     while(bit_is_clear(PIND,6));  // if i still push button at pin 6
     cbi(PORTB,SS);               // enable slave

     Data1 = SPI_MasterTransmit(1); // send value 1 to slave
     Serial.print(Data1);           // debug
     delay(50);

     if(Data1 == 2)                 //if slave response value = 2
     digitalWrite(red,LOW);         //turnOFF led at pin 2

     sbi(PORT_SPI,SS);              // disable slave
  }


   else if(bit_is_clear(PIND,7))  // if i push button at pin 7
  {
    while(bit_is_clear(PIND,7)); // if i still push button at pin 7
    cbi(PORT_SPI,SS);            // disable slave

    Data2 = SPI_MasterTransmit(3);  // send value 3 to slave
    Serial.print(Data2);            // debug
    delay(50);

    if(Data2==4)                    //if slave response value = 4
    digitalWrite(red,HIGH);         //turnON led at pin 2

    sbi(PORT_SPI,SS);               // disable slave
  }
}

Arduino Nano(从属)代码:

#define MISO 4
#define yellow 2
#define cbi(port, bits)      (port) &= ~(1 << (bits))
#define sbi(port, bits)     (port) |=  (1 << (bits))

volatile uint8_t Data;
void setup()
{
  SPCR = 0;                   // reset SPCR = 0
  DDRB |= (1<<MISO);          // MISO -  OUTPUT , SCK,MOSI,SS - INPUT
  SPCR |= (1<<SPE)|(1<<SPIE); // enable spi , spi_interrupt
  pinMode(yellow ,OUTPUT);    // Led output at pin2

}
 void SPI_Response(uint8_t cData)
{
  SPDR = cData;                   //Start transmission
  while(bit_is_clear(SPSR,SPIF)); //Wait for transmission complete
}

void loop()
{
}

ISR(SPI_STC_vect)   // Vector interrupt spi
{
  Data = SPDR;      // volatile Data = data receive

  if(Data == 1) 
  {
  digitalWrite(yellow ,HIGH);   // i turnOn led if i receive data = 5
  SPI_Response(2);              // and response to master a value = 7
  delay(10);
  }

  else if(Data == 3)
  {
  digitalWrite(yellow,LOW);     // i turnOFF led if i receive data = 6
  SPI_Response(4);              //and response to master a value = 8
  delay(10);
  }
}

1 个答案:

答案 0 :(得分:0)

您知道四线SPI是全双工的,对吗?主机和从机正在同时发送数据。

通常要做的事情是发送控制字节,然后发送一个或多个虚拟字节以接收数据。