C言語

IOポートの設定

今回使用する「基板付きキット 絵解き マイコンCプログラミング教科書」のマイコン基板のIOポート設定を実際に行います。
統合開発環境はCS+ですが、コーディングは、使い慣れたテキストエディタでも問題ありません。

IOポート設定のファイル名

IOポートの設定以外にもマイコン設定はいろいろあるため、マイコン全体の初期化処理用として、1ファイル作成することにします。
このため、RL78G14マイコンのマイコン設定のファイルとして「RL78G14_init.c」Cファイルを作成します。

IOポート設定の関数

「RL78G14_init.c」 ファイルに、IOポート初期化処理の関数を用意します。関数名は、戻り値も引数もない「 void RL78G14_init_IO_Port( void )」とします。
ポート機能で使用するレジスタの説明」で解説したIOポートのレジスタを設定します。

Cファイルを次のように作成します。

#include "iodefine.h"

/* ポート・レジスタ初期値 */
#define RL78G14_INIT_P0    (0x02U)
#define RL78G14_INIT_P1    (0x80U)
#define RL78G14_INIT_P2    (0x00U)
#define RL78G14_INIT_P3    (0x00U)
#define RL78G14_INIT_P4    (0x00U)
#define RL78G14_INIT_P5    (0x20U)
#define RL78G14_INIT_P6    (0x00U)
#define RL78G14_INIT_P7    (0x00U)
#define RL78G14_INIT_P12   (0x00U)
#define RL78G14_INIT_P13   (0x00U)
#define RL78G14_INIT_P14   (0x00U)
/* プルアップ抵抗オプション・レジスタ初期値 */
#define RL78G14_INIT_PU0   (0x00U)
#define RL78G14_INIT_PU1   (0x00U)
#define RL78G14_INIT_PU3   (0x00U)
#define RL78G14_INIT_PU4   (0x01U)  /* P40:内蔵プルアップ抵抗接続 */
#define RL78G14_INIT_PU5   (0x00U)
#define RL78G14_INIT_PU7   (0x28U)  /* P73、P75:内蔵プルアップ抵抗接続 */
#define RL78G14_INIT_PU12  (0x00U)
#define RL78G14_INIT_PU14  (0x00U)
/* ポート入力モード・レジスタ初期値 */
#define RL78G14_INIT_PIM0  (0x00U)
#define RL78G14_INIT_PIM1  (0x00U)
#define RL78G14_INIT_PIM3  (0x00U)
#define RL78G14_INIT_PIM5  (0x00U)
/* ポート出力モード・レジスタ初期値 */
#define RL78G14_INIT_POM0  (0x00U)
#define RL78G14_INIT_POM1  (0x00U)
#define RL78G14_INIT_POM3  (0x00U)
#define RL78G14_INIT_POM5  (0x00U)
#define RL78G14_INIT_POM7  (0x00U)
/* ポート・モード・レジスタ初期値 */
#define RL78G14_INIT_PM0   (0x80U)  /* P00~P06:出力モード */
#define RL78G14_INIT_PM1   (0x00U)  /* P10~P17:出力モード */
#define RL78G14_INIT_PM2   (0x7FU)  /* P27:出力モード、P20~P26:入力モード */
#define RL78G14_INIT_PM3   (0xFCU)  /* P30、P31:出力モード */
#define RL78G14_INIT_PM4   (0xF1U)  /* P41~P43:出力モード、P40:入力モード */
#define RL78G14_INIT_PM5   (0xC0U)  /* P50~P55:出力モード */
#define RL78G14_INIT_PM6   (0xF3U)  /* P62、P63:出力モード、P60、P61:入力モード */
#define RL78G14_INIT_PM7   (0x28U)  /* P70~P72、P74、P76、P77:出力モード、P73、P75:入力モード */
#define RL78G14_INIT_PM12  (0xFFU)  /* P120~P124:入力モード */
#define RL78G14_INIT_PM14  (0x3CU)  /* P140、P141、P146、P147:出力モード */

