PIC×PICCによるシリアル通信(5)

(前回の続き)


秋月のPICライターが壊れてしまって、どうしようかとあれこれしていたが、よく見たらDSUBケーブルが抜けかかっていた。(これに気づくのに30分ぐらいかかった)


これをしっかり差し込とPICライター自体は壊れておらず古いPICライターのソフトで書き込みは出来るようだったが、firmwareは依然としてupdate出来ない。


まあいい、先に進もう。どこまで実行されているのか確認するためにあちこちにRB5 = 1;だとかRB6 = 1;だとか書いていたが、どこも挙動がおかしい。どうしてかと思ってコンパイル後のファイルを見るとソースの変更箇所がコンパイルされていない。

usart16f877a.h(104):
RB6 = 1; RB3=1;
TXREG = usart_sendData[usart_send_read++ & 0x1f];// 送信バッファのデータを送信

ソースにこう書いてあるのにコンパイル後の .lst を見ると

214 ;usart16f877a.h: 103: {
215 019B 1706 bsf 6,6
216 019C 1586 bsf 6,3
217 ;usart16f877a.h: 105: TXREG = usart_sendData[us<<

104行目がコンパイルされていない。まさかと思ってproject viewを確認するとこのheaderはprojectに追加されていなかった。


File→Openではprojectに追加されないのか。これは私が悪いと言えば悪いのだが、Fileメニューには「Add New File to Project」(新しくファイルを作成してそれをprojectに追加する)という項目がある。この真下にあるもんだから、当然、こちらはOpenしてプロジェクトに追加するの意味かと思った。



「Add New File to Project」がFileのところにあるのがおかしく、これはProjectのところにあるべきだ。しかもProjectのところにはOpenという項目があるが、こちらはプロジェクトへ追加するファイルのopenではない。プロジェクトそのもののopenである。


プロジェクトへのファイルの追加は、project viewからしか行なえない。project viewが邪魔なので消して作業していたので追加の仕方がわからず、てっきりFile→Openがプロジェクトへの追加だと思ってしまった。私がしっかり確認しないのが悪いのだろうけど、MPLAB IDEを作ってる奴は、正直頭がおかしいんじゃないかと思った。


「秋月のPICライターで焼いてはテスト基板に刺す」の繰り返しで、PICのピンがよれよれだ。「もう僕これ以上頑張れない」とか「ゴールしていいよね?」とか聞こえてきそうだ。俺にもいい加減ゴールさせてくれい。



AVRのシリアル通信のテストのために作ったFT232RLモジュール基板。
いまとなっては、AVRのプログラムをやっていた日々が懐かしい!(つい2日前だが)


感慨にふけっていても仕方ないのでいつぞや買ったICD2のclone(http://d.hatena.ne.jp/yaneurao/20080229)を物置から持ち出してきた。


こいつでデバッグすれば速攻だろうと思い、MPLAB付属のICD2用のドライバをインストールした。



Programmer(プログラムをPICに書き込む機能)とDebuggerが別々の機能でいちいち切り替えなければならない。なんというひどい設計なんだ…と思いつつ、Debuggerとして起動するが、デバッグモードに入れない。

調べててもよくわからないので、ICD2.5でデバッグするのは保留にして、ICD2.5でPICにプログラムを書き込むことにした。16F877Aだけではなく、16F887(秋月で250円)にも書き込めるようだ。何のために16F877Aをターゲットにしたのかわからなくなった。


ICD2.5は秋月のライタとは違い、ものの数秒で書き込みが完了する。これならすぐにデバッグが終わりそうだ…と思ったが、なかなか手間がかかる。


どうやら割り込みルーチンに飛んできていない。割り込みルーチンはinterrupt修飾子をつけて書く。関数名は何でも良い。すべての割り込みはここに飛んでくるという大雑把な仕様となっている。

// 送受信のための割り込みハンドラ
void interrupt serial_isr(void)

ここに飛んできたら、割り込み要因によって場合分けをして、その割り込み要因を解決しなければならない。

TXEN = 1; // シリアル送信許可
TXIE = 1; // 送信割り込み許可
ei(); // 全割り込み許可

とここまで設定して、何故割り込みハンドラが全く呼ばれないのかわからない。PICの足はいまにも折れそうである。私の心もそろそろ折れそうだ。


そう言えば、MPLABにシミュレーション機能があったなぁと思い、これがPICCに対しても使えるかなと思いやってみた。



確かに使えた。このシミュレータは高機能で、USARTへの出力を画面に表示したり、USARTへの入力をファイルから与えたりすることが出来る。PICCで書いてあるソースの変数のwatchも出来るようだ。


ただ、includeしたheaderにはbreak pointは設定できないようだ。なんとも面倒くさいなぁ(´ω`) このシミュレータを使いたいなら、 .h と .c はわけるようにしよう。


それで、割り込みがかからない原因だが、タイマー割り込みを設定してみるとこの割り込みハンドラが呼び出された。PIC16シリーズは、割り込みがかかると4番地に飛んでくるので、PICCのコード生成がおかしくて割り込みハンドラが正しく設定されていないというような可能性はこれで消えた。


つまり、呼び出すための割り込み設定が足りないのである。データシートを読み直したら、PEIEも1にしなければ送受信関係の割り込みは機能しないことがわかった。おいおい、たかが送受信割り込みのために何個レジスタを設定させるんだい…。


PEIE = 1; を追加すると無事割り込みハンドラには飛んでくるようになった。割り込み要因がTXIF(送信レジスタ空きフラグ)==1なのだが、このフラグが立っているからと言って、送信完了とは限らない。ただのタイマ割り込みかも知れない。正しくdispatchする処理を書くだけでも大変である。これというのもすべての割り込みが4番地に飛んで来るというとんでもない仕様によるものだ。


そこでTXIE(送信割り込み許可)をdispatchのためのフラグとして使い、TXIE & TXIFなら、割り込み要因を送信完了によるものとみなして、自前で用意している送信bufferにデータがなければ、TXIE = 0; にする。


これですべてがうまく動いた。たったこれだけのことを調べるのに丸1日以上かかった。(ソースは明日のエントリに掲載)