第18回 プログラム解説 〜 コンフィグレーション部 〜

今回は、プログラムの中のPICマイコンのコンフィグレーション部分を説明します。

本シリーズ記事の内容を改訂して、基礎編、応用編、実践編として以下のリンクに公開しています。以下のシリーズはさらにいろいろなPICマイコンの機能をご紹介しています!

PICマイコン電子工作入門 〜基礎編〜
PICマイコン電子工作入門 〜応用編〜
PICマイコン電子工作入門 〜実践編〜

今回の説明

発光ダイオード点滅回路を完成させるために以下の順序で説明しています。このエントリの説明は(3)「プログラムを作る」の部分の、プログラム作成のステップになります。

  1. 発光ダイオード(LED)を電池と抵抗のみで光らせる回路を組む
    PICマイコンの回路を組む前に、まずは電池、抵抗、発光ダイオードのみを使って、ブレッドポード上に回路を組んで発光ダイオードを光らせてみます。ここでは電池、抵抗、発光ダイオードの回路記号、回路図と、回路図からブレッドボードに組む方法を説明します。
  2. PICマイコンのベース回路を組む
    はじめの一歩の回路は、発光ダイオードを1秒に1回光らせるだけの回路です。この回路を組みます。
  3. プログラムを作る
    発光ダイオードを1秒に1回光らせるプログラムを作成します。
  4. PICマイコンに書き込んで動作させる
    作成したプログラムをPICマイコンに書き込んで動作させてみます。
  5. ベース回路にスイッチを追加
    発光ダイオードの点滅をスイッチで開始させるために、ベース回路にスイッチを追加します。これまでは発光ダイオードを光らせる、という出力制御をしましたが、PICマイコンで外部から信号を入力する方法を確認します。
  6. ベース回路にブザーを追加
    スイッチ付きの1秒に1回光らせる回路を作りましたので、ブザーを追加してタイマーを作ってみます。

 

PICマイコンコンフィグレーション設定の概要

今回はプログラムのPICマイコンコンフィグレーション設定部分を説明します。

このコンフィグレーション設定部分では、PICマイコンの基本動作関連の設定を行います。「基本動作」って言われても何のことかわかりませんよね。この設定のすべての項目の説明は後ほど行いますが、例えば以下のような設定を行います。軽くイメージをつかんでいただければと思います。

[クロック設定]
例えばMacOSXの左上Appleメニューから「このMacについて」というメニューを選択するとこんなダイアログが表示されますよね。

System profile

このダイアログの「プロセッサ」と書いてあるところに「2.8GHz」とありますが、これはこのMacのCPUクロック周波数が2.8GHz、ということを意味しています。CPUはこのクロックをタイミングとして処理を進めていきます。もちろんクロック周波数が高いほど処理速度が高くなります。

PICマイコンもクロックをタイミングとして処理を進めていきます。なお、このクロックをPICマイコンにどのように供給するのか、その方法として2通りあります。PICマイコンの外部にクロック信号を発信する電子部品用意して、PICマイコンのクロックのピンにそれをつなげる方法(外部供給方法)と、PICマイコン内部のクロック発振器を使う方法(内部供給方法)です。この「クロック設定」では、クロックをどのように供給するかを設定します。例えば内部クロックを使用する、などという設定を行います。

[ブラウンアウト設定]
PICマイコンは3.3Vや5Vで動作しますが、何かの原因で電源電圧が低くなることがあります。それは電源の故障だったり、電源の電池がなくなってきたときなどです。このように電源の電圧が低くなってくると、PICマイコンの動作が不安定になってきます。以前説明しましたが、発光ダイオードの点滅制御などでは、点滅がおかしくなる程度で済みますが、モーター制御している場合などは危ない動作になる可能性もあります。

電源の供給電圧が低くなることをブラウンアウトと呼び、この「ブラウンアウト設定」では、ブラウンアウトが発生したときに、例えばPICマイコンの動作を一時停止する、などの設定を行います。

非常におおざっぱですが、このコンフィグレーション設定部分でどんな感じの設定をするかイメージつかめていただけたでしょうか。

他にもいろいろ設定がありますが、この後すべてを詳しく説明していきます。なお、説明するコンフィグレーション設定は、PIC12F683のものですが、もちろん他のPICマイコンでも同様の設定があります。ただしすべてのPICマイコンでこれらの設定項目が同じ、というわけではありません。高機能のPICマイコンになると、これ以外にも設定項目が追加されていたりします。ただ、PIC12F683の設定項目はどのPICマイコンにも見られる基本的なものですので、是非一通り確認いただければと思います。

それでは早速、それぞれのコンフィグレーション設定項目を説明します、といきたいところですが、その説明する前に

#pragma

について説明します。

 

#pragmaとは

コンフィグレーション設定部分を見ると、例えば、

#pragma config FOSC = INTOSCIO

という記述がありますよね。これは、PICマイコンコンフィグレーション設定のうち「FOSC」(クロック設定)という設定項目を「INTOSCIO」(内部クロック)に設定する、という意味になるのですが、そもそもその前の #pragma とか config って何なんでしょうか。(FOSCやINTOSCIOは後ほど詳細に説明します)

この入門記事の一番始めに、記事の中ではC言語自体は説明しないので、

