前回作成したプログラムの動作確認と、MPLAB X IDEのデバッグ機能の使い方を確認します。
これから行うこと
なんだか結構大変でしたが、温湿度・気圧センサーとSPI通信をしてIDを取得するプログラムを作成しました。
取得したIDが正しいかどうかはLEDの色で表示しますので、最初のプログラムの動作を確認します。
LEDの色で結果が判定できますが、それとは別にMPLAB X IDEの「デバッグ機能」を使って、本当にIDが正しく取れているか確認します。(今は「デバッグ」について分からなくて大丈夫です)
そこで、今回の記事では次の順番で進めていきます。
最初に、前回作成したプログラムの動作確認を行います。
プログラムの動作は、温湿度・気圧センサーは0xD0番地に保存されているIDを取得して、正しい値(=0x60)であればLEDを青色に点灯、違っている場合は赤色に点灯するという処理です。
次に、MPLAB X IDEのデバッグ機能を利用して、プログラムの動作を途中で止めて、実際に取得したIDの値を確認してみます。
この作業を通して、デバッグ機能の基本的な使い方を確認します。
プログラム動作確認
それでは、前回作成したプログラムをPICマイコンに書き込んで、動作確認してみます。
といっても何か派手な動きをするわけではなく、電源を入れるとLEDが点灯するだけなので、ちょっと寂しいですね。
実際に動作させると、次のようにLEDが青に点灯しました。

もし、LEDが赤に点灯したら、温湿度・気圧センサーの接続と、LEDの接続を確認してみてください。
特にLEDの接続については注意が必要です。
LED本体から3本のリード線が出ていて、中央がGNDで両側が青と赤のLEDに接続されています。向きを逆にすると逆の色で点灯しますので、接続向きを確認するようにしてください。
デバッグ機能とは?
今回の確認では、温湿度・気圧センサーから正しくIDが取得できたかどうかという二択ですので、LEDの色で識別することができました。
例えばですが、取得した湿度の値を確認したい場合など、数値自体を確認したいケースもありますよね。
その場合はLEDの点灯状態で判別するのはかなり無理があります。
他にも、作成したプログラムが動作しない場合、PICマイコンの中で何が起こっているのか知りたいケースもありますよね。(自分の場合、記事に載せている大半のプログラムは、一発でうまく動くことはほとんどない、という現状です…!)
このようなときは、MPLAB X IDEの搭載されいる「デバッグ機能」が便利です。
デバッグ機能を利用すると、作成したプログラムを1行1行実行しながら、PICマイコンの中でプログラムがどのように動いているか確認することができます。
また、1行1行動作させている最中に、変数の値を確認することもできます。
と説明されても、いまいちどうやって確認できるのか具体的なイメージが湧かないですよね。
そこで、習うより慣れろということで、作成したプログラムを使用してデバッグ機能を動かしてみます。
ところで「デバッグ」ってちょっと不思議な言葉ですよね。
昔、プログラムが動作しないとき、プログラムに「虫」(=Bug・バグ)がいてそれが悪さをする、と考えていました。
プログラムの修正作業は、その虫を取る作業と捉えて、「Bug」に「De」(日本語で「除去する」という意味)をつけて、「Debug」と呼び、日本語でもそのままデバッグと呼ぶようになったようです。
デバッグで行うこと
プログラムのmain関数内では、次のように温湿度・気圧センサーのIDを取得しています。(28行目)
void main(void) {
// 動作周波数設定
OSCCON1bits.NDIV = 0b0000; // 分周1:1
OSCFRQbits.HFFRQ = 0b010; // 4MHz
// SPI通信用ピン属性設定
ANSELC = 0b00000000;
TRISC = 0b01000000;
// LED用ピン属性設定;
ANSELB = 0b00000000;
TRISBbits.TRISB0 = 0;
TRISBbits.TRISB1 = 0;
// SPI信号線初期設定
SPI_SCK = 0; // クロックを0
SPI_MOSI = 0; // 送信データを0
SPI_CSB = 1; // チップセレクトを1(=無効)
// LEDをOFF
LED_BLUE = 0;
LED_RED = 0;
// 0xD0に格納されているチップIDを読み取る
uint8_t chipid = 0x0;
chipid = spiRead1ByteData(0xD0);
if( chipid == 0x60 ) {
LED_BLUE = 1;
} else {
LED_RED = 1;
}
// ここで動作停止
while(1){
}
}
これから、デバッグ機能を使って、実際にPICマイコンの動作中にchipid
の値がどのようになっているのか確認してみます。
これから、PICマイコンを実際に動作させて、spiRead1ByteData
関数を実行したあと、chipid
にどのような値が格納されるか確認してみます。(0x60のはずですよね)
ところで、MPLAB X IDEは、PICマイコンの動作中にPICマイコンの中の内部状態を確認します。
そのため、デバッグ中はPICkitでPCとPICマイコンを接続したまま使用することになります。
PICkitを接続すると物理的に安定しないことがありますよね。
デバッグ中は両手が空くように、PICkitをうまく固定できるようにしておくと良いと思います。
デバッグ手順の概要
デバッグ機能を使用する場合、通常のプログラム書き込み手順とは異なります。
デバッグ機能を使用する場合、手順の概略は次のようになります。
PICマイコンの中で何が起こっているのか知るために、プログラムの実行をどこかで止め、そのときの変数の値などの内部状態を確認することになります。
そのため、デバッグを開始する前に、プログラムのどこで動作を一時停止するか設定します。
この「動作を一時停止する位置」のことを「ブレークポイント」と呼んでいます。(日本語では「止める地点」という意味合いです)
ブレークポイントを設定したら、デバッグを開始します。
通常のプログラム書き込みでは、MPLAB X IDEの「書き込みボタン」をクリックしますが、デバッグを行う場合「デバッグ開始ボタン」をクリックします。
デバッグを開始すると、プログラムが書き込まれて動作を開始します。
動作開始後、PICマイコンはブレークポイントで動作を一時停止しますので、そのタイミングで変数の値の確認などを行います。
それでは、それぞれのステップを確認していきましょう!
Step 1. ブレークポイントの設定
デバッグを開始する前に、プログラムのどこで動作を一時停止するか指定します。
今回はchipid
の変数の値を確認しますので、次の行にブレークポイントを設定することにします。
chipid = spiRead1ByteData(0xD0);
それではこの行にブレークポイントを設定しましょう!
設定は、次のようにブレークポイントを設定する行の行番号をクリックします。

