PICでUSBを!(知識ゼロからのスタートです)
PIC18F14K50のUSB機能を100%自前のソフトで制御する試みです。しかもアセンブラで!
当記事は2009年12月から「TTLでCPUをつくろう!」というタイトルの もとにほとんど毎日連載をしてきたものを再編集したものです。 2011.7.9

前へ
次へ
目次へ戻る
ホームページトップへ戻る
☆PIC18F4550

PICとのつきあいはもうずいぶん長いのですが、今まで使ってきたのはPIC16FXXというナンバーのものばかりでした。
PIC18FXXは初めてさわります。
PIC18FXXはPIC16FXXに比べるとハードウェア、ソフトウェアの機能がかなり拡張されていることがわかりました。
USBを扱うためには、その拡張されたハード、ソフトについて理解する必要がありそうです。
ということでまずはPIC18F4550の機能を理解することからエントリーいたします。

[第14回]

●さてお話は戻って、PICのUSBなのですが

企画からおよそ1年半をかけて、やっとのことでMYCPU80が完成しましたので、そのあとの企画として、4ビット版の「つくるCPU」と8ビット版のそれと、それからTK80のクローンボードもつくる予定でスタートしたのでしたが、遅まきながら、たまたまUSB内蔵のPICなるものがあることを知り、そりゃあやるしかないだろう、とそれに首を突っ込むことになってしまったのが、2009年11月初旬のことでした。

そのあたりのことの説明に取りかかりましたのが、2009年12月5日([第1回])でした。
それからすでに3週間近くが過ぎようとしておりますのに、まだUSBはおろか、PICライターのプログラムの説明にも入れません。
このままでは、ほんと、年が明けてしまいます。

この調子ですと、本題の「つくるCPU」のお話は桜が咲くころまでおあずけかと…。

それほどに、この2ヶ月ほどの間に私が経験してきましたことは、密度が濃いことだったのでありますから、ともかく気長におつきあいをお願いいたします。
説明を開始しますと、いきなりむつかしーい内容に突入してしまいますので、できるかぎり平易な説明をと心がけますと、なおさら時間がかかってしまいます。

まあ、そういうところは、てきとーにはしょって、「あとは参考書などでみんな勉強してちょうだいね」、で終わってしまえば楽なのですけれど、ひとつには、せっかくそこまで追求した密度の濃い内容でありながら、悲しいことに、私はじきにすっかりさっぱり忘れてしまうものですから、私自身の備忘録を兼ねて、できるだけ詳細に説明をしていきたいと考えております。

●まずはPICライターの説明から

本来はPICライターのプログラムは全く予定にも入っていなかったのでありますが。

すでにご案内のとおり、突然にふってわいたような災難で購入したばかりのPICプログラマが壊れてしまった(と思いこんだのは単なる私の早とちりだったのですけれど)ことがきっかけとなって、パラレルポートを使ったPIC18Fライターのプログラムまで作ってしまいました。

そのPICプログラムのお話は、本来の筋からはちょいと外れておりますから、それはあくまで番外編ということにいたしまして、まずはPIC18F4550のUSB機能をコントロールするプログラムの製作についての説明に取りかかるべきなのでしょうけれど、ところが、そのUSBプログラムについては、まだ道半ばの状態なのですよねえ。
一方、PICライタープログラムについては、PIC18F4550も18F2550も一応読み出し、書き込みともにできるところまで、プログラムを作ってしまいました。

そういうことですから、まずはPICライタープログラムの製作のほうから、片付けてしまいたいと思います。
「そんなの関係ねえ」とおっしゃりたいお方などもおいでかとも思いますけれど、思わぬことからとはいえせっかく作り上げてしまったPIC18Fのライタープログラムです。
このまま放置しておきますと、じきにすっかり忘れてしまうに違いありませんから、備忘録として書きとめておきたいと思いますので、まま、我慢してしばらくおつきあいをお願いいたします。

PICライターのプログラムもCではなくて、アセンブラで書きましたけれど、こちらのほうは、DOS/VパソコンのDOSプロンプトで実行するプログラムですから、当然PICのアセンブラではなくて、8086アセンブラで作成をいたしました。

