「周辺機能」を学ぼう:1 of 6
マイコンを活用するための周辺機能の仕組みや使い方を全6回連載で解説します。
さまざまなマイコンで共通の基本的な周辺機能を学ぶので、幅広く応用することが可能です。
CPUとメモリだけでは動かない!マイコン活用に必須の「周辺機能」とは
過去の連載「マイコン入門編」で解説したように、電子機器の制御を行うマイコンは、CPUとメモリ、周辺機能で構成されています(図1)。CPUは命令(プログラム)に従って、演算やデータの読み書き、条件判断などを行います。メモリには、そのプログラムを格納(記憶)します。
周辺機能は、マイコンを便利に使うためのさまざまな機能です。例えば、CPUと外部のセンサやスイッチなどの信号のやり取りをするために、周辺機能である「入出力ポート(I/Oポート)」が必要です。
また、アナログの入力信号をデジタルの値に変換する「A/Dコンバータ」や、逆に、デジタルの値をアナログの出力信号に変換する「D/Aコンバータ」は、マイコンがさまざまな信号を扱うために不可欠な周辺機能です。
他にも、正確な時を測るのに使う「タイマ」や日付や時刻を刻んでいる「リアルタイムクロック(RTC)」は、時間に関わる処理に役に立ち、並列(パラレル)信号と直列(シリアル)信号を相互に変換する「UART(ユーアート、Universal Asynchronous Receiver Transmitter)」は通信に便利です。
本シリーズでは、このようなマイコンを便利に使うための周辺機能の基礎を、ルネサスのマイコン「RX63N」を例にして解説します。プログラムは、「RX63N」を搭載した電子工作ボード「GR-SAKURA」を用いて説明しますので、ぜひ実際にお試し下さい!
デジタル信号の出入り口「GPIO」を理解しよう
「入出力ポート(I/Oポート)」のうち、デジタル信号の出入り口である「GPIO(General Purpose Input/Output)」は、「汎用I/Oポート」とも呼ばれ、入力にも出力にも使える便利なデジタル信号の出入口です。デジタル出力のセンサの値やスイッチのON/OFFをマイコンに伝える入力や、マイコンの演算結果をLEDで表示したり、モータを動かす信号を出力したりする時などに利用します。
GPIOが汎用と呼ばれる大きな理由は、端子を入力用にも出力用にも使えるからです。初期のマイコンでは、端子の役割が入力か出力に固定されていましたが、今では多くのマイコンで入出力を自由に設定可能です。仮にGPIO端子が8本であれば、4本を入力、4本を出力として使うこともできますし、入力は1本で出力は7本といった使い方も可能です。
GPIOでは、CPUと外部装置でデータの受け渡しをするために、プログラムで扱うデジタル値(0または1)と信号(電圧のLOWレベルまたはHIGHレベル)の変換を相互に行います。RX63NマイコンのGPIOの基本となるレジスタ(※1)の役割を理解しましょう(図2)。
(※1)レジスタ(Register):マイコンのCPUや周辺機能の内部に存在する記憶回路。演算やCPUの実行状態の保持に使用する。CPU・周辺機能の内部回路のため、メモリへ書き込んだり、読み出したりするより高速に動作するが容量は小さい。さまざまな用途に使えるもの(汎用レジスタ)と機能や用途が限定されているものがある。
- ポート方向レジスタ(PDR)
端子の方向を決定するためのレジスタで、「方向レジスタ」とも呼ばれます。
- ポート入力データレジスタ(PIDR)
入力で使う端子の状態を反映するレジスタです。端子からLOWレベルまたはHIGHレベルを入力すると、0または1の値に変換した結果として読み取ることができます。端子の変化に合わせて値も変化します。読み出した時の値は保持されません。
- ポート出力データレジスタ(PODR)
出力で使う端子の出力データを格納するレジスタです。0または1の値をLOWレベルまたはHIGHレベルの信号に変換して端子から出力します。メモリと同じで書き換えるまでは値を保持しますので、端子からの出力電圧も書き換えるまで保持されます。
GPIO活用プログラムをGR-SAKURAで試そう!
今回は、「スイッチを押している間LEDが光る」というプログラムでGPIOの動きを習得しましょう。GR-SAKURA用のライブラリを利用してプログラミングします。(桜ライブラリ「デジタルI/O」)
桜ライブラリ「デジタルI/O」では、ボード上のI/O用ピンを入力として使うか、出力として使うかを最初にpinMode(ピン番号、モード)関数にて指定します。一度指定した後は、ピンの使い方を変更しない限りpinMode関数を実行する必要はありません。
入力ならば、digitalRead関数でピン番号を指定します。結果は、HIGHかLOWとして返されます。出力の場合は、digitalWrite関数を用いてピン番号と値を指定します。値は、やはりHIGHかLOWを使います。HIGHは1、LOWは0と同じです。0または1と記述しても構いません。
今回は、GR-SAKURAボード上のスイッチとLEDを使っています。これにつながれたピン番号やポート番号などが不明でも、スイッチならば「PIN_SW」、LEDならば「PIN_LED0」~「PIN_LED3」とプログラム中に書き込めば、桜ライブラリが処理してくれます。
電子工作ボード「GR-SAKURA」の構造はコチラからご確認下さい。
GPIOを使って、スイッチの値をLED点滅に反映するプログラム例を図3に示します。スイッチにつながれた端子が入力用であること、LEDにつながれた端子が出力用であることを最初にpinMode関数で指示しています(1)。最初に1回だけ定義すればよいので、setup関数の中で処理します。
次に、「スイッチが押されていたらLEDを点灯し、押されていなかったらLEDを消灯する」部分はloop関数の中で処理します。スイッチが押されたかどうかは、digitalRead(PIN_SW)が返す値で判断します。GR-SAKURAのスイッチは、何もしていない(放している)時はHIGH(プルアップ抵抗を介して、電源につながれる)となり、押されているとLOW(GNDにつながれる)になります。
digitalRead(PIN_SW)が返す値がLOWの場合=スイッチが押されていたら(2)、LEDを光らせましょう。D1のLEDはdigitalWrite(PIN_LED0, HIGH)とすれば光ります(3)。
押されていないと判断したら、digitalWrite(PIN_LED0, LOW)とすれば(4)、GPIOの出力はLOWになってLEDは消灯します。
GR-SAKURAのWebコンパイラを使って、図4に示したプログラムを実行してみて下さい。Webコンパイラの使い方は、組み込みシステム入門シリーズの「初めてのモノづくりに挑戦! 電子工作入門」の2回目と4回目を参考にして下さい。
/*GR-SAKURA Sketch Template Version: V1.08*/
#include <rxduino.h>
#define CHATTERING 50
void setup()
{
pinMode(PIN_SW,INPUT); ...........(1)
pinMode(PIN_LED0,OUTPUT);
}
void loop()
{
if(digitalRead( PIN_SW) == LOW) ...........(2)
{
digitalWrite(PIN_LED0, HIGH);...........(3)
delay(CHATTERING); ...........(5)
}else
{
digitalWrite(PIN_LED0, LOW); ...........(4)
}
}
プログラムのヒント「チャタリング」で誤作動を防止する
スイッチは、回路を導通したり(スイッチを「閉じる」、と表現することもあります)遮断したり(こちらは「開く」と表現することがあります)するものです。オンとオフですね。これをスイッチ等の装置が機械的に行う場合、どちらかの状態に一瞬にして動くわけではありません。装置が非常に速い振動を起こして、オンとオフを細かく繰り返しながら新しい状態に移ります。これを「チャタリング」と呼びます。チャタリングが分かりやすく体験できるプログラムを作成しました(図4)。試しに実行してみましょう。
/*GR-SAKURA Sketch Template Version: V1.08*/
#include <rxduino.h>
void setup( )
{
pinMode(PIN_SW, INPUT);
pinMode(PIN_LED0,OUTPUT);
}
void loop( )
{
if(digitalRead(PIN_SW) == LOW )
{
digitalWrite(PIN_LED0 , digitalRead(PIN_LED0) == 0 ? 1: 0);
while(digitalRead(PIN_SW) == 0);
}
}
期待する動作はスイッチを押さえる度にLEDが点く、消えるを繰り返す、ですがどうですか?そうなることもあればならないこともありませんか?この現象の原因がチャタリングで、もし、振動の途中の状態を、スイッチの信号として取り出してしまうと、正しい結果を得られない状況ということになります。そこで、チャタリング防止プログラムで対応します。
図3のプログラムでは、最初にスイッチが押されたことを検出してから50ミリ秒(0.05秒)停止してから処理をしています(図3の(5))。この処理を入れない場合、スイッチが押されたことを検出してLEDを点灯しても、次にスイッチの状態をチェックしたときに、チャタリングのせいで「スイッチを放している」ように見えて(入力がHIGHに一時的に戻っているため)LEDを消灯してしまうことがあります。スイッチが落ち着くまで、処理を止めることで対応しました。
本稿ではGPIOの構造と使い方を学習しました。プログラムのPIN_LED0の部分を他のLED番号(0~3までが有効)にすれば、点滅するLEDを変えられます。また、判断部分を書き換えれば、「2回押したらLEDが点灯、次に1回押したら消灯」などの複雑な処理もできます。今回はGR-SAKURA上にある入出力デバイスのみを使っていますが、デジタル出力を持つ外部のセンサをGR-SAKURAのI/O端子につないだり、LED以外のデバイス(例えば電子ブザー)をつないだりすることもできます。
次回は、時間に係わる処理を行う周辺機能「タイマ」を解説します。お楽しみに!
「周辺機能」を学ぼう
- GPIO
- タイマ
- シリアル通信
- 割り込み
- プログラミング(前編)
- プログラミング(後編)