Menu

My Works
- LEDチェッカ
- 太陽電池式回路テスタ
- TTL Pong
- DSP プリセットラジオ
- 電動式 CVCC 電源装置
- OLED MP3 プレーヤ
- etc.

Report
- MIDI のハードウェア
- aitendo DSPラジオ一覧表
- etc.

Parts Collection
- Logic IC
- Calculator LSI
- CMOS Melody IC
- etc.

Blog

Recent Updates

主な更新のみ

24/03/10
- Logic IC Collection


PIC を使ってみた

記述内容の正確性、公開しているソフトウェアを使用した上の損害などについて
本ページの製作者は一切責任を負いません。

最終更新: 2015/01/07


PIC に手を出す

電子工作や個人的な試作で用いる 8bit マイコンといえば、現在は AVR と PIC の2強といえます。世の中には いろいろなアーキテクチャがありますが、秋葉原の電子部品小売店で安定して手に入るのはこの2種だけだったからです。2005 年くらいまでは両方とも手に入る種類も限られていて、価格も同程度であったので、AVR から覚えた私はとくに PIC を使おうという動機や必然性もなく、したがって PIC に手を出すこともありませんでした。

ところが最近は事情が変わってきました。まず、手に入る PIC マイコンの種類の増加です。手許に秋月電子の 2003 年当時の電子かわら版があるので、これと 2012 年現在を比較すると、フラッシュ品の扱い品数は 15 種類から 162 種類と大幅に増加しました。さらに、USB 内蔵品、16bit アーキテクチャ、タッチセンサ、フラットパッケージなど、魅力的な周辺機能や特徴を持つデバイスが多くなりました。

さらに、マイコン単価のデフレーションです。2012 年くらいから、機能に比較してこれまでの常識ではありえないような安価で PIC マイコンが販売されるようになりました。たとえば USB 内蔵の 18F14K50 が ¥170とか、40ピンDIP の Flash 品が ¥180 とか、ADC内蔵の 8pin Flash が ¥45 だとか、わけのわからないことになってしまいました。10 年後にはディスクリートのトランジスタよりマイコンの方が安くなりそうな勢いです。

追い打ちをかけるかのように、秋月電子での AVR マイコンの扱いが減少傾向になってきました。(より正確には、扱いが AA ランクになり、在庫切れ商品がなかなか入荷されなくなってしまいました。)もしかしたら、秋月は PIC 一本に絞るのではないか!? ということで、これらの点から、いまさらながら PIC に手を出すことになりました。せっかくなのでここにレポートしてみます。

何から始めるか

まずはプログラマです。PIC プログラマはあまり自作する気にならないので、ここは純正品を使います。PICKit2 と PICKit3 が安く手に入る USB 接続の純正プログラマです。PICKit3 のほうが多くのデバイスに対応しているので、そちらを購入しました。秋月電子価格で ¥3,900 です。おまけにデバッグ機能もついてきます。ついでにデバイスも、PIC18F14K50PIC18F45K20 の2種類購入しました。PICKit3 には "USING PICkit3" とかかれたでかい紙が入っていて、それをみれば誰でもプログラム・デバッグの流れが一目でわかるようになっています。

PIC ファミリの特徴

秋月で扱いのある PIC アーキテクチャは、おおむね以下の表の通りに分けられます。

アーキテクチャ ファミリ ビット数 命令数 クロックサイクル 命令幅 スタック ROM/RAM 備考
Baseline PIC10
PIC12
PIC16
8 bit 33 4 12 bit 2 3k/138 割り込みなし
Mid-Range PIC12
PIC16
8 bit 35 4 14 bit 8 14k/368  
Enhanced
Mid-Range
PIC12F1xxx
PIC16F1xxx
8 bit 49 4 14 bit 16 28k/1.5k  
PIC18 PIC18 8 bit 83 4 16 bit 32 128k/4k C言語特化型
PIC24 PIC24F
PIC24H(高性能)
16bit   2 24 bit - 256k/98k 3V 品が多い
MIPS32 M4K PIC32MX 32bit   1 32 bit - 512k/131k 5V動作不可
Versatile DSCs dsPIC30F 16bit    2 24 bit - 144k/8k DSP
5V動作可能
High Performance
DSCs
dsPIC33F 16bit   2 24 bit - 512k/54k DSP
5V動作不可
参考:AVR ATtiny2313 8 bit 123 1 16 bit - 2k/128  
参考:AVR ATmega644A 8 bit 131 1 16 bit - 128k/16k  

8 bit 品の型番とアーキテクチャの関係は知っていないと分かりづらいと思います。C で開発したいならば PIC18 ファミリがいいでしょう。ローエンド品になると命令数も少ないし、レジスタも1つしかないので、アセンブラで書くのも苦ではないと思います。

