ブレッドボードの配線は、「AVRをI2Cスレーブとして使う スレーブからのデータ送信」と同じだが、今回はATMega328PではなくてATMega88Vを使っている。
AVRのI2Cのライブラリはいくつか公開されているようだが、テストなのでベタ書きでやってみた。
Atmel StudioのプロジェクトはGithubで公開しました。
https://github.com/ryood/Arduino_master_AVR_sleve/tree/master/Atmel%20Studio/I2C_Slave_Sender_Interrupt
<一部抜粋>
#define F_CPU 8000000UL // 8MHz
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
//TWI状態値
#define SR_SLA_ACK 0xA8 //SLA_R 受信チェック
#define SR_DATA_ACK 0xC0 //送信パケットチェック
#define SR_ENDP_ACK 0xA0 //終了orリピートチェック
volatile uint8_t sdata;
void twi_error(){
PORTB = 0x02;
while(1);
}
void twi_init(){
// 8MHz clk, bit rate 100kHz
TWBR = 2;
TWSR = 0x02;
//slave address
TWAR=0xfe;
// 割り込みを許可
TWCR = ((1<<TWEN) | (1<<TWEA) | (1<<TWIE) | (1<<TWINT)); // Enable TWI port, ACK, IRQ and clear interrupt flag
}
スレーブなのでI2Cのクロック設定は必要なのかどうなのかよくわからないが、I2Cのクロック(F_SCL)は
F_SCL = F_CPU/(16 + 2*TWBR*Prescaler)とTWBRレジスタとTWSRレジスタのプリスケーラで設定。I2Cのクロックはスタンダードで100kHzなので、AVRを1MHz駆動すると
TWBR*Prescaler = (F_CPU / 2*F_SCL) - 8 = (1MHz / 2*100kHz) - 8 = -3となってしまって設定できない。AtmelのI2Cのドキュメント「AVR311: Using the TWI module as I2C slave」(doc2565.pdf)の4Pを見ても、SCLを100kHzにするならCPUクロックは1.6MHz以上にしなさい、みたいなことが書いてある。
なのでFuse Bitを書き換えて内蔵RCの8MHz駆動にしてSCLを100kHzに設定した。
Fuse Bit: lFuse:0xE2 hFuse:0xDF eFuse:0x01I2C割り込みの有効化はTWCRのBITで
TWCR = ((1<<TWEN) | (1<<TWEA) | (1<<TWIE) | (1<<TWINT)); // Enable TWI port, ACK, IRQ and clear interrupt flagTWEN、TWEA、TWIE,TWINTに1をセットすると割り込みが有効化されるようだ。
ほんと全然良くわかっていない(^q^;
ISR (TWI_vect)
{
// 割り込みごとにLEDを点滅
PORTB ^= 0x02;
switch (TWSR & 0xF8) {
case SR_SLA_ACK:
TWDR = sdata;
break;
case SR_DATA_ACK:
break;
default:
twi_error();
}
TWCR |= (1<<TWINT); // Clear TWI interrupt flag
}
割り込みルーチンはかなりシンプル。TWSRレジスタの状態値はいろいろあるが、最低限っぽいこれ動いた。
TWCR |= (1<<TWINT); // Clear TWI interrupt flagTWINTは割り込み時の処理がひと通り終わったあとに1をセットするらしい。1をセットしてクリアしないと(ややこしい(^q^;)割り込みが続かない。
冒頭の
// 割り込みごとにLEDを点滅は割り込みがかかっているかどうかをLEDの点滅で確認するためのデバッグ用の処理だ。
PORTB ^= 0x02;
マスター側のArduinoのスケッチは、「AVRをI2Cスレーブとして使う スレーブからのデータ送信」と同じものです。
https://github.com/ryood/Arduino_master_AVR_sleve/tree/master/Arduino/master_reader
動いたからいいもののAVRのI2Cを把握するのはなかなか大変だ.。しんどい話やで(^q^;;;
0 件のコメント:
コメントを投稿