Problem with Atmel SPI initialization

Hi there, im trying to use my Micro OLED Sparkfun display (here is the datasheet https://cdn.sparkfun.com/assets/learn_tutorials/3/0/8/SSD1306.pdf) but i have a problem about code. Maybe is the problem in code because im working first time with SPI in Atmel so if would be somebody so nice and check it out, give me some advices about i will be so thankful.

Code is here

#define F_CPU 16000000
#include <avr/io.h>
#include <util/delay.h>

void SPI_MasterInit(void)
{
 /* Set MOSI and SCK output, all others input */
 DDRB = (1<<DDB3)|(1<<DDB5)|(1<<DDB1)|(1<<DDB2)|(1<<DDB0);
 PORTB |= (1<<PB2);
 /* Enable SPI, Master, set clock rate fck/16 */
 SPCR = (1<<SPE)|(1<<MSTR)|(1<<SPR0);
}
void SPI_MasterTransmit_Command(char cCommand)
{
 /* Set to command mode pin number 9 */
 PORTB &= ~(1<<PB1);
 /* Start transmission */
 SPDR = cCommand;
 /* Wait for transmission complete */
 while(!(SPSR & (1<<SPIF)));

}

 void SPI_MasterTransmit_Data(char cData)
 {
 /* Set to data mode pin number 9 */
 PORTB |=(1<<PB1);
 /* Start transmission */
 SPDR = cData;
 /* Wait for transmission complete */
 while(!(SPSR & (1<<SPIF)));
 }

 void Display_ON(void)
 {
 PORTB &= ~(1<<PB0);
 _delay_us(10);
 PORTB |= (1<<PB0);
 _delay_us(10);
 PORTB &= ~(1<<PB0);
 _delay_us(10);
 SPI_MasterTransmit_Command(0xAf);
 _delay_ms(200);
 }

int main(void)
{
    /* Replace with your application code */
    while (1)
    {
 SPI_MasterInit();
 Display_ON();
 SPI_MasterTransmit_Command(0xA5);
    }
}

What seems to be the problem?

problem is it doesnt work, so i dont know if is the initializing correct

As you are doing direct port manipulation, it is useful (for following logic and debugging) to assign meaningful names to ports and pins. Example.

#define DDR_SPI DDRB
#define DD_MOSI PB3
#define DD_SCK  PB5
#define DD_SS   PB1

Then you can make meaningful assignments such as,

DDR_SPI = (1 << DD_MOSI) | (1 << DD_SCK);

Also, to get rid of the annoying warning, change:

#ifndef F_CPU
#define F_CPU 16000000
#endif

You also seem to have SS designated as pin 9. Is this what you want?

For debugging as well, don't be so hasty in dispensing with all the IDE trappings. Change int main() to void setup(), add an empty void loop() (keep the compiler happy) and initialize Serial.begin(38400) so you have the luxury of debug printing until your issues are sorted. You think you can make these changes?

Post new code after.

so here is the new code, still same problem, display doesnt want to work

#define F_CPU 16000000
#include <avr/io.h>
#include <util/delay.h>
#define SCK DDB5
#define SDIN DDB3
#define D_C DDB0
#define CS DDB2
#define RST DDB1

void SPI_MasterInit(void)
{
	/* Set MOSI and SCK output, all others input */
	DDRB = (1<<SCK)|(1<<SDIN)|(1<<D_C)|(1<<CS)|(1<<RST);
	PORTB &= ~(1<<CS); 
	/* Enable SPI, Master, set clock rate fck/16 */
	SPCR = (1<<SPE)|(1<<MSTR)|(1<<SPR0);
}
void SPI_MasterTransmit_Command(char cCommand)
{
	/* Set to command mode pin number 9 */
	PORTB &= ~(1<<D_C); 
	/* Start transmission */
	SPDR = cCommand;
	/* Wait for transmission complete */
	while(!(SPSR & (1<<SPIF)));
	
}
	
	void SPI_MasterTransmit_Data(char cData)
	{
		/* Set to data mode pin number 9 */
		PORTB |=(1<<PB1);
		/* Start transmission */
		SPDR = cData;
		/* Wait for transmission complete */
		while(!(SPSR & (1<<SPIF)));
	}
	
	void Display_ON(void)
	{
		PORTB &= ~(1<<RST);
		_delay_us(10);
		PORTB |= (1<<RST);
		_delay_us(10);
		PORTB &= ~(1<<RST);
		_delay_us(10);
		SPI_MasterTransmit_Command(0xAF);
		_delay_ms(200);
	}
	
int main(void)
{
	SPI_MasterInit();
	Display_ON();
	
    while (1) 
    {	
		SPI_MasterTransmit_Command(0xA5);
    }
}

Some possible problems:

You are re-initializing the SPI interface each time through your while(1) loop.

You never call "Display_On() or SPI_MasterTransmit_Data().

You never set the Slave Select line back to HIGH to let the receiver know you have completed the transmission.

i call both functions in main and than it goes to the while loop,

See Figure 8-5 : Write procedure in 4-wire Serial interface mode

Where is the code to set CS back to HIGH when you are done sending the command byte?

It looks like the device uses Mode 3 so shouldn't you be setting the CPHA and CPOL bits of SPCR to 1.

Does the display work if you use one of the example sketches that uses the SPI library?

display is working with some demo code but with my code not, and here is my new code

 #define F_CPU 16000000
 #include <avr/io.h>
 #include <util/delay.h>
 #define SCK DDB5
 #define SDIN DDB3
 #define D_C DDB0
 #define CS DDB2
 #define RST DDB1

 void SPI_MasterInit(void)
 {
	 /* Set MOSI and SCK output, all others input */
	 DDRB = (1<<SCK)|(1<<SDIN)|(1<<D_C)|(1<<CS)|(1<<RST);
	 /* Enable SPI, Master, set clock rate fck/16 */
	 PORTB |= (1<<CS);
	 PORTB |= (1<<D_C);
	 SPCR = (1<<SPE)|(1<<MSTR)|(1<<SPR0)|(0<<DORD);
 }
 void SPI_MasterTransmit_Command(int cCommand)
 {
	 PORTB &= ~(1<<CS);
	 PORTB &= ~(1<<D_C);
	 _delay_ms(200);
	 /* Start transmission */
	 SPDR = cCommand;
	 /* set dc and cs low to send command */
	 /* Wait for transmission complete */
	 while(!(SPSR & (1<<SPIF)));
	 /* set dc cs high again */
	 PORTB |= (1<<CS);
	 PORTB |= (1<<D_C);
	 
	 
 }
 
 void Display_ON(void)
 {
	 PORTB &= ~(1<<RST);
	 _delay_ms(50);
	 PORTB |= (1<<RST);
	 _delay_ms(50);
	 PORTB &= ~(1<<RST);
	 _delay_ms(50);
	 SPI_MasterTransmit_Command(0xAF);
	 _delay_ms(200);
 }
 
 int main(void)
 {
	 SPI_MasterInit();
	 Display_ON();
     SPI_MasterTransmit_Command(0xA5);
	 
 }

and here is example hookup

I think you should study the SparkFun library to see how they do things:

For example, they do a LOT more setup than just sending "DISPLAYON":

 // Display Init sequence for 64x48 OLED module
 	command(DISPLAYOFF);			// 0xAE

	command(SETDISPLAYCLOCKDIV);	// 0xD5
	command(0x80);					// the suggested ratio 0x80

	command(SETMULTIPLEX);			// 0xA8
	command(0x2F);

	command(SETDISPLAYOFFSET);		// 0xD3
	command(0x0);					// no offset

	command(SETSTARTLINE | 0x0);	// line #0

	command(CHARGEPUMP);			// enable charge pump
	command(0x14);

	command(NORMALDISPLAY);			// 0xA6
	command(DISPLAYALLONRESUME);	// 0xA4

	command(SEGREMAP | 0x1);
	command(COMSCANDEC);

	command(SETCOMPINS);			// 0xDA
	command(0x12);

	command(SETCONTRAST);			// 0x81
	command(0x8F);

	command(SETPRECHARGE);			// 0xd9
	command(0xF1);

	command(SETVCOMDESELECT);		// 0xDB
        command(0x40);

 command(DISPLAYON); //--turn on oled panel