ただ、いくらなんでも、その対象となる、PIC18F4550について、なんの説明もしないまま、いきなりそのライタープログラムについてだけ説明をするというのも、なんだかなあ、と思いますし、まあどうせその先にはPICのアセンブラを使った、USB制御のプログラムについて説明をしていくことになりますから、PICライタープログラムの説明にとりかかる前に、そもそもPIC18F4550とはどのような特徴をもったICなのか、特に、今までのポピュラーなPIC16F84とか、16F628、16F88とどこがどう異なるのか、といったあたりについて、まずはざっと整理をすることからとりかかるのがよろしいかと思います。
[2011.7.9注記]
ここでは「後ほどPICライターについての説明をいたします」という意味のことを書いているのですが、その後のお話しの展開の中で、そのことは全くきれいさっぱり忘れてしまいました。
「備忘録として書いておきたい」などと言いながら、もうかれこれ1年半以上もそのままにしておいたわけですから、備忘録どころかそれこそその内容もなにもかもすっかり忘れてしまいました。
いまさらそれについて思い出しながら書くというのもなんだかなあと思います(いやあ、それは多分無理でございましょう)ので、この件(PICライタープログラム)につきましては、とりあえずは保留ということにさせていただきます。あしからずご了承を。[注記ここまで]

●しかしお話には順序というものがありますので

まあでも、お話の順序といたしまして、今回の最初の書き出しのところで、ちょいと書きましたように、11月のはじめのころに戻りまして、USB内蔵のPICの存在を知ったという、そのあたりから始めたいと思います。

MYCPU80はそもそものはじめには、基板の空いたスペースにTK80回路を載せて、さらに余ったスペースに、PICを利用したRS232Cインターフェースを搭載するというつもりでした。
しかしながら、いまどきのパソコンはRS232Cのインターフェースを持たないものがほとんどですから、するとRS232Cインターフェースを利用するためには、USBシリアル変換ケーブルを使用することになります。

どうせUSBシリアル変換をするのならば、基板上にUSBシリアル変換ICをのっけてしまい、見かけ上はUSB接続、ということにしてしまったほうがスマートではないか、と考えました。

ところがこのUSBシリアル変換IC、FTDI社のFT232RLはなかなかのすぐれものなのですが、残念なことに普通のDIP型ではなくてフラットパッケージしかありません。
DIP型のICならばハンダ付けも少し慣れた方でしたら別にどうということもないのですけれど、端子間ピッチがわずか0.65mmのフラットパッケージということになりますと、これはちょっと、よほどハンダ付けに慣れた方でないといささかハードルが高くなりすぎます。

それじゃあ、FT232RLだけはこちらでハンダ付けしてから、MYCPU80基板を供給しようか、とも思って、プリント基板のアートワークにその配線を追加するところまでしたのですが、そういうハンダ付け作業は、当方としても相当に緊張してしまいます。
万一ハンダ付けに失敗したとなると、あの大きなMYCPU80基板1枚がまるごとオシャカになってしまいます。
おまけのつもりで追加した機能ですのに、そのおまけのためにそこまでのリスクを背負うのもなんだかなあ、ということで考え込んでしまいました。

結局その解決策として、FT232RLだけをのせた小さな基板を別に作って、それは完成品で供給することにして、そのFT232RL基板とMYCPU基板とは、基板接続コネクタでつなぐことにしました。
コスト的には、秋月のUSBシリアル変換ケーブルを使ったよりも高くなってしまい、これまた釈然としないところもあったのですけれど、そのようなもの(USBシリアル変換ケーブル)を使うことなく、直接USBコネクタ接続をする形にしたい、というこだわりもあったので、コストについては、割り切って考えることにしました。

今後に予定していますMYCPU4ビット、8ビットの組立てキットや、TK80クローンキットも同じ方式のインターフェースを搭載するつもりでおりました。
そういう矢先に、USB内蔵PICの存在を知ってしまったのでした。

そんな有りがたいものがあるのなら、そりゃあ使うしかないじゃありませんか。
大喜びで、飛びついたところまではよかったのですが、いざ首をつっこんでみますと、とてもとてもそんなに甘いものではありませんでした。