行番号をクリックすると、行番号が四角の記号に変わり、行が赤色でハイライトされます。
これがブレークポイントが設定されている表現になります。
Step 2. デバッグ開始
次に、PICマイコンにデバッグ実行してもらいます。
今までは書き込みボタンをクリックしていましたが、デバッグの場合は次の「デバッグ実行」のボタンをクリックします。(右側にある小さい▼部分をクリックするとメニューが表示されます。その場合は「Debug Project」を選択してください)

もし、上のデバッグボタンが見当たらない場合、ボタンが隠れています。
その場合は、ウィンドウサイズを大きくするか、次のように マークにマウスカーソルを合わせるとボタンが表示されます。

デバッグボタンをクリックすると、最初に次のダイアログが表示されます。

このダイアログでは「ソフトウェアブレークポイントを使用するか?」と聞いています。
この内容を理解するにはPICマイコンのハードウェア知識が必要です。ほとんどのケースで「Yes」ボタンをクリックして問題ありませんのでYesをクリックして先に進めます。
ダイアログの英文は、(だいたい)次のような内容です。
ハードウェアブレークポイントが一つだけあります。さまざまなデバッグを行う場合、ブレークポイント一つでは足りません。
ソフトウェアブレークポイントを使用しますか?
要するに、「ハードウェアブレークポイント」と「ソフトウェアブレークポイントのどちらを使うか?と聞いています。そこで、これらの違いを簡単に説明します。
デバックを行うためには、PICマイコンの動作を一時停止する必要があります。そのためには特殊なハードウェア機構が必要になります。「ハードウェアブレークポイント」とは、その特殊なハードウェア機構のことを指しています。
この「ハードウェアブレークポイント」は、文字通りPICマイコン内部のハードウェアで構成されていますので何個も用意することはできません。例えば上のメッセージではハードウェアブレークポイントは一つしかない、と言っています。
ところで、デバッグを行う場合、プログラムを一時停止したあと、プログラムを1行ずつ実行することがあります。このとき、1行ずつ実行するためにさらに別のハードウェアブレークポイントが必要になります。
ハードウェアブレークポイントが一つしかない場合、プログラムを一時停止することはできますが、そのあとの1行ずつ実行する、ということができなくなってしまいます。
これとは別に「ソフトウェアブレークポイント」という仕組みがあります。
これは、ソフトウェア的にブレークポイントの制御をしますので、何個でも用意することができます。
このソフトウェアブレークポイントは、MPLAB X IDEがブレークポイントの位置の命令を一時的に書き換えてデバッグできるようにしています。
実際のデバッグでは、基本的にはソフトウェアブレークポイントで問題ありません。
ただし、ソフトウェアブレークポイントを使う場合、デバッグ用に一時的にプログラムが書き換えられてしまいます。
例えば、マイクロ秒単位でのタイミングが非常に重要で、プログラムの書き換えによるわずかな遅延も許容できない場合、ソフトウェアブレークポイントではうまくデバッグできないことがあります。
そのような場合はハードウェアブレークポイントを使用します。
次に、書き込み時の電圧について確認があります。

