連載
» 2013年02月05日 08時35分 UPDATE

マイクロマウスで始める組み込み開発入門(10):アナログからデジタルへ、センサーの値をA/D変換して取得しよう! (1/2)

マイクロマウスの市販組み立てキットを完成させた北上くんとえみちゃん。サンプルのソースコードに頼らず、オリジナルプログラムをイチから組もうと奮闘中。今回は、“壁の有無”や“壁までの距離”を検知する「センサー」の値を取得する方法についてだ。

[三月兎,MONOist]

前回のあらすじ

 組み込み技術者に要求される要素が“ギュッ”と詰まった「マイクロマウス」。北上くんと新入社員のえみちゃんは、スキルアップを兼ねてマイクロマウスの開発を始めることにしました。「階層構造」を意識したオリジナルプログラムを開発することになったえみちゃんは、北上くんの指導の下、スイッチやブザーの制御を着々とこなしてきました(前回の記事へ)。


本連載の登場人物

ay_mouse01_man1.jpg
北上 篤人(きたがみ あつと)
26歳、男性。次期プロジェクトリーダーとして期待されている(と、本人は思っている)。専門は、ソフトウェア開発。電気回路やハードウェアに苦手意識を持っていて、いつか克服したいと考えている。

ay_mouse01_woman1.jpg
物江 えみ(ものえ えみ)
22歳、女性。この4月に入社したばかりの新入社員。C言語は大学の授業で学んだ程度なので、仕事についていけるかどうか不安を抱えている。性格は明るく、好奇心旺盛。早く一人前になりたいという強い熱意を持っている(ようだ)。



マイクロマウスに搭載されている「センサー」の仕組み

――ピンポーン! (チャイムの音)

えみ

こんにちはー!


北上

おぉ、いらっしゃい!!


えみ

センパイ、今日は「センサーの処理をする」って言ってましたけど、一体どんなことをやるんですか〜?


北上

マイクロマウスに搭載されている「センサー」の値を取得して、PCのモニターに表示させるんだよ。


えみ

あれ?

それって確かマイクロマウスのハードウェアを組み立てた後にやりましたよね?


北上

うん。でもあの時は、サンプルのソースコードを使ったよね。今度は、自分のプログラムでやるんだよ!! ここを自分の手でやっておけば、「A/D変換」と「シリアル通信」の方法が理解できるはずだよ。


えみ

A/D変換? シリアル通信? う〜ん。聞いたことはあるけど、何だっけ……?


北上

とにかく、いつものように始めよう!

まずは、センサーの値をA/D変換して、取り込んでみようか。


えみ

はーい!



 今回は、“壁の有無”や“壁までの距離”を検知する「センサー」についてです。通常、センサーを使って測定した値をマイコンに取り込む場合、アナログ値をデジタル値に変換する処理「A/D変換」が必要です。また、その値をユーザーが読み取るには、「シリアル通信」を使って、PCのモニターに表示させなければなりません。マイコンプログラミングをする上で、このA/D変換とシリアル通信は、避けて通れません。今回の内容でA/D変換について、そして、次回の内容でシリアル通信について詳しく解説していきます。えみちゃんと一緒に、理解を深めていきましょう!!

 では、本題に入る前に、ここでマイクロマウスの市販組み立てキット「Pi:Co Classic」に搭載されているセンサーの概要を説明します。

 Pi:Co Classicは、前方に4つのセンサー(赤外線LEDとフォトトランジスタ)を搭載しています(画像1)。発光器であるLEDは、指向性の高いものが採用されており、これをパルス発光させることで、通常よりも遠くまで光を照射します。また、発光量を大きくすることで外乱光の影響を受けにくくしています。

4つのセンサー 画像1 Pi:Co Classicには、前方に4つのセンサー(赤外線LEDとフォトトランジスタ)が搭載されている。走行中に壁の有無や距離を測定する

 受光器であるフォトトランジスタも同様に指向性の高いものが採用されています。フォトトランジスタの受光部がLEDから放たれた赤外線を受けると、エミッタ−コレクタ間に電流が流れます(画像2)。この値を取得することで、光量を測定できます。

エミッタ−コレクタ 画像2 LEDから放たれた赤外線が壁に反射し、フォトトランジスタが受光したときにエミッタ−コレクタ間に電流が流れる(青矢印)

 光量はアナログ値ですから、マイコンに取り込むには、デジタル値に変換しなければなりません。Pi:Co Classicに搭載されているマイコン「SH7125」には、逐次比較方式の10ビット A/D変換器が内蔵されています。Pi:Co Classicは、このA/D変換器により、外部から入力されたアナログ値をデジタル値に変換して、マイコンに取り込みます。

 近ごろ、コンピュータ技術が進化し、世の中が「デジタル化」していると言われますが、私たちの身の回りの音・温度・湿度・光などは、昔も今も変わらずアナログ値なのです。ここで紹介したように、A/D変換器でアナログ値を、コンピュータが扱えるデジタル値に変換することで、これらデータをデジタル機器などに取り込み、利用できるのです。


 マイクロマウスに搭載されているセンサーの仕組みを理解したところで、いつものように、プログラミングに必要な情報をデータシートでチェックしておきましょう(表1、画像3、画像4、画像5)。