●PIC18F4550は相当に難しそう

たかがPICと甘く見たのがそもそもの間違いで、Microchip社のホームページからダウンロードしたPIC18F2550/4550のDataSheetはなんと英文438ページ!!!
パラパラっと見ただけでも、いままで普通に使っていた、16F628や16F88とは相当に様子が異なっていることはいやでも認識せざるを得ませんでした。
ことにUSB機能についての部分は正直言って、まったくわからん!何回読んでもさっぱり、わかりませんよぉ。
これはえらいものに首をつっこんでしまった…。

USBについては、私は全く知識ゼロ、ずぶのシロートも同然というところからのスタートでしたから、もうちんぷんかんぷん、さっぱりわからん状態で、もう出口も入り口もない、という情けないことになってしまいました…。

あ。なぜPIC18F2550/4550かといいますと。

Microchip社のホームページで調べますとUSB内蔵のPICは、かなりたくさんの種類があることになっていますけれど、日本においては簡単に入手可能なものは限られています。

この手のものを入手するのにやっぱり一番手っ取り早いのは秋月の通販です。
秋月ではUSB内蔵PICとして、PIC18F2550とPIC18F4550、それとPIC18F14K50が入手できます。
ウェブや「トランジスタ技術」誌を参考に勉強しながらスタートを切ることにしましたら、そこで取り上げられていましたのは、みんな一様にPIC18F4550でした。
こいつは40pinでちょいと大きいので、MYCPUやTK80クローンのUSBインターフェースとしては不向きなのですが、そこはそれ、なにしろUSBの知識ゼロからのスタートですので、いたし方がありません。
ということで、まずはPIC18F4550を使ってのスタートとなった次第です。

●右も左もCばっかりじゃございませんかぁ

ところがところが、いざPIC18F4550のDataSheetをMicrochip社のウェブサイトからダウンロードしてみると、すでに書きましたように、こいつはいままでのPIC16F88などとはちょっと違って、なかなかにてごわそうな感じです。
そこにもってきてUSB機能の使い方となると、なんじゃこりゃあ、何回読んでもさっぱりわからんではないか!

うう。つうことは、やっぱり、あれだ。
ウェブサイトからいろいろサンプルプログラムをかき集めるとか、Microchip社のサイトから参考プログラムなどをダウンロードしてみるしかないか。
まずはそいつをPIC18F4550に実際に書き込んでみて、動作を確認することからぼちぼち始めるのがよろしかろう。

ところが、PIC18F4550と秋月のPICプログラマを入手して、いざUSBのサンプルプログラムから勉強を開始しようとした、そののっけから見事につかえてしまいました。

ウェブも「トランジスタ技術」の記事も、ソフトはぜーんぶ、Cコンパイラで作成、なんですと。
なんでPICのプログラムをCなんぞで書いたりするのさ!

いや、別にCを毛嫌いしているわけではありませんよ(してる。してる。しっかりしてる)。
ただ、私は、ことにPICなどのプログラムはCを使うべきではないと思っています。
ま、それについてはいずれ、その理由も説明していくつもりですし、本稿を書き進めていきますうちに、その理由もおのずから明らかになってくることと思っています。

ですけれど、何度も繰り返しておりますように、悲しいことに、USBの知識ゼロからのスタートですから、嫌いなCでも使うしかありません。
ええ。ダウンロードしましたよ。Microchip社のサイトからフリーのC18コンパイラつうのを。

このコンパイラはフリーでダウンロードできますけれど、3ヶ月ほどしますと一部機能が使えなくなるのだそうです。
でもどうやらその制限というのは、なんでも「最適化」がちょいと甘くなる程度で、コンパイラとしての通常使用には問題はないのだそうです。

ところがところが、さて準備万端整えて、いざCでUSBのプログラミングのスタートだ、となったのですけれど。
うう。…わかりません。
わからん。やっぱり、まったくわからんではないか。

●サンプルプログラムがさっぱり、わかりませぬ

