未だにシリアルサーボが動かせないでいろいろ試していました。うごいたりうごかなかったりするんだよなー。3byte送って3byte受信するから、その切り替えがうまくいっていないのかなーとか値を変えつつ送ってみるも、だめ。
そこで私は送ったデータと動作の可否をExcelに書いた。
あらやだ、ビットの数が性格に偶数でないと反応しないわ!
これはパリティのせいだと思うじゃないですか。
私はひたすらパリティをいじくった。
パリティの値を固定にしてオシロスコープを眺めてみたり、
パリティの値を反転させてみたり、
3byte目のパリティを2byte目のパリティをxorしてみたり、
毎回TX9をセットしてみたり、TX9Dをクリアしてから書き込んだり、
TXSTAを直接いじったり……・。どれも当然ながらうまくいかない。
私はUSBアダプタの信号外床が違うのかを知るためにオシロスコープを眺めた。
オシロスコープは信号の波形をしっかり記録してくれた。
図a : PICの送ったデータ
図b : USBアダプタが送ったデータ
ストップビットの長さが違っている。そこで次のようにして送信が全て完了するまで待機するようにした。
while(!TXIF);
TXREG = data;
while(!TRMT); // 送信が終わるまで待つ
TRMTは送信が全て完了したときに1になり、バッファが残っているときは0となるフラグである。TXIFはTXREGに格納できる状態の時に1, そうでなければ0となるフラグである。
TXIF, TRMT = 1のとき送信できるようにすればいいので、次のようにしてよい。
while(!(TXIF && TRMT));
TXREG = data;
受信は、送信が完了した後で有効にする必要がある。これはTXとRXを短絡しているためで、送信データを受信と見なさないようにするためである。
// 受信許可・送信不可
while(!TRMT); // 送信が全て終わるまで待つ
TXEN = 0;
CREN = 1;
for(i = 0; i < 3; i++) {
while(!RCIF);
// データの取得
g_response.data[i] = RCREG;
RCIF = 0;
}
CREN = 0;
最後に連続した3byteずつの動作を送信・受信の流れに振り分けるために
for(buff = i2c->buff, end_buff = buff + i2c->buff_size; buff < end_buff; buff += 3) {
sendSerialServoData(buff);
}
として無事動作した。めでたしめでたし。
ああ、雨が降っていて帰れない
追記
部室に置いてあった傘を借りました。今日返します。あとラベル付け忘れたので付けておきました。
0 件のコメント:
コメントを投稿