標準TTLだけ(!)でCPUをつくろう!(組立てキットです!)
(ホントは74HC、CMOSなんだけど…)
[第411回]
明けましておめでとうございます。
本年もよろしくお願いいたします。
本日は2日です。たまにはリセットして脳細胞をリフレッシュさせるためにも、お正月くらいはのんびりしなければ、ということで、一杯やりながらヒッチコックの名作でも見て過ごそうかとか、いやいやそれもいいけれど、やっぱりマリリンモンローも捨てがたいなあとか、うう、ジョンウェインもいいし、スチーブマックィーンもいいし、むむ、そんなことを言っていると、ああ、オードリーヘップバーンとかイングリッドバーグマンまで見たくなってしまって、だめだ、どれから先に見ようか迷ってしまう…。
で。まあ、とりあえず、パソコンをONにして、前回のところを読み直しておりましたら(なんでオードリーヘップバーンとイングリッドバーグマンの葛藤からいきなりここに飛んでしまうのかは、本人にもまったくの謎なのでありますが)、PIC16F88のパルス出力プログラムに誤りがあることに気がついてしまいました。
設問は、「最短の幅のパルスを出力しなさい」というものでした。
こういう設問は、サンプルプログラムとしては避けるべきなのでありまして、こんな設問をしてしまうものですから、オードリーヘップバーンもイングリッドバーグマンも見られなくなってしまいます。
「最短の」などとはしないで、「適当な」くらいにしておけば、いまごろは一杯やりながら、映画鑑賞を心行くまで楽しんでおれましたのに…。
そうなのです。
前回のサンプルプログラムは最短ではありませんでした。
●PIC16F88テストプログラム(その2)
で。もっと短くできるじゃないか、ということでパルスの出力部を書き直した、アセンブラのソースプログラムです。
[注記]このプログラムにはミスがあります([第416回]参照)。
前回のプログラムのどこをどうしたのかと言いますと、loopの中の、movf PORTB,wを取ってしまったのです。これは冗長でした。
実行結果です。
前回はジャノ目基板の裏が見えておりましたので、今回は表が見えるようにしました。
抵抗とコンデンサは裏に取り付けましたから、表側にはPIC以外はなにも見えません。
命令を1つ削りましたので、パルス幅がその分(1μs)短くなって、4μsになりました。
本日はこれでおしまい。
さあ、ヘップバーンを見るぞお、だったのですけれど。
だめではないか。
もっと短くできるじゃないの。なに考えてるんでしょうかねえ。
やっぱり、年の暮れからのアルコールが抜けてないようでありまして…。
●PIC16F88テストプログラム(その3)
ということでパルスの出力部をまたまた書き直してしまった、アセンブラのソースプログラムです。
[注記]このプログラムにはミスがあります([第416回]参照)。
さきほどのtest5.asmで、
xorlw 01(アセンブラ表記では、ここはxorlw 1でも構いません)
movwf PORTB
としていたところを、loopに入る前に、
movlw 1(ここはアセンブラ表記では、movlw 01でも構いません)
としておいて、loopの中では
xorwf PORTB
だけにしています。
PICの命令はちょいとクセがありまして、ワーキングレジスタ’w’とユーザー定義レジスタ(これは一般形では’f’で示されます)との間の演算は、8080やZ80などとは異なっていて、演算結果を’w’に置くだけではなくて、’f’に置くこともできるのです(その場合には’w’の値は変わりません)。
アセンブラの正しい表記では、結果を’w’に置く場合は、
xorwf PORTB,0
と書きます。
xorwfは’w’と’f’とのXORを計算せよ、という命令です。
PICのアセンブラニーモニックは一般に悪く言われているほどわかりにくいものではありません。そのまんまです。
これに比べるとCの表記のほうがもっともっとタチが悪うございます。
あ。で、最後に付加したパラメータがdestinasion(’d’)です。結果の格納方向です。
ここを0にすると結果は’w’に入れられます。
結果をユーザー定義レジスタ(今回の例ではPORTB)に入れるには、
xorwf PORTB,1
と書きます。
参考までに、PICのData SheetのInstruction Descriptionに記載されているXORWFの説明です。
[出典]Microchip社PIC16F88Data Sheet
ここには記載されていないのですが、別のPICのData Sheetでは、’d’=1がdefaultであると書いてあります。
defaultは近年はやりの「債務不履行」ではありません。
指定省略時に選択される標準設定のことです。
で、さきほどのプログラムに戻りますと、
xorwf PORTB
は、最後のパラメータを省略していますから、PICアセンブラによって、ここはデフォルトの’1’が指定されます。
ということは、演算結果が’w’にではなくて、PORTBに入れられ、’w’の値はそのまま(’01’のまま)残るということになります。
あ。movlwはmove literal to wという命令で(literalは定数のことです)、定数を’w’に格納します。
このアセンブラニーモニックも「そのまんま」です。
これが実行結果です。
xorwf PORTBとgoto loopのみを繰り返し実行しますから、その命令実行時間は、xorwfの1サイクルタイム(1μs)+gotoの2サイクルタイム(2μs)=3μsになります。
これが、PICをcpuクロック4MHzで走らせたときの、最短幅の出力パルスです。
実は最初にサンプルプログラムを書いたときは、このプログラムだったのですけれど、PORTBの他の出力ビットがオープンドレインらしいことに気がつかなくて、そちらのおかしな出力の振る舞いに気を取られて、いろいろプログラムを直して試しているうちに、最初のプログラムのことをすっかり忘れてしまって、前回のプログラムになってしまったのでした。
それはともかくとしまして、Cを使っていては、こういう芸当はとてもできない、といいますか「思いもよらないこと」ではないか、ということについての、ひとつの見本にはなったのではないか、と思うのですがいかがでしょうか?
これが、「ソフトウェアでハードウェアを制御する」ということなのだ、と私は思うのであります。
2010.1.2upload
前へ
次へ
ホームページトップへ戻る