これは通常のプログラム書き込みの時にも表示されますよね。
今回は外部電源を使用して、PICkitから電源供給しませんので問題ありません。
OKをクリックします。
さらに確認があります。

このダイアログの内容は、プログラムに書いてあるコンフィグレーション設定を一時的に変更して良いか?という確認です。
日本語では、「「現在のプログラムのコンフィグレーション設定では、PWRT
がEnable
になっていますが、これらはデバッグ時には、Disable
にする必要があります。一時的に変更して実行しますがいいですか?」という内容です。
この変更は、デバッグ実行時のみMPLAB X IDEが一時的に変更するだけで、作成したプログラムを書き換わるわけではありませんので、Yesをクリックして進めます。
クリックすると、プログラムをビルドして、書き込み、デバッグモードで実行します。
すぐにブレークポイントで一時的に動作が止まり、次のようにPICマイコンは待機状態になります。

一時停止した時点のPICマイコンの状態が確認できますので、chipid
の値を確認しましょう!
Step 3. 変数の値の確認
それでは、変数chipid
の値を確認しましょう!
確認方法は3通りありますので、それぞれの方法で確認してみます。
なお、デバッグ方法に関して重要な操作がありますので、「❶ 変数名にマウスカーソルを合わせる」からご確認いただければと思います。
❶ 変数名にマウスカーソルを合わせる
最初の方法は、chipid
という変数名にマウスカーソルを合わせます。
カーソルを合わせて1〜2秒待っていると、chipid
の内容がツールチップとして次のように表示されます。

ツールチップ部分は「Address = 0x75, chipid = NULL; 0x0
」と表示されています。
この意味は、「chipid
という変数は、メモリのアドレス0x75番地に格納されていて、その値は0x0」という意味です。
温湿度・気圧センサーのIDの値は0x60ですが、chipid
の値は0になっていますので正しくデータが受信できていないのでしょうか?
実は、「ブレークポイントで一時停止した状態」というのは「その行をこれから実行する状態」なんです。つまり、まだspiRead1ByteData()
は実行されていないんです。
そこで、この行を1行だけ実行してみます
ブレークポイントの行を1行だけ実行して次に進めるには、次のボタンをクリックします。(このボタンは「ステップオーバー」というボタンで、詳細は次回の記事で解説します)

なお、このボタンが見当たらない場合、ボタンが隠れています。
その場合は、ウィンドウサイズを大きくするか、次のように マークにマウスカーソルを合わせるとボタンが表示されます。

1行実行すると、次の行で一時停止した状態になります。

これで、spiRead1ByteData()
が実行されましたので、変数chipid
に正しい値(0x60)が格納されているはずです!
先ほどと同じように変数の値を確認してみます。

