Search code examples
arduinospiatmegaatmelice

SPI not working on atmega328p


I'm trying to program an atmega328p, but the SPI bus isn't working. It's not sending any data over the bus.

My code is as follows:

#include <asf.h>
#include <stdio.h>
#include <main.h>

int main (void)
{
    board_init();
    SPI_MasterInit();

    DDRD = (1<<DDD5);

    while(1)
    {
        PORTB &= ~(1<<DDB2);
        SPI_MasterTransmit(0xAB);
        PORTB |= (1<<DDB2);

        PORTD ^= (1<<DDD5);
    }
}

void SPI_MasterInit(void)
{
    /* Set MOSI and SCK output, all others input */
    DDRB = (1<<5) || (1<<3) || (1<<2);
    /* Enable SPI, Master, set clock rate fck/16 */
    SPCR = (1<<SPE)|(1<<MSTR)|(1<<SPR0);
}

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

I'm trying to send some random data over the bus (0xAB) to check if the bus works properly so I can add further code. In the while loop I also set a pin.

On my scope image I see no data being send on the SPI pin MOSI and the CLK pin is also not sending information. PB5 (the pin I'm inverting everytime I try to send data) is working and has a period of about 20 microseconds.

I'm programming the Atmega328p through an Atmel ICE. The programming interface is also through SPI, I read somewhere that this might be an issue. I'm not completely sure.

Does anyone know what might be the problem?


Solution

  • My first guess was not setting SS pin (PB2) as output. It may cause switching to the slave mode almost randomly. But it seems to be set as an output (it's not stated in comments).

    But after closer look to this expression, it's obvious it's not set at all:

    DDRB = (1<<5) || (1<<3) || (1<<2);
    

    There is a huge difference between logical or || and bitwise or |.