これらの項目については予め確認しておいてください、と書いていました。そのためプログラムの説明では、これらの項目は知っているものとして説明をしてきました。ただ、この #pragma についてはC言語入門の部分ではあまりでてこないのですが、PICマイコンのプログラムではコンフィグレーション設定に使用されています。つまりMPLABX + XCコンパイラを使う限り、どんな簡単なプログラムでも避けて通れない構文となっています。そこでC言語入門部分ではあまり説明されない、#pragma についてここで詳しく説明しておきます。

この#pragmaは、難しく言うと、特定のコンパイラや特定の統合開発環境に特化した命令を記述するための指示子ということになります。と言ってもすんなりわかった、という感じではないと思いますので、「特定のコンパイラ」と「特定の統合開発環境」の2つのケースについてそれぞれ具体例を説明しますので、それらを元に #pragma の働きのイメージをつかんでいただければと思います。

まずはコンパイラの例です。ここでは、XC8コンパイラ(特定のコンパイラ)がコンパイル時に、

#pragma config FOSC = INTOSCIO

という文をどのように解釈するか説明します。

まず、XC8コンパイラはコンパイル時に、”#pragma”という文字列を見つけると「自分向けに特化して書かれた何かが、このあとに書かれているかもしれない」と判断します。次に #pragma の後に、config という文字列を見つけると、「あ〜、configね。configってことは、PICマイコンのコンフィグレーション設定をしたいんだね。さらにconfigの後には[設定項目] = [設定値]とかかれているはずだから、その後もみてみよう」と判断していきます。それで実際その後に FOSC = INTOSCIOと書かれているので、FOSC(クロック設定)はINTOSCIO(内部クロック)に設定する、という処理を行います。

ところで、”#pragma config FOSC = INTOSCIO”というXCコンパイラ向けの記述があるソースコードを他のコンパイラでコンパイルしたらどうなるのでしょうか。例えば、MacOSXやiOSのアプリを開発するXcode上で、ソースコードにこの記述をしてビルドしてみると、、、何も起こりません。Xcodeでビルドを実行すると、裏ではLLVMというコンパイラがプログラムをコンパイルします。コンパイル時にこのLLVMコンパイラが “#pragma” を見つけると、自分宛に特別な何かが書かれているかもしれない、と判断します。#pragmaの次を見ると、config、とありますが、LLVMコンパイラはこのconfigは何のことか知りません。そこで、この記述は他のコンパイラ向けに書かれたものなんだな、と判断してこの記述は無視する、という動作をします。なお、#pragma の後に書かれている文字列が、自分が理解できない場合、エラーにするコンパイラもあります。(次の説明でこの例がでてきます)

次に統合開発環境の例です。PICマイコン関係から外れてしまいますが、MacOSXやiOSアプリを開発するための統合開発環境、Xcode(特定の統合開発環境)の具体例を説明します。

サンプルとして、function_a()、function_b()、function_c()とmain()関数があるプログラムを作ります。以下のような感じです。

Base Program

このサンプルでは、各関数は何もないので非常に短く、スクロールしなくても全体のプログラムを表示できてしまいますが、もしこのプログラムが非常に長い場合に、例えばfunction_c()を編集したい場合、いちいちfunction_c()が表示されるまでスクロールするのは大変ですよね。そこで、一発でfunction_c()の部分を表示するショートカットがあります。以下の画面の赤枠部分をクリックすると、、、

Function search

関数の一覧が表示され、

Function search popup

例えばここでfunction_c()を選択すると、function_c()の部分が表示されます。(実際はすでに表示されていますので何も変化がありませんが)

ところで、この関数の数か多くなってくると、このメニューの表示項目数も増えて、メニューから探すのすら大変になるかもしれませんよね。そこで、関数を分類しておくことができます。まず、function_a()、_b()、_c()を「ユーティリティ関数」、main()を「メイン関数」と分類しておきたいとします。このような時は、分類したい関数の先頭のところに、

#pragma mark [分類名]

と記述します。例えば、以下のように記述してみます。

Pragma

なお、「メイン関数」の記述の一行前に、

#pragma mark –

も記述しておきました。これらの記述をするとどうなるかというと、、、

Function search pragma

このように、function_a()の一つ上に、#pragma markで指定した「ユーティリティ関数」という文字列が表示されます。さらに、main()の一つ上に、#pragma markで指定した「メイン関数」という文字列が表示されます。さらに、「メイン関数」の一つ上に区切り線が入っています。これは、#pragma mark – で指定したものです。

この#pragmaの使い方は、始めに説明したXCコンパイラとはちょっと違いますよね。XCコンパイラはコンパイルするときに、その過程で#pragmaを見つけると、特定の処理をしていました。

しかし、Xcodeでは、コンパイルを指示したときではなく、随時#pragmaが認識されています(正確にいうと、裏でLLVMが部分コンパイルしてその結果をXcodeがもらってこのように処理しています)。

つまり、#pragma mark、という記述は、Xcodeが関数ジャンプメニューを表示するときに、メニューに分類文字列を表示するために使用されている構文です。ちなみに、この#pragma markという記述をMPLABX上で記述してビルドすると、エラーになります。MPLABX(XC8コンパイラ)は、#pragmaの後の文字列が解釈できないと、エラーにする、という仕様のようです。

ちょっと余計な説明が多かったですが、#pragma、というのは特定のコンパイラや特定の統合開発環境に対して、それらに特化した特定の処理を指示する、ということがおわかりいただけたでしょうか。(なかなかうまく説明できないのでわかりづらかったと思いますが、、、すみません)

次回、各コンフィグレーション設定の説明を行います。

 

更新履歴

日付 内容
2015.9.22 新規投稿
2018.12.3 新シリーズ記事紹介追加