2011年4月3日作成 2010年4月6日更新

PICプログラマの製作にもどる

PIC16のプログラム書き込み方法

PICプログラマを作ったときに調べた書き込み手順を、自分が忘れてしまわないうちに書いておきます。

マイクロチップ社のデータシートにすべて書かれているので、まずはそれを読みます。自分はPIC16F88に書き込みたかったので、PIC16F87/88 FLASH Memory Programming Specification 39607c を読みました。

ICSPとLV-ICSP

PIC16の書き込みモードには、ICSPモードとLV-ICSPモードがあります。

MCLR(VPP)ピンに高電圧(13Vとか9Vとかデバイスにより異なる)を印加して書きこむのが以前からあるICSPモードで、多くの(たぶん全ての?)デバイスに書きこむことが出来ます。

対してLV(Low-Voltage)-ICSPモードは比較的最近のデバイスでサポートされた方法のようで、高電圧が必要無く、MCLRに掛ける電圧はVDD(2.0-5.5V)でよいので書き込み機の回路を簡単にできます。そのかわり書き込みモードと通常のプログラム実行モードの切り替えにPGM(PIC16F88の場合RB3)ピンを使用するので、PGMピンを通常のIOポートとして使えなくなります。また、LV-ICSPモードを使用するにはコンフィギュレーションワードのLVPビットが1でなければなりません。LVPビットは工場出荷時やチップイレース後には1になっています。

ICSPモードへの入り方

ICSPモードの場合

以上。

LV-ICSPモードの場合

以上。PGMピンはずっとHに固定していても動いたので、自作の回路ではそのようにしている。

簡単でしょ?

書き込み手順概略

ICSPモードとLV-モードでは書き込みモードへの入り方は違いますが、書き込みモードに入った後の書き込み手順は同じです。

書き込みは

の順で行います。消去コマンドには、現在のポインタが含まれるブロックを消去するBegin Eraseコマンド、プログラムメモリをすべて消去するBulk Erase Program Memoryコマンド、データメモリをすべて消去するBulk Erase Data Memoryコマンド、チップ全体を消去するChip Eraseコマンドがありますが、バルクイレースとチップイレースはVDDが4.5〜5.5Vの間の時しか使用できないので、今回作成したプログラマでは幅広い電圧で書き込みができるようにこれらのコマンドは使わず、Begin Eraseコマンドのみを使用することにしました。

5Vでしか使わない!という場合は、バルクイレース/チップイレースを使ったほうが、少しだけ書き込み手順が簡単になります。

コンフィグレーションワードでコードプロテクトを有効に設定すると、チップイレースコマンドでしか消去できなくなるので、注意が必要です。

コマンドの詳細

コマンド一覧

CommandMapping (MSB … LSB)DataVoltage Range
Load Configuration0 0 0 0 000000000000000002.0V-5.5V
Load Data for Program Memory0 0 0 1 00, data (14), 02.0V-5.5V
Read Data from Program Memory0 0 1 0 00, data (14), 02.0V-5.5V
Increment Address0 0 1 1 0 2.0V-5.5V
Begin Erase0 1 0 0 0 2.0V-5.5V
Begin Programming Only Cycle1 1 0 0 0 2.0V-5.5V
Bulk Erase Program Memory0 1 0 0 1 4.5V-5.5V
Bulk Erase Data Memory0 1 0 1 1 4.5V-5.5V
Chip Erase1 1 1 1 1 4.5V-5.5V
Load Data for Data Memory0 0 0 1 10 0 0 0 0 0 0,data (8), 02.0V-5.5V
Read Data from Data Memory0 0 1 0 10 0 0 0 0 0 0,data (8), 02.0V-5.5V
End Programming1 0 1 1 1

フラッシュメモリは消去後、ビットが1になります。プログラムメモリなら0x3FF、データメモリなら0xFF。

通信の実際