基板ポート一覧 表1 基板ポート一覧(※Pi:Co Classic 取扱説明書_ver1.08.pdfより抜粋)
STK-7125回路図のセンサー部分 画像3 STK-7125回路図のセンサー部分
センサー発光部の回路図 画像4 センサー発光部の回路図
センサー受光部の回路図 画像5 センサー受光部の回路図 ※画像クリックで拡大表示

ドライバの作成

えみ

「アナログ」と「デジタル」か〜。正直、これまであまり意識したことなかったです。


北上

組み込み開発をする上では「必須」と言える知識だね。


えみ

うーん。マイコンを扱うには、プログラミング以外にもいろいろな知識が必要なんですねぇ!


北上

実際にモノを制御するわけだからね。まぁ、そこが組み込み開発、マイコン制御プログラミングの面白さだと思うよ!! それじゃあ、早速、センサー処理のプログラムを書いてみよう!


えみ

はいっ!!



 それでは、いつものようにプログラムを作成していきましょう。まずは「init.h」に、A/D変換の設定に関する記述を追加します(ソースコード1)。

void init_adc(void);                //A/D変換 初期化
ソースコード1 「init.h」にA/D変換の設定を追加する

 続いて「init.c」のI/Oポートの初期化部分に、センサーLEDのポート出力設定(ソースコード2)を追加し、A/D変換の初期化(ソースコード3)を新たに記述します。

void init_io(void)
{
 
    ……(中略)……
 
    //センサーLED
    PFC.PAIORL.BIT.B6        = 1;    //PA6を出力に設定(左)
    PFC.PAIORL.BIT.B7        = 1;    //PA7を出力に設定(右)
    PFC.PAIORL.BIT.B8        = 1;    //PA8を出力に設定(前左)
    PFC.PAIORL.BIT.B9        = 1;    //PA9を出力に設定(前右)
}
ソースコード2 「init.c」の「init_io(void)」にセンサーLEDの設定を追加

void init_adc(void)
{
    STB.CR4.BIT._AD0     = 0;       //AD0のスタンバイを解除
    STB.CR4.BIT._AD1     = 0;       //AD1のスタンバイを解除
    //
    AD0.ADCR.BIT.ADST    = 0;       //AD停止
    AD0.ADCSR.BIT.ADF    = 0;       //ADFフラグクリア
    AD0.ADCSR.BIT.ADIE   = 0;       //割込み禁止
    AD0.ADCSR.BIT.TRGE   = 0;       //トリガイネーブル無効
    AD0.ADCSR.BIT.CONADF = 0;       //ADFコントロール(独立ADF)
    AD0.ADCSR.BIT.STC    = 0;       //ステートコントロール(50ステート)
    AD0.ADCSR.BIT.CKSL   = 3;       //周辺動作クロックPφ
    AD0.ADCSR.BIT.ADM    = 0;       //シングルスキャン
    AD0.ADCSR.BIT.ADCS   = 0;       //サイクルスキャンしない
    AD0.ADCSR.BIT.CH     = 0;       //AD0-ch0選択
    //
    AD1.ADCR.BIT.ADST    = 0;       //AD停止
    AD1.ADCSR.BIT.ADF    = 0;       //ADFフラグクリア
    AD1.ADCSR.BIT.ADIE   = 0;       //割込み禁止
    AD1.ADCSR.BIT.TRGE   = 0;       //トリガイネーブル無効
    AD1.ADCSR.BIT.CONADF = 0;       //ADFコントロール(独立ADF)
    AD1.ADCSR.BIT.STC    = 0;       //ステートコントロール(50ステート)
    AD1.ADCSR.BIT.CKSL   = 3;       //周辺動作クロックPφ
    AD1.ADCSR.BIT.ADM    = 0;       //シングルスキャン
    AD1.ADCSR.BIT.ADCS   = 0;       //サイクルスキャンしない 
    AD1.ADCSR.BIT.CH     = 0;       //AD1-ch0選択
}
ソースコード3 A/D変換の初期化

 A/D変換では3種類のレジスタにアクセスし、初期設定を行います。項目は多いですが、CKSL(クロックセレクト)以外は初期値で問題ありません(表2)。CKSLは、「3」を指定すると周辺動作クロック(Pφ)になります。

A/D変換に必要なレジストリ 表2 A/D変換に必要なレジスタ ※画像クリックで拡大表示

 全てのハードウェアの初期化を行うinit_all関数に、A/D変換の初期化を追加します(ソースコード4)。

void init_all(void)
{
 
     ……(中略)……
 
    init_adc();            //ADCの初期化
}
ソースコード4 「init.c」のinit_all関数に、A/D変換の初期化を追加

 これで、A/D変換の準備ができました。

       1|2 次のページへ

Copyright© 2017 ITmedia, Inc. All Rights Reserved.