仕様は複雑ですが、ArduinoのexampleにはWire/master_readerというマスター側が受信するサンプルプログラムがあるし、AVR側のSlaveプログラムも読み取るレジスタの値を多少いじれば大丈夫そうなのでやってみました。
配線図
タクトスイッチが並んでる基板は、スイッチの押し下げで信号線がGNDに落ちる仕様です。
ArduinoとAVRの両方にプログラムを書き込まないといけないので、常にどちらかのUSBを引っこ抜いて実験しました。
※AVRのRESETピン(ピン1)がArduinoからの制御とAVRプログラマーの制御が干渉するのでちょっとハマってしまいました(^q^;
Arduinoをマスター/受信で使う
Wire/master_readerを元に多少改変しました。
#include <Wire.h> #include <stdio.h> void setup() { Wire.begin(); // join i2c bus (address optional for master) Serial.begin(9600); // start serial for output } void loop() { Wire.requestFrom(0x7f, 1); // request 1 bytes from slave device 0x7f while (Wire.available()) // slave may send less than requested { int x = Wire.read(); // receive a byte as character Serial.println(x); // print the character } delay(500); }
Wire.requestFrom()でスレーブのアドレスと読み込むバイト数を指定するので、アドレスの「0x7f」と「1」バイトを指定。
シリアル通信の出力は読み込んだバイトをそのまま10進数で出力するようにしました。タクトスイッチの押し方の組み合わせで2進→10進変換器みたいな感じになります。
AVRをスレーブ/送信で使う
前回の「スレーブ/受信」のプログラムから改変したところをかいつまんで
状態値の定義部
//状態値
//#define SR_SLA_ACK 0x60 //SLA_W 受信チェック
#define SR_SLA_ACK 0xA8 //SLA_R 受信チェック
//#define SR_DATA_ACK 0x80 //受信パケットチェック
#define SR_DATA_ACK 0xC0 //送信パケットチェック
#define SR_ENDP_ACK 0xA0 //終了orリピートチェック
I2Cの通信が終了した時、TWSR(TWIステータスレジスタ)に状態値がセットされていますが、アドレスを受け取ってACKを返した時、R/WがRの時(スレーブがマスターにデータを送信するモード)0xA8がセットされるので「SR_SLA_ACK」を0xA8と定義しました。
同様にデータ送信終了時はCxC0がセットされるので「SR_DATA_ACK」も変更しました。
データを送信する関数
void twi_send(uint8_t sdata){
TWCR = (1<<TWINT) | (1<<TWEA) | (1<<TWEN);
// Wait for TWINT Flag set.
while( !( TWCR & (1<<TWINT) ) );
if( (TWSR & 0xF8 ) != SR_SLA_ACK )
twi_error();
// データを送信
TWDR = sdata;
TWCR = (1<<TWINT) | (1<<TWEA) | (1<<TWEN );
// Wait for TWINT Flag set.
while( ! ( TWCR & ( 1<<TWINT ) ) );
if((TWSR & 0xF8 ) != SR_DATA_ACK)
twi_error();
}
ここは受信時とは手順が違うので、まあこうなったということで(^q^;
ソース等はGithubで公開しています。
https://github.com/ryood/Arduino_master_AVR_sleve
Arduino: master/send、AVR: slave/recieveのときは
Arduino/I2C_master_writer
AtmelStudio/I2C_Slave/Reciever
Arduino: master/recieve、AVR: slave/sendのときは
Arduino/master_reader
AtmelStudio/I2C_Slave/Sender
を使います。
0 件のコメント:
コメントを投稿