pp.339ff.
「SPIで何かを読み出してみる / K型熱電対とMAX31855 (5V版) / MAX31855内部で線形変換した温度を読む -」で使った温度センサーから熱接点温度をMISOで受けてみる。
MAX31855はセレクトされればクロックに同期して勝手にデータを送り返してくれるが、AVR側のシフトレジスタを空ける必要があるためAVR側でダミーデータの転送処理をする。MOSIの配線はないので実際は何も転送されない。
氷に塩をまぶして氷点下の温度を得た。
#include <avr/io.h> #include <util/delay.h> extern "C" { #include "USART.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を有効化する。 /***********************************/ /* ためしにMISOで何かを受信してみる */ /***********************************/ initUSART(); int16_t sute; float temp; while(1){ PORTB &= ~(1 << PB2); // スレーブをセレクトして、 SPDR = 0x00; // 1バイトぶんのダミーデータを転送して、 loop_until_bit_is_set(SPSR, SPIF); // 転送処理の終わるのを待って、 sute = SPDR << 8; // 受信した8ビットを16ビットの上位にはめ込んで、 SPDR = 0x00; // また1バイトぶんのダミーデータを転送して、 loop_until_bit_is_set(SPSR, SPIF); // 転送処理の終わるのを待って、 sute |= SPDR; // 受信した8ビットを16ビットの下位にはめ込んで、 PORTB |= (1 << PB2); // スレーブセレクトを解除して、 sute &= 0xfffc; // 下位2ビットはここでは無関係なので消して、 temp = (float)sute / 16.0; // 摂氏に換算して、 printFloat(temp);printString("\n");// USART経由で表示する。 _delay_ms(500); } return 0; }