Search code examples
avrspi

avr SPI transfer function only works once


u8 SPI_transfer(u8 copy_u8Reciever)
{
    SPDR=copy_u8Reciever;
    while (GET_BIT(SPSR,7)==0);
    return SPDR;

I can only use the function once , in the second time it goes on an infinite loop , it is weird because I used this code before and it worked very well , now the code is stuck in this while loop


Solution

  • To check if SPI is working correctly use an oszilloscope or make a loopback if there are some buttons and leds on your board.

    Possible configuration issues:

    • controller is not in master mode
    • SPI Clock is to high
    • wrong polarity/phase of SCK and MOSI
    • problems with SS
    • SCK, MOSI and SS are not configured as output

    Loopback (Connect MOSI with MISO):

    unsigned char spi_init()
    {
        // ...
    
        // Setup SCK, MOSI and SS as output
        // PORT configuration gets overwritten from SPI controller
        SPI_DDR  |= (1<<SPI_SCK) | (1<<SPI_MISO) | (1<<SPI_MOSI) | (1<<SPI_SS);
        
        // Check if master abort has occurred
        if(!(SPCR & (1<<MSTR)))
            return 0xFF;    // Return master abort
        return 0x00;        // Return no fault
    }
    
    
    unsigned char spi_transfer(unsigned char data)
    {
        SPDR = data; 
        while(!(SPSR & (1<<SPIF)));
        
        return SPDR;    // Return received data from the bus
    }
    
    int main()
    {
       // Define some output if possible
       DDRC = 0xFF;
    
       spi_init();
    
       while()
       {
           // Write some input to output
           PORTC = spi_transfer(PINA);
       }
    }