AVRのSPIモジュール / MOSIからとにかく何かを出してみる

pp.339ff.

#include <avr/io.h>
#include <util/delay.h>

int main(){
    DDRB  |= (1 << PB2); // PB2を!SS端子(OUT)として使う。
    PORTB |= (1 << PB2); // 最初はスレーブセレクトを解除しておく(Hを出力しておく)。
    DDRB  |= (1 << PB3); // PB3をMOSI端子(OUT)として使う。
    PORTB |= (1 << PB4); // PB4をMISO端子(IN)として使う。内部プルアップしておく。
    DDRB  |= (1 << PB5); // PB5をSCK端子(OUT)として使う。

    //SPCR &= ~(1 << CPOL | 1 << CPHA);           // mode(0,0)。デフォルト。CPOL、CPHAのCはclock。
    //SPCR &= ~(1 << CPOL); SPCR |=  (1 << CPHA); // mode(0,1)
    //SPCR |=  (1 << CPOL); SPCR &= ~(1 << CPHA); // mode(1,0)
    //SPCR |=  (1 << CPOL | 1 << CPHA);           // mode(1,1)

    //SPCR &= ~(1 << DORD); // MSBファーストで転送する。デフォルト。
    //SPCR |=  (1 << DORD); // LSBファーストで転送する。

    SPCR |= (1 << SPR1 | 1 << SPR0); // SPIのクロック周波数。ここでは8MHzを128分周した(62.5kHz)。SPRのRはRate。
    SPCR |= (1 << MSTR);             // AVRをマスターにする。
    SPCR |= (1 << SPE);              // SPIを有効化する。

    /************************************/
    /* ためしにMOSIから何かを出してみる */
    /************************************/
    while(1){
        PORTB &= ~(1 << PB2);              // スレーブをセレクトして、(何もつないでいないので実際は何もセレクトされない)
        SPDR = 0b10101010;                 // 何かをMOSIから出して、
        loop_until_bit_is_set(SPSR, SPIF); // 転送終了時にSPSR (SPI Status Register)のSPIF (SPI Interrupt Flag、bit[7])が立つのでそれまで待って、
        PORTB |= (1 << PB2);               // スレーブセレクトを解除する。
        _delay_ms(10);
    }
  
    return 0;
}

f:id:ti-nspire:20200108145702p:plain
f:id:ti-nspire:20200108150150j:plain:w500