無事、0x60になっていることが確認できました!
❷ Variablesウィンドウで確認
次の方法は、「Variablesウインドウ」で確認する方法です。
MPLAB X IDEの下の方にウインドウがいくつか並んであると思いますが、その中に「Variables」というウインドウがあるはずですので探してみてください。
見つからない場合は、MPLABX IDEメニューの「Window」→「Debugging」→「Variables」を選択してください。
このウインドウを確認すると、次のように変数の値が表示されています。(クリックすると拡大できます)

❸ Watchesウィンドウで確認
最後の方法は、Watchesウインドウを確認する方法です。
先ほどのVariablesウインドウの並びに「Watches」ウインドウがあると思いますので探してみてください。
見つからない場合は、MPLABX IDEメニューの「Window」→「Debugging」→「Watches」を選択してください。

先ほどの2つの方法とは違って、何も表示されていませんよね。
このウインドウでは、自分で確認したい(Watchしたい)変数などを登録しておく必要があります。
それでは変数chipid
を登録してみましょう。
次の部分をダブルクリックします。

次のダイアログが表示されますので、変数名chipid
と入力してOKボタンをクリックするとchipid
が登録されて、中身の確認ができるようになります。

なお、ダブルクリックの間隔が長い場合(ゆっくり2回クリックした場合)、次のように変数名の欄に直接変数名を入力するモードになります。
次のようにchipidと入力しても登録することができます。

デバッグの終了
これでデバッグ機能を使用してchipid
の確認ができました。
PICマイコンはまだ処理を一時停止しています。
この後にさらにプログラムがあり処理を継続させたい場合は、次のContinueボタン(処理継続ボタン)をクリックします。

Continueボタンをクリックすると、プログラムの処理を続けます。
今回のプログラムはこの後while(1){}
ですので、実行は続けても何も変化はありません。
最後に、デバッグを終了する場合は、以下のFinishボタン(デバッグ終了ボタン)をクリックします。

