はじめに
Harmony v3 を用いた PIC32MX の開発をかじってみようと思い立ち、もう 4~5 年経過してしまいました。年老いたなぁ~。歳を取ると熱量が下がってきてしまいます。
さて、先日、MPLAB X IDE 6.25 から PickIT3 がサポートされなくなるという記事 (Microchip MPLAB® X IDE v6.25 Will Discontinue Support for Legacy MPLAB PICKit™ 3 In-Circuit Debugger) を見たので、もう待ったなしであると思い、現在最新版の MPLAB X IDE 6.20 で LEDの点滅をやってみました。
使ったソフトウェア
- Windows 10 Professional
- MPLAB X IDE 6.20
- XC32 v4.40
- MCCなどは MPLAB X IDE 起動後に自動的にインストールされます。
MPLAB X IDE 6.20のインストール方法と初回起動
ここで説明するよりも、公式 YouTube を見たほうがいいでしょう。
ハマりポイントは、
- MPLAB 初回起動後は 再起動する必要がある。右下に小さく英語でメッセージが出ているのだが、たいていの人は気が付かない。
- MCC の初回起動するには ダミーのプロジェクトを 1回作成する必要がある。
- MPLAB X IDE をインストールするときに、古いバージョンの MPLAB X IDE は自動的に削除されない。
いずれも、上記公式ビデオで説明をしていますね。
使った電子部品
- PIC32MX230F064B : 秋月電子でも在庫僅少ですね。同様のほかの型番でもよいと思います。
- LM2950-33 : LDO (電圧変換レギュレータ) IC です。 USB 端子から供給される 5Vから PIC32 が必要とする 3.3V を作り出します。3.3V が供給できればなんでもいいはずです。
- 8MHz 水晶発振器 : 将来の USB Host 評価のためにはチップ内部クロックで 48MHz を作り出す必要があります。
- 22pF セラミックコンデンサ (2個): 水晶発振器の安定発振のお供に使います。
- 0.1uF 積層セラミックコンデンサ (3個) : 電源安定化用のパスコンです。推奨されています。
- 10uF 電解コンデンサ (2個) : Vcap端子と、LDOに必要です。
- 10kΩ 抵抗 (1個) : MCLR 端子につけます。ICSP書き込み時に必要です。
- 220Ω 抵抗 (1個) : LED の電流制限用です。
- LED (1個)
- USBコネクタ、ICSP用ピンヘッダ、など。
評価回路
近い将来 USB Host の評価も想定しているため、LED点滅には直接無関係な部品も搭載しています。
オレンジ線は 5V、赤線は 3.3V の電源です。PIC32MX は VDD=3.3V のチップであり、一部の端子しか 5Vに耐えられないので、間違えないように注意してください。
JP1 は USBを接続します。今現在は 5V電源供給源として使います。
JP2 は PIC32MX への書き込み用 ICSP端子です。 Pickit3 を差し込みます。
RB15 ピンを LED とつないで、MPLAB X IDE 上で作成したプログラムで点滅させていきます。今回もブレッドボード上で実装しました。
MPLAB X IDE 6.20 でLチカプログラムを実装してみよう
MPLAB X IDE のアップデートや MCC, Harmony のインストールがすべて完了しているもの、とします。なるべく簡潔に、必要最小限の作業となるようにしています。
ウィザードでプロジェクトを作成する
2: 赤い囲みのボタンを押して、新しい project を作成するウィザードを立ち上げます。
3: Application Project(s) を選択して Next を押します。
4: 使う チップとツールを指定します。今回は PIC32MX230F064B と PickIt3 を指定しました。チップへの書き込みをせずに、プログラムを書いてコンパイルするだけなら Tool は No Tool でも大丈夫です。
5: コンパイラを指定します。 XC32 コンパイラを指定します。バージョンも指定します。この例では v4.40 しか出てきていませんが。
6: プロジェクト名や保存場所、文字コードを指定します。漢字でコメントを書くのであれば unicode (例: UTF-8) などを指定したほうが安全かと思います。
7: Finish ボタンを押して プロジェクトファイル群が生成されるのを待ちます。この時 MCC (Code Configurator) も動きだします。少し時間がかかるのですが待ちましょう。
プロジェクトプロパティの設定
わかりにくいですが 1のボタンを押すことで、プロジェクトのプロパティを変更できます。
Pickit3 の電力設定
「Pickit3 あるある」ですが、電力の設定をしておかないと、電流不足で書き込めない問題が起きることがあります。Pickit3 の電源供給ラインの電流制限が厳しめだったのが原因らしいですが。その「例の設定」はここにあるので示しておきます。
MCC の設定
今度は MCC (Code Configurator) の設定をします。チップの動作モードや端子の設定などを視覚的に見せることで、ミスを減らす試みだと思います。ここで設定したものは、この後生成する C++ コードに反映されますが、その前のプロジェクトとの差分があれば差分の確認・修正を逐一求められます。ぽちぽちマウスクリックすればいいです。
今回は、DMAや割り込み処理をしないで Lチカするので、それらの設定はしません。
クロック構成の設定
1: "Project Graph" タブにある、"System" アイコンを選択して、3番のプルダウンメニューで "Clock Configuration" を選択します。
2: "Clock Diagram" が表示されます。今回の回路では 8MHz の水晶から 48MHz のシステムクロックを生成するように設定します(赤丸部分)。 USB はまだ使わないし、周辺回路もいじらないので、それらのクロック設定は特に必要ありません。
ピン設定
1: チップの端子設定をします。また、"Project Graph" で "Pin Configration" を選択します。
2: 今回は RB15 ピンに LEDをつないでいるので、そのピンだけ設定します。(赤枠部分)
3: "Pin Diagram" を見ると RB15 だけが、設定済み(=assigned)を表す緑色になっています。
MCCの設定をもとにコードを生成
"Resource Management (MCC)" タブの "Generate" ボタンを押すと、今まで MCCで設定した内容となるような設定ファイルや必要な 関数が生成されます。今回の例では GPIO 1ピンだけの追加で、I2CとかUARTとかの機能は一切使わないので、ほぼ素のままのコードが出てきます。その分、見通しやすいはずです。
メインプログラム
"Project" タブのSource Files -> main.c が生成されます。クロックすると右側にそのソースコードが表示されます。ここに Lチカに必要なコードを書き足していきます。
main()
main() 関数の while ループの中に 次のコードを書きます。本当は すでに用意されている SYS_Tasks() 関数の中に書くべきですが、まだ Harmony を実質的に使っておらず app.c が生成されていないことと、最初なので見やすく・わかりやすくする、ということでこのように書いています。
while ( true )
{
/* Maintain state machines of all polled MPLAB Harmony modules. */
SYS_Tasks ( );
PORTBbits.RB15 = 0; // low (LED On)
__delay_ms(1000);
PORTBbits.RB15 = 1; // high(LED Off)
__delay_ms(1000);
}
PORTBbits.RB15 は RB15ピンの状態を H/L に設定しています。回路を見てほしいですが、RB15=L のとき、LED に電流が流れて点灯するようになっています。
XC32 には delay() がないらしい
48MHz で動作しているので、RB15 の H/L 切り替えは十分に待ち時間を取る必要があります。PIC16 用の XC8 や Arduino では delay() という何もせず待つ関数が用意されていますが、XC32には用意がないそうです。ここでは __delay_ms() という ミリ秒待つ関数を用意することにします。
__delay_ms()
CP0 レジスタ (カウンタ) はシステムクロック 2発で 1増えるらしいです。システムクロックは definition.h 内で CPU_CLOCK_FREQUENCY というラベルで定義されていますので、これを使って 1ミリ秒あたりのカウンタ増分を求めておきます。次のコードを main() の前に挿入します。プロトタイプ宣言すれば main() の後に挿入してもよいですね。
#define TICK_PER_MS (CPU_CLOCK_FREQUENCY/2/1000)
void __delay_ms( uint32_t d )
{
uint32_t delayCount, startTime;
startTime = _CP0_GET_COUNT();
delayCount = d * TICK_PER_MS;
while((_CP0_GET_COUNT() - startTime) < delayCount);
}
TICK_PER_MS は、1ミリ秒当たりの CP0レジスタの増加量が格納されることになります。
_CP0_GET_COUNT() 関数は CP0 レジスタの値を返す、組み込み関数です。
dミリ秒経過したら この関数を抜けるような作りになっています。
CPUクロックが速いので、長い待ち時間を設定してCP0レジスタのオーバーフローさせないように注意してください。(注意のしようがないか...)
PIC32MX へ書き込み
変更した main.c を保存後、下の矢印ボタンを押して、コンパイルから書き込みまで一気にやってしまいましょう。Pickit3 を ICSPにさしておくのを忘れずに。
エラーなく書き込みまで終われば、下記のようなメッセージが Output に出てきます。
ちゃんと、LED が 1秒ごとに点灯・消灯を繰り返しています。
まとめ
今回は、USB Host評価を念頭に置いた MPLAB X IDE 6.20 の一連の作業を習得すべく LED点滅をさせました。 MCC や Harmony の生成コードがほとんどない状態なので、見通しよく PIC32MX の書き込みまで至ることができました。
今後は少しずつ機能を増やしたもので実装していこうと思います。