PIC×PICCによるシリアル通信(4)
(前回の続き)
PICのアーキテクチャはとてもややこしい。この手のハードに不慣れな私は、いろいろ惑わされる。
例えば、ボーレートの設定。AVRではクロックをボーレートで割ったあと16で分周した値の上位、下位8bitずつをUBRRH,UBRRLに書き込むだけで良かった。
PICの上位機種はそれに近い形になっているのだが、16Fシリーズはそう簡単じゃない。
条件 BRGHビット=0 BRGHビット=1
SYNCビット=0 通信速度=Fosc/(64(X+1)) 通信速度=Fosc/(16(X+1))
SYNCビット=1 通信速度=Fosc/(4(X+1)) なしFoscはPICのクロック周波数(Hz)です。
X はSPBRGレジスタの値で0から255の値です。PIC16F873の非同期通信(USART)
http://www.interq.or.jp/japan/se-inoue/pic7_7.htm
こうなっている。右上の式でSPBRGを求めるなら、Xについて解けばX=Fosc/16/baudrate-1となりAVRの時と同じである。何故か、このBRGH=1のモードを「高速ボーレートモード」と呼ぶことになっている。
何をもって高速とするのかよくわからない。低いボーレートに対してこの式を適用するとSPBRGが8bitしかないのであふれてしまうから、SPBRGが8bitを超えそうなときはさらに4で割った値を設定しよう、というのが低速モード(BRGH=0,SYNC=0)の発想である。
このことに気づかずに低いボーレートだからBRGH=0の式を適用しようとすると64で割るため有効桁が少なくなりすぎて精度が悪くなる。
そう考えると「高速ボーレートモード」は高速なボーレート用のモードではないと思うのでこんな紛らわしい名前をつけるのは勘弁して欲しいものがある。
さて、私の移植したコンパイルは通ったものの送信も受信も出来ていない。この手の移植は、私の場合、コンパイルさえ通れば(ロジック上のミスはあまり起こりえないので)一発で動くのが普通なのだが。
ひょっとしてPIC16Fシリーズでは1word = 14bitだから、int型が14bitとか言うこともありえるのか?と思って念のため確認すると…。
PICCの基本データ型を下記の表に示します。char,short,int,longの各整数型は、基本的には符号付ですが、修飾子のsignedやunsignedをデータ型の前に付与し、符号付か否かを明示的に指定できます。
ええと、charが8bitで、short,intが16、longが32、float,doubleが24bit or 32bitのようだ。1word = 14bitの変態アーキテクチャに実装したにしては頑張ってると思う。doubleよりlongのほうが精度が高いのは少し違和感があるが、まあ良しとしよう。
では何故動かないのだ?嫌な予感がして、usart.h側の初期化部分の先頭で RB4 = 1; などとしてプログラムを書き込み、テスタで読み取ってみたが1が出力されていない。
まずは動くとわかっているソースを持ってきてコンパイルしようと思い、LEDを点滅させるだけのサンプルを人様のページからコピペしてきたら、DelayMsという関数が無い。
探してみたら、
C:\Program Files\HI-TECH Software\PICC\LITE\9.60\samples\delay
こんなところに入っている。頼むから、こんな大事なものはincludeフォルダに入れておいてくれ…。
しかもそのページには周波数の設定を変更するために、delay.hとdelay.cを自分のprojectフォルダにコピーしてきてそれを書き換えて使いなさいとか書いてある。さすがにそんなことはしたくないので、
#define XTAL_FREQ F_CPU
#include "../samples/delay/delay.h"
として、samples/delay/delay.cはプロジェクトに追加することにした。これなら、delay.hとdelay.cには手を加えなくて済む。(またDelayMs,DelayUsの引数には256以上は指定できないようなので注意が必要だ。)
それでもやはり動かない。PICライターやPICが壊れているのかと思ったが、PICライターからはverifyに成功しているのでPICライターやPICが壊れたということは考えにくい。
ひょっとして、ごちゃごちゃリンクしているのが悪いのかと思ってmain関数の中身は
for(;;)
{
TRISB = 0;
PORTB = 0xff;
}
とだけ書いたプログラムにしてみたが動かない。
TRISは0が出力なので、ひょっとして全port、defaultでは出力だったんじゃないかと思って、TRISA〜Eまで0xffで初期化してみたが、一向に改善しない。(初期状態ではTRISBは0xffで初期化されていて、defaultでは入力っぽい)
検索してたらPIC Cはbank切り替えをするコードをときどき出力しないというとんでもないバグがあるのを知って愕然とする。だけど去年の情報だから、さすがにもうなおってるだろう。(実際、なおってる。心配はいらない。)
あれ?と思ってGND,Vccを測定してみたら0V。おやおや、FT232RLモジュールが壊れたのか?と思ったらテスタのプローブが差し込み口から抜けていた。
テスターでやっとPORTB-GND間は5Vであることが確認できた。
これでやっとスタート地点に立てた。いたるところに RB4 = 1;や RB5 = 1;などと埋め込み、どこまでは正しく実行されているのかを調べていくことにする。
秋月のPICライターではヒューズビット(PICではコンフィギュレーションビットと呼ぶのか?)をhexファイルをloadするごとに手動で設定しなおさなければならない。PIC Cのほうでは
__CONFIG(UNPROTECT & PWRTEN & XT );
と書いて、ヒューズビットの設定をしているはずなのに…。
秋月のPICライターをversion upすればひょっとして改善されるかと思って、確認したら秋月のPICライターのソフトは2008/6/22に更新されている。downloadしてきたところfirmwareのバージョンも最新のものにするように表示されたのでfirmwareを更新しようとしたら、通信エラーになってPICライターがお亡くなりになった。
(つづく)