処理としては、
AVR(Slave)→Arduino(Master)
AVRからタクトスイッチの押し下げ状態を含めた8Byteのデータを送信。Arduinoは受け取ったデータをSerial通信でパソコンに送る。
Arduino(Maseter)→AVR(Slave)
Arduinoから0..7の範囲でインクリメントした1Byteデータを送信。AVRは受け取ったデータの位置にあるLEDを点灯(LEDの点灯が流れる)。同時にタクトスイッチの押し下げ状態をORしてLEDを点灯。
AVRで使用したTWIのステータスコードは
// TWI ステータスコード
// Rx
#define TWI_SLA_W_ACK 0x60
#define TWI_RX_DATA_ACK 0x80
#define TWI_RX_STOP 0xA0
// Tx
#define TWI_SLA_R_ACK 0xA8
#define TWI_TX_DATA_ACK 0xB8
#define TWI_TX_DATA_NACK 0xC0
AVRはスレーブだがRX(受信)、TX(送信)両方の動作をする。I2C通信の開始時にマスターから送られる最初のI2Cアドレスの次のW/Rビットを見てRX、TXの処理に入る。
データの送受信の処理はTWI割り込みルーチン内でTWIステータスコードでSwitch文で処理した。
switch (TWSR & 0xF8) {
// Slave TX
case TWI_SLA_R_ACK:
TXdata_n = 0;
case TWI_TX_DATA_ACK:
TWDR = TXdata[TXdata_n++];
break;
case TWI_TX_DATA_NACK:
break;
// Slave RX
case TWI_SLA_W_ACK:
break;
case TWI_RX_DATA_ACK:
RXdata = TWDR;
break;
case TWI_RX_STOP:
break;
default:
twi_error(0x55);
}
ほんとはRXモードのときにTX用のステータスコードを受け取った場合などの例外処理をしないといけないと思うが、かなりめんどくさそうなので今回は端折った。
のちのち禍根を残すことになるかもしれないが(^q^;
Atmel Studioのプロジェクト
https://github.com/ryood/Arduino_master_AVR_sleve/tree/master/Atmel%20Studio/I2C_Slave_Rx_Tx_ATMega88V_Byte_Sequence_Interrupt
Arduinoのスケッチ
https://github.com/ryood/Arduino_master_AVR_sleve/tree/master/Arduino/master_tx_rx
0 件のコメント:
コメントを投稿