以上が典型的なデバッグの手順です。
デバッグ機能は他にも色々な機能があります。
次回の記事で、このプログラムを使用して他のデバッグ機能の確認を行います。
更新履歴
日付 | 内容 |
---|---|
2018.5.6 | 新規投稿 |
2025.8.1 | MPLAB X IDE Version6.25対応 |
有用な情報をいつもありがとうございます。
紹介されている部品をなるべく揃えて記事を参考に1つずつ進めているところです。
私も3年前のteruさんと同じように赤い■が破れた柄になりRunningのままになりました。
■開発環境
Windows10
MPLAB X IDE 6.15
XC8 v2.46
PicKit5
1) Break Pointで止まらない件
→ while(1){
で止めようとすると止まらずに、
2行に渡っているwhile文を下記のように1行に書き換えると止まりました。
→ while(1){ }
複数行行に渡っている文の1行目だけをBreak Pointに出来ないような気がします。
試しにwhile文の直前に適当に
→ __delay_ms(100);
を追記してBreake Pointに設定すると止まったので、
上記の1文1行にすることを思いつきました。
2) chipidの中身を見ようとすると”Not Recognized”になる件
1)で止まるようになったけど、変数が読めない件は
管理者殿の解説通りなのかな?と思いました。
main関数の外に、chipidをグローバル変数としてvolatile無しで
”uint8_t chipid = 0;”
と定義しても、記事の通りに変数の中身が読めるようになりました。
追記
プログラムの中で作っている3つのユーザー関数は
1バイトの返値を期待していると思うのですが、
モニターしてみると2バイトで戻ってきているようです。
追加情報でした。
しゅう☆さま、
貴重な情報をいただきどうもありがとうございます!
1) whileのブレークポイント
while文を1行で書くと止まるという情報は知りませんでした…
このあたりは、ソースコードと生成された機械語の対応関係で何かあんでしょうかね。すみません、謎解明はできませんでした。
2) chipid
chipidをグローバル変数にすると、確実にメモリが確保されるようですね。volatileをつけるより素直な解決方法のような気がしました。
また、追加情報についてもどうもありがとうございます。私の方でも確認してみようと思います。
このようなコメントをいただけて本当に感謝いたします。
私自身もそうですが、他の方の参考にもなるのでとても貴重です。ありがとうございます。
それにしてもマイコンの世界は奥深いですよね。趣味といいますかライフワークとしてずっと楽しめますよね。
お忙しいところコメントどうもありがとうございました!
いつもツールラボ様のサイトで勉強させていただいてます。
見よう見まねでここまできました。
以前、他の方と同じ内容の相談になるのですが、私のほうでもデバックができなくて困っています。
通常であればデバックすれば、赤色四角のアイコンで止まりchipidのアドレスがわかるはずなのですが、私のほうではツールラボ様と同じアイコンではなく、赤色四角が破れたような形のアイコンになっており、pick3の動作コメント欄にはrunningのままになっています。
現状は、1の方法ではchipidにカーソルを合わせるとchipidとだけ表示され、2・3の方法でも何も進展がない状況です。
なにかわかりましたらお返事いただけると助かります。
なお私のパソコンで使っているMPLABはv5.40で、xc8はv2.20となっております。
あと、第21回のブレッドボード回路の動作確認はできています。
私のほうで疑問に感じる事があるのですが、デバックを始めるとuint8_tなどに赤色の波線がつくのですが、これは何か関係があるのか気になっています。
よろしくお願いします。
ご質問どうもありがとうございます。
こちらでMPLABX IDE v5.40 + XC8 v2.20で確認したところ、chipidはunrecognized(認識できない)という状態でした。
この原因ですが、chipid変数は値を代入するだけでその後何もしないので、コンパイラによっては「この変数はあってもなくても動作に関係ないだろう」という判断がされてしまい、PICマイコンに書き込むコードから削除されてしまいます。
この状態になると、人間が見るソースコードとPICマイコンで動作しているプログラムに差が出てしまい、結果としてデバッグ時に変数がない状態になってしまいます。
解決方法としてはいくつかあります。一つはコンパイラの設定で最適化をしない、を選択する方法です。もう一つは、プログラム上に最適化しないでくれ、と明示的に書く方法です。
そこで、以下のようにプログラムを変更して試していただけませんでしょうか。
1) chipidの宣言をmain関数の中ではなく、先頭の方に以下のようにグローバル変数で定義する
volatile uint8_t chipid = 0;
2) main関数で宣言しているuint8_t chipid = 0;を削除、またはコメントアウトする
変数宣言時に「volatile」をつけると、メモリ上に変数を確保してくれます。
お世話になっております。
長い間別の作業をしており、お返事遅れまして申し訳ございません。
ようやくデバック作業を開始できましたので確認したのですが、やはり失敗してしまいます・・。
お返事いただきました通り
volatile uint8_t chipid = 0;をグローバル変数で定義し、uint8_t chipid = 0;はコメントアウトはしています。
念のため配線間違いがあるのか、第21回のブレッドボード回路の動作確認をしており、配線は間違いないようなのですが。
電源の確保は、PICKKIT3はパソコンのUSBから(5V)、ブレッドボードには3.3Vを直接流しています。
PICKKIT3からの配線はオスメスジャンパー線でブレッドボードに繋げています。
なお、デバックした後のエラーは下記のようにでています。
Device Erased…
Programming…
The following memory area(s) will be programmed:
program memory: start address = 0x0, end address = 0x7ff
configuration memory
program memory
Address: 0 Expected Value: 3180 Received Value: 0
Failed to program device
お手数をおかけしますが、よろしくお願いします。
情報どうもありがとうございました。
いただいたエラーログをみると、PICマイコンへの書き込みに失敗しています。そこで大変お手数なのですが、LEDを点滅させるような簡単なプログラムの書き込み、動作ができるかご確認いただければと思います。
エラーログの最後の行は「3180を書き込んだはずなのに、読みだすと0になっている」という内容で、プログラムがうまく書き込めていないというエラーになっています。
返信が遅くなり申し訳ございません。
いろいろと手こずっており遅くなりました(・・;)
ようやく無事にデバック出来ましたことをご報告させていただきます。
出来なかった原因といたしまして、PICKKITの配線に問題がありました。
アドバイスいただいた通り、まず簡単なプログラムを書き込もうとしたのですが、なぜか出来ずエラーも同じものが出てましたので、これは配線ミスか・・と疑いやり直したところ無事にできました。
初歩的なミスでお手間をとらせてしまい申し訳ありませんでした。
ただプログラムを書き込める状態になっているのもかかわらず、何故かうまくいかなかった原因が今もわかりません。
と言いますのも、デバック停止位置が
while(1)では、ずっとrunnig状態でデバックできず
chipid = spiRead1ByteData(0xD0);のところで停止すると出来たことです。今回~chipidをグローバル変数で定義していることと関係があるのでしょうか。謎のままです。
結果的にアドレスに0X60が表示されましたので、私は大満足しております。
本当にありがとうございました。
はじめてご連絡させて頂きます。
32回のBME280の動作確認プログラムにて確認作業をしているのですが
どうも上手くIDの読み込み確認が出来ません。
57歳おっさんの冷や水なのですが、ご指導頂けると助かります。
PCのOSはWindows7にてMPLAB X IDE v5.25 です。
どうか宜しくお願い致します。
因みにFBでも全く同じ内容で投稿させて頂きました。
ご回答が遅くなり申し訳ございませんでした。
「IDの読み込みができない」というのは、この記事のデバッグ手順で、変数chipidの中身が0x60にならない(0x00になっている)という状況でしょうか。
chipidが正しく取得できない場合、SPI通信がうまくできていない可能性がありますので、まずは完成プログラムを書き込んで気象データが正しく液晶ディスプレイに表示されるかご確認いただければと思います。
完成プログラムが動作しているのに、chipidが正しく取得できない場合はプログラムやデバッグの問題の可能性があります。また完成プログラム自体が動かないのであれば、回路の問題も考えられます。
お手数ですが、まずは問題の切り分けをしていただければと思います。
ご回答ありがとうございます。
私も通知が来ず、分かりませんでした。。
PICはAliexpressで購入したもので、16F628Aとなっているしプログラムもその設定で書き込んでいますが、中華製なので中身がA無しを使われている可能性もありますね。
表の見方が分かりましたので、今後はそこで確認したいと思います。
いつも連載で勉強させて頂いています。