void RL78G14_init_IO_Port( void )
{
    /* ポート・レジスタ初期化 */
    P0 = RL78G14_INIT_P0;
    P1 = RL78G14_INIT_P1;
    P2 = RL78G14_INIT_P2;
    P3 = RL78G14_INIT_P3;
    P4 = RL78G14_INIT_P4;
    P5 = RL78G14_INIT_P5;
    P6 = RL78G14_INIT_P6;
    P7 = RL78G14_INIT_P7;
    P12 = RL78G14_INIT_P12;
    P13 = RL78G14_INIT_P13;
    P14 = RL78G14_INIT_P14;

    /* プルアップ抵抗オプション・レジスタ初期化 */
    PU0 = RL78G14_INIT_PU0;
    PU1 = RL78G14_INIT_PU1;
    PU3 = RL78G14_INIT_PU3;
    PU4 = RL78G14_INIT_PU4;
    PU5 = RL78G14_INIT_PU5;
    PU7 = RL78G14_INIT_PU7;
    PU12 = RL78G14_INIT_PU12;
    PU14 = RL78G14_INIT_PU14;

    /* ポート入力モード・レジスタ初期化 */
    PIM0 = RL78G14_INIT_PIM0;
    PIM1 = RL78G14_INIT_PIM1;
    PIM3 = RL78G14_INIT_PIM3;
    PIM5 = RL78G14_INIT_PIM5;

    /* ポート出力モード・レジスタ初期化 */
    POM0 = RL78G14_INIT_POM0;
    POM1 = RL78G14_INIT_POM1;
    POM3 = RL78G14_INIT_POM3;
    POM5 = RL78G14_INIT_POM5;
    POM7 = RL78G14_INIT_POM7;

    /* ポート・モード・レジスタ初期化 */
    PM0 = RL78G14_INIT_PM0;
    PM1 = RL78G14_INIT_PM1;
    PM2 = RL78G14_INIT_PM2;
    PM3 = RL78G14_INIT_PM3;
    PM4 = RL78G14_INIT_PM4;
    PM5 = RL78G14_INIT_PM5;
    PM6 = RL78G14_INIT_PM6;
    PM7 = RL78G14_INIT_PM7;
    PM12 = RL78G14_INIT_PM12;
    PM14 = RL78G14_INIT_PM14;
}

IOポート設定の関数の説明

最初に、iodefine.hをインクルードしています。
iodefine.hには、P0や、PU0などの制御レジスタが定義されています。
これらの 制御レジスタは、特殊機能レジスタと拡張特殊機能レジスタとよばれ、特殊機能レジスタは、FFF00H~FFFFFHに、拡張特殊機能レジスタは、F0000H~F07FFHのアドレスに割り当てられています。
例えば、P0は、FFF00Hに割り当てられています。PU0は、F0030Hに割り当てられています。
直接アドレスに対して値を参照したり、代入したりできるのですが、このアドレスに対して、defineにて定数名を付けたのが、iodefine.hです。
このため、このヘッダファイルをインクルードすることにより、レジスタのP0や、PM0などの名称が利用できるようになります。

iodefine.hで、P0などの定数名のアドレスが0xFFF00ではなくて0xFF00になっていますが、これは、nearという領域に対してのアドレスのためです。
near領域は、0xF0000~0xFFFFFのアドレス範囲になっているため、0xF0000のFが省略可能だからです。

次に各ポート関連のレジスタの設定ですが、基本的にマイコンがリセットしたときの初期値は決められているため、リセット値から変更が必要なレジスタに対して設定を行えば問題ありません。
ただし、今回は、リセット値のままでもあえて設定することにしています。
理由は、リセット値のままとしているのか、設定し忘れているのかが判断しにくいことと、設定内容をコメントにして記述しておけば、リセット値を意識しないのでわかりやすいという理由です。
実務では、すべてではありませんが、すべて設定を行うというルールとしている場合もありますので、今回は、学習も兼ねてすべて記述しています。

次にレジスタの設定の順番です。
基本的には、信号の伝わる順番に設定していきます。ただし、これも明確にこうするという決まりはないと思っています。
ただし、一番最初に行わなければならないのは、周辺I/Oリダイレクション・レジスタ(PIORx)の設定です。これについては、レジスタの設定の中で一番最初に行いますので、このIOポート設定の関数より前に行うことを想定していますので、IOポート設定の関数では行いませんでした。
このポート設定で最初に行ったのは、ポート・レジスタの設定です。
これは、入力モードか出力モードを選択するポート・モード・レジスタ(PMxx)の初期値が 1 の入力モードのため、モードを出力に切り替える前にポート・レジスタの値を 0 で初期化しておくために最初に設定しました。
次に入力の内蔵プルアップ抵抗の接続有無を選択するプルアップ抵抗オプション・レジスタ(PUxx)の設定を行います。
これは、今回のマイコン基板はSWが付いているのですが、回路にプルアップ抵抗がないため、優先的に設定しました。
プルアップ抵抗オプション・レジスタ(PUxx) の次は、入力タイプを選択するポート入力モード・レジスタ(PIMxx)です。これは、すべて初期値のままなので、このタイミングでなくてもよかったのですが、今後変更が入る場合は、ポート・モード・レジスタの初期値が入力モードのため、入力に関するレジスタということでこのタイミングで設定しました。
ポート入力モード・レジスタ(PIMxx) の次は、ポート出力タイプを選択するポート出力モード・レジスタ(POMxx)です。これは、ポート・モード・レジスタ(PMxx)のあとでもよかったのですが、ポート入力モード・レジスタ(PIMxx)の後がわかりやすいと思いこのタイミングで設定しました。
そして次は、入力・出力のモードを選択するポート・モード・レジスタ(PMxx)です。結局最後になりますが、モードを選択して、IOポートの設定は完了です。