Cのすぐれた特徴として(あるいは便利なところとして)、ユーザー定義の関数が、あたかもC本来のコマンドと全く同様に使えることである、ということが、まことしやかに伝えられておりますようですが。
私は、とんでもないことだと思っております。
これこそCの最もケシカラヌところだと思っております。

そもそも言語なるものは(ことにコンピュータのそれは)、厳格に例外なくきっちりと定義されていてしかるべきもので、それとユーザー定義の関数などとは、明確に峻別されておるべきものだという認識をもっております。

もちろん誰かが作った便利な機能が公開されて、そしてそれをだれもが簡単にコマンドライクに利用できるということは、これはとても有意義なことに違いありません。

しかし、アプリはどこまでいっても、アプリです。基本的なコマンドとは一線を画してしかるべきものです。
そうしておかないことには、これからCを学ぼうとする人たちが、先輩のサンプルプログラムの中で未知の「コマンド」に遭遇するたびに泣くことになります(そうではありませんか?)。

なんでこんなばかな言語が広まってしまったのでしょうかねぇ。

いや。これはCの責任ではないでしょう。
おそらくは、それを使う人たちの安易な姿勢こそが問題なのだと思います、です。

もともとCコンパイラはユーザー定義の関数や変数に対しては、かたくななほどきわめて厳格でした。
たとえば、Cのソースで、ユーザー定義の関数がMainの後ろに続いて記述されている場合においても、プログラムの先頭で、その関数を定義しておくことが求められます。
Cにもいろいろあるようで、そうではないコンパイラもあるのかもしれませんが、私の知る限りではそういうことになっています。

例を使って説明してみましょうか。
ごくごく簡単なCプログラム例です。
test1.cpp、test2.cpp、test3.cppの3つのプログラムです。

[test1.cpp]
// test1
//
#include <stdio.h>
//
void main()
{
printf("ohayo!\n");
PRINT();
}
//
int PRINT()
{
printf("good morning,sir!\n");
}

[test2.cpp]
//test2
//
#include <stdio.h>
//
int PRINT();
//
void main()
{
printf("ohayo!\n");
PRINT();
}
//
int PRINT()
{
printf("good morning,sir!\n");
}

[test3.cpp]
//test3
//
#include <stdio.h>
//
void main()
{
int PRINT();// user fubction
printf("ohayo!\n");
PRINT();
}
//
int PRINT()
{
printf("good morning,sir!\n");
}

以上の3つのプログラムを順にコンパイルして実行してみましたら、結果はこうなりました。

最初のtest1.cppはコンパイルエラーになってしまいます。
PRINT()が「未定義」だ、つうんですよね。
あんた、どこに目ぇついとんの?すぐ下にあるでしょうが?
と言ったところで、コンパイラ様は妥協などしてはくれませぬ。

test2.cpp、test3.cppのように、実際に参照するラインよりも前の位置で定義しておかないと、Cコンパイラ様にはわかっていただけませぬようです(test3は実行すると画面がスクロールしてしまいますから、省略しましたが、実行結果はtest2と同じになります)。

ですけれどBASICなら、そんなに融通の利かないことはありません。

中日電工オリジナルのZBK−BASICでの使用例です。

参照する行より前で定義しておかなくても、同じプログラムの中にありさえすれば、いきなり使っても拒否されたりすることはありません。

「うむむ。そういういい加減なところがBASICの悪いところなんだよな」
などと批判されたりしていたものなのでありますけれど、Cなんぞもっともっとタチが悪いじゃございませんか。

それほどかたくなに、厳格に、事前の定義を求めておきながら、ヘッダーファイルをインクルードすると、もう事実上、無制限、何でも有り、でダバダバに通してしまいます。

じゃあ、ヘッダーファイルの中で定義してあるのだろう、と思ってそれを見てみますってえと、そこにもまた別のヘッダーファイルがいくつもインクルードされていて、いったいどのヘッダーファイルでお目当ての関数や変数が定義されているのか、さっぱりわからない状態でありますねぇ。

これって、事実上の無法地帯とちがいますかぁ。
「トランジスタ技術」のサンプルプログラムなどでもたいていは、「ユーザー関数については、ヘッダーファイルを見てね」でけりをつけていたりして。
でもそのヘッダーファイルは省略されていて、本文には載ってませんよぉ。
え。ヘッダーファイルについては、ウェブのダウンロードサービスを利用せよ?
そんな、面倒なぁ。