注意すべきは、命令サイクル≠クロックサイクルであるということ、8 bit品ではROM・RAM アクセスにバンク処理が必要なことです。Enhanced Mid-Range よりローエンドの PIC アーキテクチャでは、RAM の割り当てが複雑になっています。具体的には、複数ある128 バイトのレジスタバンク上の、 80〜96 バイトの領域に RAM が割り当てられるといった具合です。さらに、Mid-Range アーキテクチャでは、その領域さえもリニアに割り当てられていません。PIC18 アーキテクチャでは改善されて、256 バイトのレジスタバンク全面にリニアに割り当てられていますが、依然バンク処理の煩雑さは残ります。

また Enhanced Mid-Range よりローエンドの PIC アーキテクチャでは命令幅がデータ幅の倍数でないため、直接的なプログラムメモリへのアクセス手段は用意されていません。代わりにデータシートでは、RETLW 命令を使った間接的なアクセス手段を紹介しています。

C 言語の開発環境をみると、以前の MPLAB(純正開発環境) は PIC18 からの対応でしたが、今は MPLAB XC コンパイラによってほとんどの PIC マイコンの開発が C で行えるようになっています。もっともフリーのライセンスでは最適化なしのプログラムになるので、ローエンドマイコンでの開発効率はたかが知れていますが・・・。

ライバルの AVR アーキテクチャと比較すると、その設計思想の違いが見て取れます。AVR では、ローエンドからハイエンドまで、ほとんど同じアーキテクチャを採用しています。AVR アーキテクチャはアドレス空間がリニアであり、バンク処理もなく、レジスタが 32 個もあって、1命令=1クロックサイクルで処理をするという特徴を持つ RISC アーキテクチャです。反対に PIC では、プロセッサ規模に応じてさまざまな種類のアーキテクチャを採用しています。汎用のアーキテクチャで全ての問題を解決しようという AVR に対し、解決する問題の規模に合わせたアーキテクチャを設計するというのが PIC の方針といえるでしょうか。適材適所といえば一言ですが、そのぶんプログラマにしわ寄せがくることになります。あとむやみやたらに多品種なせいでエラッタが多い印象があります。

コンパイラ

AVR や ARM にはフリーでオープンソースな GCC が使えましたので C 言語のコンパイラには困りませんでしたが、PIC はこんな変なアーキテクチャですから GCC はありません。Microchip のウェブページによると、C 言語の純正コンパイラは MPLAB XC、MPLAB C、HI-TECH C の3種類あるようです。Microchip としてはこの先 PIC10 ファミリから PIC32MX ファミリまで対応した MPLAB XC に一本化する感じっぽい雰囲気なので、これを使うことにします。IDE として MPLAB IDE が必要なので、これを先にインストールしておきます。

8bit、16bit、32bit の 3 種類のアーキテクチャ向けに、それぞれ別々のコンパイラが用意されています。また、それぞれのコンパイラについて Free, Standard, PRO の 3 つのエディションが用意されています。Standard, PRO は有料で、それぞれ $500, $1,000 くらいです。それらの差は最適化のレベルです。有料のエディションは高いので Free エディションをインストールしましたが、Free エディションでは、コンパイルするたび 「PRO エディションだと4倍早いよ」と催促してきます。さすがに4倍はないでしょう...

ICSP コネクタ

昔からある秋月の PIC プログラマキットは、EPROMライタのようにゼロプレッシャソケットに IC を差し込んで書き込む方式でした。そのせいで PIC の書き込みはそういうものだという先入観みたいなものがありましたが、ちゃんと In-System-Programming にも対応しています。PIC では、In-Circuit Setial Programming (ICSP) という名称になります。使われるのは単列 6 ピンのコネクタです。


ICSP コネクタ

上図が ICSP コネクタのピン出力です。PICkit のICSPコネクタは ▼ マークのある方が1ピンです。信号の意味は以下の通りです。プロトコルはアプリケーションノート AN910 で公開されています。

  1. MCLR/VPP : プログラミング用の高電圧出力。旧デバイスは 13V typ. であったが、最近のデバイスは 9V max. となっている。したがって、古いプログラマで最近のデバイスに書き込むことはできない。
  2. VDD : 電源。PICkit3 ではターゲットに電源供給することができる。
  3. VSS : GND 線。
  4. PGD/ICSPDAT : 2線シリアルデータ線。
  5. PGC/ICSPCLK : 2線シリアルクロック線。
  6. PGM/LVP : Single-Supply Programming モード用。非対応デバイスはこのピンを使わない。PGM ピンに L を入力することで単一電源プログラミングモードになる。

それでは、ターゲット側のプログラミングコネクタまわりの回路はどうするべきでしょうか?データシートでは、以下のような回路が推奨されていました。PICKit 3 についてくるでかい紙にも説明があり、MCLR ピンは 1k〜10k でプルアップすることが推奨されています。MCLR に高電圧が加わるので、VDD - MCLR 間に抵抗を挟むのはまずいと思うかもしれませんが(具体的には、ターゲット側の電源レギュレータが電流引き込みに対応していない場合、マイコンの消費電流によっては VDD に高電圧が加わることになるため)、プログラマ側の VDD - VSS 間インピーダンスが 1kΩ 以下なので、プログラマ側に電流が引き込まれることになるため、問題ありません。