ここで、 周辺I/Oリダイレクション・レジスタ(PIORx) 以外にも、アナログ入力とデジタル入出力を選択するポート・モード・コントロール・レジスタ(PMCxx)や、A/Dポート・コンフィギュレーション・レジスタ(ADPC)がありましたが、こちらについては、アナログの設定であるA/Dコンバータ関連のレジスタの設定のところで行ったほうがわかりやすいと考えて、IOポート設定の関数では行いませんでした。

各設定値をdefineを使って定数名にしていますが、直接、値を代入しても問題ありません。
実務では、処理の中で値をそのまま記述することはしないところが多いというのがあります。ここで定数名にするメリットはありませんが、設定値がまとまっているというくらいでしょうか。

ポート・レジスタ(Pxx)の設定値の説明

初期値は、すべて 0 を出力します。
今回は、P01、P17、P55以外は、特に 1 を出力することはないため、設定は不要ですが、ポートのモードが入力モードになっているため、念のため、すべて 0 で再設定します。
P01、P17、P55については、LED0~LED2に該当するポートですが、LEDを消灯で初期化するため、1 を設定します。
マイコン基板の回路図では、LEDが5Vと繋がっているため、1を設定することでマイコンから5Vが出力される結果、LEDの両端が5Vとなり、電流が流れないため、点灯しなくなります。
設定は、8ビット毎で設定していますが、1ビット毎に設定することも可能です。この場合は、P00なら、そのまま P00 = 1U; などとして設定します。

プルアップ抵抗オプション・レジスタ(PUxx)の設定値の説明

初期値は、0(内蔵プルアップ抵抗を接続しない)になっていますが、一部、PU4のみ0x01(PU40)が1(内蔵プルアップ抵抗を接続する)になります。
今回は、SWが割り付けているP73(26ピン)とP75(24ピン)が内蔵プルアップ抵抗を接続させますので、そのポートに該当する。PU7を0x28に設定します。
それ以外は、初期値と同じ値としています。
設定は、8ビット毎で設定していますが、1ビット毎に設定することも可能です。この場合は、P73なら、そのまま PU73 = 1U; などとして設定します。

ポート入力モード・レジスタ(PIMxx)の設定値の説明

初期値は、すべて 0(通常入力バッファ)になっています。
今回は、特に 1(TTL入力バッファ)にする必要はないため、すべて初期値を設定します。

ポート出力モード・レジスタ(POMxx)の設定値の説明

初期値は、すべて 0(通常出力モード)になっています。
今回は、特に1(N-chオープン・ドレイン出力モード)にする必要はないため、すべて初期値を設定します。

ポート・モード・レジスタ(PMxx)の設定値の説明

初期値は、すべて 1(入力モード)になっています。
今回は、未使用・未接続のポートはすべて出力モード(入力専用ポートは除く)とするため、次のポートを出力モードに設定して、その他は初期値のままの設定とします。

出力モードにするポート:P00~P06、P10~P17、P27、P30、P31、P41~P43、P50~P55、P62、P63、P70~P72、P74、P76、P77、P140、P141、P146,P147

次のポートは、出力ポート以外で使用するため、初期値のままの設定とします。
入力モードにするポート:P73、P75
入力専用ポート:P121~P124、P137
アナログ入力にするポート:P20~P26、P120
TOOLで使用するポート:P40
I2Cで使用するポート:P60、P61

P130、P137のポート・モード・レジスタの設定がありませんが、P130は、出力専用ポート、P137は、入力専用ポートとなっているため、PM13というレジスタありません。

以上が、IOポート設定の関数についてでした。
IOポートレジスタの説明を学んでいない方は、「ポート機能で使用するレジスタの説明」を参照していただければと思います。また、ポート割り付けについても説明していますので、参照していただければと思います。



-C言語