PICによってMPLABでのデバッグができるものとできないものがあるようなのですが
それをどこで調べればよいか教えて下さい。
PIC16F628Aが安めに売っていたので購入しプログラムして、いざデバッグしようとすると
「A debug header is required to debug this device」と表示されデバッグできません。
検索してみると、デバッグヘッダーという器具を使わないといけないということでした。
参考ページ:http://yak-shaver.blogspot.com/2013/09/pickit3-debug-header.html
ところが、ここに書かれている文書「Processor Extension Pak and Header Specification」が
メーカーのページにも無くて参照することができません。
それで「Device Support」の一覧表を見てみるとICDデバッグが「サポート」となっていて
記述が合わないのです。
実際デバッグできないので、記述が間違っているのではないかとおもうのですが、そうすると
次に買おうとするPICがデバッグできるのかどうか、どうやって調べればいいでしょうか?
各PICのデータシートを見ても書き方がそれぞれバラバラでよく分からないときがあります。
それでもやはりデータシートの記述で確認するしかないでしょうか?
回答が遅くなり申し訳ございませんでした(コメントの通知がきておらず、今気づきました…)
デバッグができるかどうかの情報は添付いただいた画像のファイルになります。このファイルは、MPLABX IDEをインストールすると、ドキュメントフォルダにインストールされますので、ご自身のPCでも確認できます。
なお、添付いただいたファイルの赤枠部分は、Microchip社の「MPLAB ICD」という製品でデバッグできるか、という情報です。
一番上の欄の名前がわかりづらいですが、以下のようになっています。
ICDP: ICDを使ったプログラム書き込み
ICDD: ICDを使ったデバッグ
PK3P: PICkit3を使ったプログラム書き込み
PK3D: PICkit3を使ったデバッグ
16F628Aは、PICkit3/4であればデバッグもできますが、16F628はデバッグができない、ということになります。
デバッグヘッダが要求される、ということは16F268Aではなく628と認識されてしまっている可能性があります。