PICとは、PGCピンとPGDピンを使用したクロック同期式のシリアル通信でコマンドをやり取りします。

  1. まずPGCピンをH
  2. PGDピンに送信するデータをLSB(最下位ビット)からセット (0=L / 1=H)
  3. PGCをL(クロックの立ち下がりでデータが取り込まれます)
  4. これを6ビット分繰り返してコマンドの送信を完了します
  5. データシートのコマンド一覧表ではコマンドが5ビットで表記されていますが、実際に送信するときには最後に1ビット追加して6ビット分送信します。追加するビットは0でも1でも良いようなのですが、今回作ったプログラマでは0を追加しています。

  6. データが不要(コマンド一覧表のData欄が空欄)なコマンドの場合これで終了
  7. コマンド送信後1us待ってから、データを16ビット送信または受信を行う
  8. コマンドの送信と同じで、クロックの立ち下がりでデータ有効。受信時はPGCピンをHにしてから80ns後にデータが確定するので、その後PGDピンを読み取ってからPGCをLにする。

    実際にやり取りするデータは14ビットとか8ビットなので、前後に0を追加して16ビット分送受信する。

実際の書き込み手順

書き込み手順は、ICSPモードでもLV-ICSPモードでも同じです。

書き込み位置を示すアドレスポインタに直接値を設定することは出来ません。Increment Address コマンドでアドレスポインタを1進めることと、Load Configuration コマンドでアドレスポインタを 0x2000(コンフィギュレーションメモリの先頭)に設定することと、ICSPモードに入りなおしてアドレスポインタを0にリセットすることしか出来ません。現在のアドレスポインタを読み出すことも出来ません。

プログラムメモリーの書き込み

  1. ICSPモードに入る
  2. ICSPモードに入った直後のアドレスポインタは0

  3. Begin Erase
  4. 2ms待つ
  5. End Programming
  6. 2〜4で1ブロック消去。PIC16F88の場合1ブロック32ワードなので、書きこむアドレスが32で割り切れる時にBegin Eraseコマンドを出せば良い

    (バルクイレースコマンドとかで先に消去してあるなら、ここで消去する必要はない)

  7. Load Data for Program Memoryコマンドで1ワードデータをセット
  8. Increment Address
  9. 5〜6を4回繰り返す(4ワードラッチにセットする)
  10. Begin Programming Only Cycleコマンドでフラッシュメモリに書き込む
  11. 2ms待つ
  12. End Programming
  13. 5〜10を8回繰り返す(1ブロック分 4*8=32)
  14. 2〜11をすべてのデータを書き終わるまで繰り返す

書き込みが終了したら書いたアドレスをすべて読み出してみて、正しく書けているかを確認する。

プログラムメモリーの読み出し

  1. ICSPモードに入る
  2. ICSPモードに入った直後のアドレスポインタは0

  3. Read Data from Program Memory
  4. Increment Address
  5. 2〜3を好きなだけ繰り返す

読み出しは簡単

コンフィギュレーションメモリの書き込み

コンフィギュレーションメモリの書き込みもプログラムメモリと同じ方法で書き込みできるのですが、Begin Eraseコマンドで8ワードしか消えないようでした。(0x2000番地でBegin Eraseコマンドを出すと、0x2000〜0x2007までしか消去されなかった。)

コンフィギュレーションワード2が0x2008番地なので、0x2008番地でもBegin Eraseコマンドを出すようにしました。

PIC16用HEXファイルの読み方

PIC16F88でLEDを点滅させるプログラムのHEXファイル


:040000008A11D12F61
:100FA20083018A11D42F7030831603138F009B01A3
:100FB20086018501FF30831203138600FF3085000E
:100FC2000630F2000E30F100B030F000F00BE72FE7
:100FD200F10BE72FF20BE72F831203138601850132
:100FE2000630F2000E30F100B030F000F00BF72FB7
:0E0FF200F10BF72FF20BF72FDB2F8A110028DF
:04400E00B93FFC3F7B
:00000001FF

数はすべて16進。2文字で1バイトを表す。


PICプログラマの製作にもどる


webmaster@kyoutan.jpn.org

('A`)