I have spent quite a few hours trying to set the SPI interface for the ATMEGA324A.

I wrote the code following the example on the data sheet and by reading other threads on this forum. Unfortunately, I wasn't able to make it work.
I am new to Atmel chips, but I have SPI programming experience with other microcontrollers, so this is becoming frustrating.

I am programming the microcontroller using Atmel studio 7.0 and the STK 500. The SPI is not connected to any chip for now.

I notice the SCK signal is not coming out from PortB.

To check if the code is running, I am also using PortC to turn on and off some LEDs, and this works fine.

Below is the code. Hope some of you can help me understand what I do wrong.

At that point it does become an output (good, it's the best solution to avoid the usual AVR SPI "gotcha"!) and the previous line has now ensured it is high.

But it's only in MasterTransmit but not in ReadByte that you then control it? So for the read it is going to be high and hence the device is not selected.

Also have you noticed how similar Read and Transmit actually are? That's because with SPI you always do the same thing (send one byte, receive another) so you might as well just have one common routine anyway:

Then use this for (a) transmit (ignore the return) (b) receive (just send 0xFF if nothing better to send) or (c) both

Anyway, the lack of SCK - you haven't got your ISP programmer still connected by any chance? I've noticed this in the past with STK500 where it "holds" the lines. Just remove the cable from the ISP6PIN header and see what happens.

From what your wrote I understand my code is fairly correct and should work properly, right?

I tried to remove the ISP6PIN, but I can't still see any message and clock coming out of the SPI port of the chip. I didn't modify the functions to SPIExchange yet, but the program as it is now should at least be able to transmit data. Unfortunately, it doesn't. :(

Also have you noticed how similar Read and Transmit actually are? That's because with SPI you always do the same thing (send one byte, receive another) so you might as well just have one common routine anyway:

I tend to disagree. If you want to make a general SPI send/receive primitive, that IMO is no place to fuss with chip-select. It would be very rare to have nothing but single-byte send/receive transactions.

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

I am verifying the operations with a scope. And using the LEDs on the STK500 (PortD connected to LEDs) to check if any signal is coming out. Attached is a picture of the setup, as you can see, only LED7 is on corresponding to the SCK that is therefore a constant signal (high).

Before Arduino was invented, LEDs were typically active-low. It is the most natural way from an electrical point of view.
.
No disrespect to Arduino users. Humans in general are happier with positive logic. I certainly feel more comfortable from a software design perspective. It just means that you use XOR to invert for active-low hardware pins.
.
Likewise, active-low buttons are better from an electrical perspective. I read a PINx register and invert bits with XOR.
.
David.

Could you please post what your found for the sake of others who read this thread at a later time?

I was making 2 big (and stupid) mistakes:

1. I was running the chip with a very fast clock, so I could not really see the LEDs turning on and off at that rate. To many they seemed off all the time, but they were actually flickering. Reducing the clock speed with this command by David, helped.

It is easy to search for activity with the Saleae Logic Analyser software. I doubt if a scope can search.
I have got a bit further with PulseView but it crashes my PC. And it does not seem to navigate as conveniently as Saleae Logic.
.
David.

Am I doing something wrong by using that SPI_trasnfer(0x00) to read the second half of the data coming from the ADC?

Nope, that's a standard technique - some people call values like 0x00 "stuffing bytes" as they are just dummy/rubbish bytes who's value does not matter but that are simply used to trigger the further transfer of more 8 bit parts of the thing to be read.

Also, I am trying to read the MISO data on the scope, but they are not always the same, even if the input analog voltage is constant (maybe because of the added noise).
How can I display a numerical value. I guess just writing printf() in main() would not be enough.

How could the receiving end know that you were about to send "CH0" and to have already pre-loaded the first half of that result? The usual sequence is transfer_byte(command to say what you want), then N times part_result=transfer_byte(something to prompt the transfer).

But the device you are connecting to must surely have a datasheet - I imagine it tells you the write/read sequences for the various commands it supports?