現状としては、TeraTermに値は送信されてくるのですが、同じ値ばかり送られてきてしまい、センサーに手をかざしたり、光を当てても変化が見られませんでした。
念のため、別の人にArduinoで確認してもらったところ、センサー自体は壊れていないそうです。
(じゃあその人に聞けば。と思うかも知れませんが、今取り組んでいる内容が、その人から課せられた課題のようなものでして、本人に聞くのはNGなのです。)
そのため、プログラム中での値の読み込み方に問題があるのだと思いますが、どこを直すべきなのかが分からず困っております。
(書き込み機はAVRISP mk2を使用、PCとの接続にはFT232RLを使用しています)
#include<avr/io.h>
#include<util/twi.h>
#include<util/delay.h>
typedef unsigned int byte;
static unsigned int i=0;
unsigned int red = 0;
/////////////////////////USART///////////////////////
byte getch(void){
while(!(UCSR0A & _BV(RXC0)));
return UDR0;
}
void putch(byte c)
{
while(!(UCSR0A & _BV(UDRE0)));
UDR0 = c;
}
/*USART通信初期化用関数*/
void usart_init(void){
UBRR0 = 25;
UCSR0A = 0b00100000;
UCSR0C = 0b00000110;
UCSR0B = 0b00011000;
}
/////////////////////////I2C///////////////////////
/*16進数1桁計算用関数*/
void puthex1(byte d){
d += '0';
if(d>'9') d+='a'-'9'-1;
putch(d);
}
/*16進数2桁計算用関数*/
void puthex2(byte d){
puthex1(d>>4);
puthex1(d & 0x0F);
}
/*結果計算用関数*/
void putdec2(byte x){
putch('0' + (x/1000)%10);
putch('0' + (x/100)%10);
putch('0' + (x/10)%10);
putch('0' + x%10);
}
/*エラー処理用関数*/
void i2c_error(void){
putch('[');
puthex2(TWSR);
putch(']');
putch(0x0d);
putch(0x0a);
while(1);
}
/*I2C初期化用関数(通信速度)*/
void i2c_init(void){
TWSR = 0x00; /*分周値=1*/
TWBR = 32; /*100k = 8MHz / (16+2*TWBR*分周値)*/
}
/*master側:1byte送信用関数*/
void i2c_write(byte d){
TWDR = d; /*送信データ*/
TWCR = _BV(TWINT) | _BV(TWEN); /**/
while(!(TWCR & _BV(TWINT))); /*データ送信完了まで待機*/
if((TWSR & TW_STATUS_MASK) != TW_MT_DATA_ACK) /*ACKを送れない場合*/
i2c_error();
}
/*master側:1byte受信用関数(+ack返信)*/
byte i2c_read_ack(void){
TWCR = _BV(TWINT) | _BV(TWEN) | _BV(TWEA);
while(!(TWCR & _BV(TWINT))); /*データ受信完了まで待機*/
if((TWSR & TW_STATUS_MASK) != TW_MR_DATA_ACK) /*ACKが返ってこない場合*/
i2c_error();
return TWDR; /*データを送り返す*/
}
/*master側:1byte受信用関数(+noack返信)*/
byte i2c_read_nak(void){
TWCR =_BV(TWINT) | _BV(TWEN);
while(!(TWCR & _BV(TWINT))); /*データ受信完了まで待機*/
if((TWSR & TW_STATUS_MASK) != TW_MR_DATA_NACK) /*NACKが返ってこない場合*/
i2c_error();
return TWDR; /*データを送り返す*/
}
/*master側:送信開始用関数*/
void i2c_start(byte id){
byte s;
/*開始条件送信*/
TWCR = _BV(TWINT) | _BV(TWSTA) | _BV(TWEN);
while(!(TWCR & _BV(TWINT))); /*開始条件の送信完了まで待機*/
s = TWSR & TW_STATUS_MASK;
if(s != TW_START && s != TW_REP_START) i2c_error();
/*アドレス送信*/
TWDR = id;
TWCR = _BV(TWINT) | _BV(TWEN);
while(!(TWCR & _BV(TWINT))); /*アドレスの送信完了まで待機*/
s = TWSR & TW_STATUS_MASK;
if(s != TW_MT_SLA_ACK && s != TW_MR_SLA_ACK) i2c_error();
}
/*master側:送信終了用関数*/
void i2c_stop(void){
TWCR = _BV(TWINT) | _BV(TWSTO) | _BV(TWEN);
while(!(TWCR & _BV(TWSTO))); /*送信終了になるまで待機*/
}
/*スレーブ(センサー)のアドレス設定*/
#define sensor (0x2A << 1)
int main(){
byte th, tl;
/*DDRD = 0x01;*/
/*PORTD = 0x00;*/
usart_init();
i2c_init();
/*センサーへの設定*/
i2c_start(sensor | TW_WRITE); /*センサーへのデータ書き込み*/
i2c_write(0x00); /*コントロールバイトを指定*/
i2c_write(0x84); /*ADCリセット*/
i2c_write(0b01010100); /*アドレス再設定*/
i2c_write(0x00); /*コントロールバイトを指定*/
i2c_write(0x04); /*ADCリセット解除*/
i2c_stop();
_delay_ms(2500); /*センサの計算終了まで待機*/
i2c_start(sensor | TW_WRITE);
i2c_write(0b01010100); /*アドレス再設定*/
i2c_write(0x03); /*出力データバイトを指定*/
i2c_write(0b01010101); /*リードモードに変更*/
i2c_stop();
while(1){
for(i=0;i<4;i++){
/*センサー値受信*/
i2c_start(sensor | TW_READ);
th = i2c_read_ack(); /*上位バイトを読み込み*/
tl = i2c_read_nak(); /*下位バイトを読み込み*/
i2c_stop();
_delay_ms(100); /*0.1s待機*/
/*結果出力*/
putdec2(th | tl>>8); /*結果計算(上位+下位)*/
//putdec2(red);
putch(',');
}
putch(0x0d); /*改行*/
putch(0x0a);
i=0;
}
}