0
\$\begingroup\$

I just started learning this. I have a few questions I want to clarify. Here is the red lined copy of the relevant part for my questions. enter image description here

  1. What port and bit to write to enable SPI? I never really get how to go to Alternate functions of ports.
  2. It said DDR_SPI be replaced by actual Data Direction Reg. Is that DDRB?
  3. Is SPI pin PB2 bit that named /SS? Which is SELECT?
  4. MOSI is bit3 in PORTB this means DD_MOSI=3 so (1<<DD_MOS) = 0b00001000?
  5. If #4 is correct, WHY go through shifting, just use 0b00001000, forget shifting.
  6. Is DD_MOSI=03, DD_MISO=4, DD_SCK=5 in the program?
  7. Looking at SPI control reg SPCR, is: SPE=6, MSTR=4, SPRO=0?
  8. If my guess is correct, why going through LEFT SHIFTING?

Thanks for your patience

\$\endgroup\$

1 Answer 1

0
\$\begingroup\$

This is what I get, maybe slightly inaccurate, but the manual can explain best when you have the clue I am giving here.

  1. It seems, looking at your code fragment, that to enable SPI, the register SPCR is written to. SPCR should mean (Serial Peripheral [Interface] Control Register) SPE should mean SP enable MSTR should mean master SPRO don't know

  2. Once SPI is enabled, DDR_SPI overrides DDRB, it seems. So DDR_SPI has to be set beforehand, as done in the code fragment.

  3. SS negated is Slave Select. It is used when the SPI interface is programmed as a slave.

  4. Yes. "1 << DD_MOSI" is the b3 in a byte. They use this to make MOSI (Master Out Slave In) an output, along with SCK (clock), using DD_SCK.

  5. #4 is correct, and they use this notation to make it clear that they are raising TWO bits (b3 & b5). But forget the numbers, use the mnemonics (DD_MOSI & alike). They could have used a mask, like you say (but your mask is wrong - too many "0" and one less "1"

6 & 7) Probably yes, but the manual clarify that much better than you or me.

  1. Left shifting because this is easy: you say bit 3, and you use "1 << 3" to create a mask for it. The other way would be possible: "0x80 >> 1" to indicate bit 6, but it looks horrible! Or you can use a mask "0b00001000" to define DD_MOSI (which I would prefer, like you), but you should stick to what the Atmel people did for us.

Don't worry too much... after you get aquainted with MCU hardware manuals, you will find that things are well explained and not too difficult to understand. You seem to know bits manipulation, and all boils down to that.

==== UPDATE after comment =====

The code fragment SPI_MasterInit cited in the question is a sort of pseudo code. I've found it at page 37 of the ATMega328P, and just above the example the manual states:

DDR_SPI in the examples must be replaced by the actual DDR register... DD_MOSI, DD_MISO ... must be replaced ...

So, there is no register named DDR_SPI and no DD_MOSI and alike. One must set explicitly DDRB (in this case) doing something like

ldi r17, (1 << 3) | (1 << 5)    ; ...or equivalent...
out DDRB, r17

About using a pin as a simple I/O pin, yes - one must be sure that no peripheral using that pin is enabled. Maybe some peripheral can use that pin optionally, i.e. only if some particular feature is enabled. In this case, the SS pin works this way. The manual says that if the SPI peripheral is programmed as a Master, the SS pin is left alone (general purpose I/O) - but if the SPI peripheral is configured as Slave, the SS pin is forced to be an input.

\$\endgroup\$
4
  • \$\begingroup\$ Thanks so much Monica. I wrote all my questions in the original post as I cannot even hit return in the reply post. Now I am going a little deeper. I question (1), from your answer, The enable any ALTERNATE function of the PORTS( like ADC, SPI, COUNTER, INTERRUPT), I just go to the particular register to enable the function, that will over ride the PORT. In another words, if I want to use the PORTS as simple digital in/out port, I have to make sure I DISABLE ALL the alternate functions? \$\endgroup\$
    – Alan0354
    Commented Jul 30, 2023 at 7:08
  • \$\begingroup\$ Hi Monica, on your reply #2, Where is DDR_SPI register? I search through the whole datasheet, I can't find the register name DDR_SPI. Thanks \$\endgroup\$
    – Alan0354
    Commented Jul 30, 2023 at 8:47
  • \$\begingroup\$ I've update my answer, hope it helps. I took a look (not very deeply) to the manual, sorry for not having done so before. It seems you are on the good way! Aside: my nickname is Linuxfan, not Monica! \$\endgroup\$ Commented Jul 31, 2023 at 4:46
  • \$\begingroup\$ Thanks Monica, sorry for the late reply. \$\endgroup\$
    – Alan0354
    Commented Aug 1, 2023 at 4:57

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.