お話があらぬ方向に暴走してしまいましたけれど、USBに関する「トランジスタ技術」の参考プログラムも、ウェブの参考プログラムも、Microchip社のサンプルプログラムさえも、全然参考になりませんですよお。
やたら、ヘッダーファイルがしかも多重インクルードされていて、さらにやたらめちゃめちゃわけのわからぬ変数やら関数やらが多用されているものでありますから、こんなもの、わかるわけがありませんよお。
ほんとうに、Cコンパイラなどくそくらえ、って言いたくなってしまいます。

思うにCはプロの業界専門言語なのですよね。たぶん。
仲間内でしか通用しない、符牒ちりばめ言語。

OSや巨大なアプリケーションプログラムを普通の言語で構築していたのでは、多分間に合わないほど、要求されるシステムが巨大化してきているのでありましょう。そういうものをつくりあげる場合にこそ便利な言語がC。
たとえて言いますならば、プロの大工さんが、りっぱな建物を短期日で建築しようという場合に似ているのでは、と思います。

プロなのですから、余計な言葉は不要です。
いえ、邪魔ですらあります。
親方が、「ハチ!」、「クマ!」というだけで、八五郎も熊さんも、「あいよっ」てんで動きます。
あるいは無言で「!」って目配せするだけで八っつぁんも熊さんも、「あれだな」って動きます。
はたからシロートが見てたってちんぷんかんぷんでさっぱりわかりませんけれど、プロならそれでいいのでしょう。
それじゃあ、まったくわかりませんから、もう少しわかるように説明してくださいよぉ、なんて言おうものなら、「ベラボウメェ、こちとら江戸っ子だぁ。そんなかったるいこたぁできるかよぉ」って怒鳴られてしまいます。

おお。よくテレビで出てくる、魚市場などのセリにも似てますねえ。
指を使ってなにやらわけのわからぬ符牒を怒鳴っているだけでセリが成立しています。
まあ、すごいものだと思います。

私は、Cはそういうたぐいの言語だと思っています。
仲間内ならば便利な言語。
ならば、仲間内だけではなくて、それを他人に理解させよう、つう気がおありならば、そこんところは、もう少していねいにコメントすべきではないでしょうかと。

もともとの命令はともかくとして、ユーザーが勝手に定義した関数や変数については、当事者以外はわからないのがあたりまえで、それならば、それを「サンプルですよぉ。参考にしてくださいよぉ」というのでありますならば、そのユーザー定義の部分についても説明をしてくださらなくては、まったくわからないのです。
ところが困ったことに、どうもそういうCをお使いになる方々の中に、「そんなことはわかれよ。どシロートめが」という目線を感じてしまうのですよねえ。
エスパーじゃありませんから、そりゃあ無理ですってば。

いえいえ。Microchip社のサンプルプログラムがそうだ、といっているのではありませぬ。
これはまた、しつこいほどコメントがついているのでありますけれど、今度はやたらコメントが多すぎて、
「で、本当のところ、絶対に必要なのは、どれとどれなの?ねえ。教えてよ」
ということになってしまって、やっぱり使い物にならないのでありますよ。

およそ10日ほども、Microchip社からいっぱいダウンロードしたり、ウェブをあちらにこちらにさまよい歩いたりしたのですけれど、みーんな結局追求不能なCプログラムばっかり。
ヘッダーファイル群の森深く分け入って、出口がわからない状態で、ほとんど泥沼で窒息寸前。

もお、あかん。
さじを投げてしまいました。

いいよ。わかったよ。
もともと私ゃPICなんぞをCでプログラムすることにゃ反対だったんだから、それが節を曲げて、Cでいこうとしたことが、だいたい間違いだったのよ。
こうなったら、意地でも、アセンブラ(機械語)でやってやるぞよぉ。
CPUをつくろう!第406回(2009.12.23upload)を再編集

PICでUSBを![第14回]
2011.7.9upload

前へ
次へ
目次へ戻る
ホームページトップへ戻る