Как я могу решить данные, передаваемые от ведомого устройства к главному с помощью SPI? - PullRequest
0 голосов
/ 04 августа 2020

Я пытался установить связь между двумя AVR (ATmega128) с помощью SPI.

Данные передаются правильно от ведущего к ведомому, но данные передаются неправильно от ведомого к ведущему, первый бит выборки всегда неверен.

Ведомый отправляет (0X7E) мастеру, но полученные данные (0X3F).

Где ошибка?

Код МАСТЕРА

#include <avr/io.h>
#define F_CPU 16000000UL
#include <util/delay.h>
#define ACK 0x7E

void spi_init_master(void)
{
    DDRB = (1<<0)|(1<<1)|(1<<2);              //Set MOSI, SCK, SS as Output
    PORTB |= 1; 
    SPCR = (1<<SPE)|(1<<MSTR)|(1<<SPR0); //Enable SPI, Set as Master, Prescaler: Fosc/16
}

//Function to send and receive data
unsigned char spi_tranceiver(unsigned char data)
{
    PORTB &= ~(1<<0);
    SPDR = data;                       //Load data into the buffer
    while (!(SPSR & (1<<SPIF) ));       //Wait until transmission complete
    PORTB |= (1<<0);
    return (SPDR);                      //Return received data
}

int main(void)
{
    spi_init_master();                  //Initialize SPI Master
    
    unsigned char data;
    unsigned char ret;
    
    while (1) 
    {
        ret = spi_tranceiver(data);
    }
}

Код РАБА

#include <avr/io.h>
#define F_CPU 16000000UL
#include <util/delay.h>
#define ACK 0x7E

void spi_init_slave(void)
{
    DDRB = (1<<3);                                  //MISO as OUTPUT
    SPCR = (1<<SPE);                                //Enable SPI
}

//Function to send and receive data
unsigned char spi_tranceiver(unsigned char data)
{
    SPDR = data;                                  //Load data into buffer
    while (!(SPSR & (1<<SPIF) ));                  //Wait until transmission complete
    return (SPDR);                                 //Return received data
}


int main(void)
{
    spi_init_slave();                             //Initialize slave SPI
    unsigned char data;
    
    while (1) 
    {
        data = spi_tranceiver(ACK);
    }
}

1 Ответ

0 голосов
/ 14 августа 2020

Может проблема в перезагрузке регистра данных @SLAVE. В вашем коде это делается с помощью опроса. Поэтому, если у вас высокая тактовая частота, ведомое устройство не получает достаточно времени для правильной перезагрузки регистра.

Важное примечание:

Тактовая частота SPI должна быть F_CPU / 4 на slave (см. datasheet on page 168)

Попробуйте установить задержку на мастере. Итак, у ведомого есть время перезагрузить регистр:

#define F_CPU ?????????UL  // Clock speed of system in Hz

unsigned char spi_tranceiver(unsigned char data);

#include <util/delay.h>

int main(void)
{
    // ...
    
    while (1) 
    {
        ret = spi_tranceiver(data);
    }
}

unsigned char spi_tranceiver(unsigned char data)
{
    _delay_ms(10);
    PORTB &= ~(1<<SS);
    SPDR = data;
    while (!(SPSR & (1<<SPIF)));
    PORTB |= (1<<SS);
    return (SPDR);
}

Попробуйте запустить ведомое устройство до того, как будет запущено главное устройство!

...