Continue to Site

Welcome to

Welcome to our site! is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

Question on assembly programming of SPI for ATmega328


Full Member level 4
Sep 21, 2016
Reaction score
Trophy points
Activity points
I have questions and verification of the coding. Here is a copy of the relevant part from the datasheet of page 170 and 91.

1) Is DDR_SPI just a given name of Data Direction Reg DDRB with address 0x04(0x24) in p100? Just to make it easier to understand the program. There is NO real DDR_SPI register.

2)From DDRB for PortB shown, MOSI is bit3, SCK is bit5. Therefore in line 2 of code above, DD_MOSI = 3, DD_SCK=5.
meaning (1<<DD_MOSI)=0b00001000, (1<<DD_SCK)=0b00100000, AND (1<<DD_MOSI) | (1<<DD_SCK) = 0b00101000 in binary. is this correct?

3) If (2) above is correct, why do all the shifting? That waste a lot of time clocking and slow down the program. why can't I just write like this:
DD_MOSI = 0b00001000
DD_SCK = 0b00101000
ldi r17,(DD_MOSI) | (DD_SCK) ; Loading 0b00101000 into r17, same as with the shifting by save a lot of time.

I know I am wasting my time on this, BUT I just want to go deeper. I might be wrong, but I feel I learn more if I do this than just take a short cut go directly to C++ and use other people's sub routine.

You miss one important point: you don't run the program as you wrote it, you run the compiled version. The compiler itself makes the binary equivalent of the shifts and includes it in the binary executable as a single value. It's just much easier to understand the written version if register names or variable names are used instead of lots of '1's and '0's.
1) yes, as described. In assembly, don't use address (0x04), just use "DDRB"
2) yes,
3) no. It does not cost runtime processing power. It is shifted at compile time

To 2)
I don't recommend to use 0b00101000, also don't use "1<<3"
Better define "SCK_pin = 5",
And use
It's much more better to understand what this line of code does, even without comment.

When I write assembly code I don't care about real address, I always use the (register) names

Thanks for the replies. That really help. It is getting fun learning all these. I did not realize the shifting is done in compiling, not real time shifting.

I want to verify one more thing that there's a TYPO in the notes in post 1. Here is that particular part.


I just want to verify it should be PB3 and DDB3 in red, not PB5 and DDB5. as MOSI is BIT3 in PORTB.

This is in p171 of the datasheet.

I just want to verify it should be PB3 and DDB3 in red, not PB5 and DDB5. as MOSI is BIT3 in PORTB.
yes, after checking old datasheets and the latest one, that PB5 is just an example, the actual values for SPi in a 328 are:
PB2 - SS

LaTeX Commands Quick-Menu:

Similar threads

Part and Inventory Search

Welcome to