PIC16F628 データシートより抜粋; POR 対応品の場合、図の キャパシタ, ダイオード は不要

何か作ってみる

ここまで調べれば、もう PIC を使って何でも作れますね。手始めに、某所で買った 16 セグLEDモジュールを使って、簡単な時計を作ってみましょう。マイコンにはピン数が必要なので、さっき買った PIC18F45K20 を使うことにします。マイコンの持つ機能から言えばけっこうもったいない使い方ですが、なにせたった¥180 なので、気兼ねなく使えます。マイコンは安くなりましたね!10 年前だったら、¥180 じゃあ AT90S1200 も買えません。

実は、買ってから気付いたのですが、このマイコンは 5V動作不可能でした。この LED モジュールは セグメント内部で LEDが2直列になっているので、Vf の関係から 3.3V 単電源では駆動不可能です。仕方がないので、電源を分けて、LED はどうにかして駆動することにします。適当に PIC の種類を選んだせいで、早くもハードウェアにしわ寄せが来てしまいました。

要求仕様は次のような感じです。

次に、ハードウェア を設計します。回路図はこんな感じです。

次に、ソフトウェア を設計します。せっかくなので C で書きましょう。プログラムはこんな感じになりました。

最後に、回路を実装して、プログラムを書き込んで完成です。

この製作については、別ページにまとめました。

使用した上で気付いた点

ここには、AVR ばかり使ってきた私が PIC マイコンを使って実際に製作してみて、気付いた点をいくつか書きます。

まず、プログラマ PICkit3 のできが非常に良いです。さすが、業界のデファクト・スタンダード的存在の PIC マイコンだけあって、フィードバックもそれだけ多いのでしょう。特に、筐体も USB ケーブルも赤いので、他の USB ケーブルと一目で区別がつくし、ごちゃごちゃした私の机の上でも見失わない所がいいですね(笑)。

肝心のマイコンですが、データシートをちゃんと読まないといけない部分が多い印象です。たとえば 今回使用した PIC18F45K50 で言うと、一部の IO ポートはデフォルトで アナログ入力になっていたり、初期状態で WDT が ON になっていたり、外部 RC 発振モードになっていたり、といった具合です。データシートもレジスタの記述があちこちにあって、互いにリンクされていないのでやや手間取りました。しかし全体的にコストパフォーマンスは良いです。

IO ポートは基本的に PORTx、TRISx、LATx のレジスタで操作します。TRISx は方向レジスタですが、"0" で出力、"1" で入力という具合に、AVR と逆なので注意。ピン状態の読み込みは PORTx レジスタを読み込めばOKです。ピンへの出力は LATx か PORTx への書き込みでOK です。LATx と PORTx の違いは、読み込み時にデータラッチの値を読むか、ピン状態の値を読むかの違いです。この違いは Read-Modify-Write をしたときに関わってきますので、ピン出力は LATx への書き込みで行ったほうが無難です。

IO ポートについて、プルアップ機能を内蔵しているデバイスもありますが、全ての IO ポートにプルアップ機能がついているわけではないので注意。そのほか、デバイスによっては各ポートで細かい構成が異なる(入力レベルの違い、入力シュミットトリガバッファの有無、)ので、AVR で可能だった 適当に配線してからプログラムを書くというような設計をすると後で痛い目をみることもありそうです。ドライバ特性も、スペックシートどおりという感じで、出力電流はあまり流せません。

PIC18 シリーズでは、コンフィギュレーションビットはアドレス空間の一部を占めています。すなわち、AVR のようにプログラムとは別に指定する必要はなく、HEX ファイルに埋め込むことが可能です。MPLAB XC8 コンパイラでは、プログラム内で #pragma config ディレクティブによってコンフィギュレーションビットを記述すれば OK です。#pragma config には 2進表記は使えないので注意(厄介なことにエラーは出ません)。

タイマの入力は オシレータ出力ではなく、命令クロック(Fosc/4)です。

データシートからレジスタの説明をいちいち探しだすのが大変でした。

割り込みは高優先度割り込みと低優先度割り込みの2種類があります。各割り込み要因ごとにそれらのどちらかを設定します。各割り込み要因ごとに割り込みベクタが存在するわけではありません。実際のプログラムでの割り込み処理としては、各割り込みルーチン内でレジスタの割り込みフラグによって条件分けすることになります。割り込みフラグは自動でクリアされません。ベースラインシリーズには割り込みすらなかったりするので、かなり割り切った設計だと思います。

コンパイル時はビルド設定を Release にするのを忘れずに。

総括

PIC マイコン自体はそれほど使いやすいアーキテクチャだと感じませんでした(少なくとも 8bit 品に関しては)。AVR ほどのとっつきやすさ、明快さはないです。PIC を使ってから AVR の開発をすると、AVR の"高級マイコン"っぷりがよくわかります。それでも PIC のメリットをあげると、豊富な品種、圧倒的な安さ、入手性、この3点につきます。それに、Microchip のドキュメントも日本語版含めそれなりに豊富です。いわば、PIC は"大衆マイコン"であるといえるでしょう。

参考文書