このページは「24環境」の情報です

第8回 ハードウェア入門2.DIOの基礎

海老原祐太郎
2002/9/1

前回、デジタル出力ポートにHやLの電圧を出したり、デジタル入力ポートの
電圧をソフトウェアで0/1として取り込んだりが自由にできるようになりました。

しかしテスターで計って5Vが確認できただけでは面白くありません。
今回は実際にモノを動かしてみます。

基本はLED

いきなりメカを動かすのも大変なので、最初はLEDを制御してみます。

dio2_1.gif

LEDを点灯するには電圧(Vf)2.5Vをかけます。電流(Ic)で明るさが決まります。
電流を あまり流しすぎるとLEDの寿命を縮めてしまいます。
一般的に小型のLEDは5mA程度、大型のLEDでは15〜20mAくらい流すようにします。
前回の説明のとおり、デジタル出力ポートはHレベルにしたときに5Vに近い電圧がでます。
図の抵抗はLEDに流す電流を決める「電流制限抵抗」と呼ばれるものです。

出力ポートがHレベルで5Vだとすると、LEDに2.5Vをかけますので抵抗に
かかる電圧 Vr=5-2.5で 2.5Vになります。

電流を10mAとすると、オームの法則から R=E/I で 2.5/0.01= 250Ωとなります。
250Ωという抵抗は無いので、だいたい近い240Ωとか270Ωを使用します。

出力ポートをHレベル。つまりソフトウェアから1を書き込むとLEDが点灯し、
0を書き込むとLEDが消灯します。

と、ここまで説明しておいてアレですが、現実にはこの回路はあまり使いません。
10mAも電流を流すとデジタルICの出力が耐え切れず出力電圧が下がってしまう
ことがあるのです。
「だめです!電圧が低下しています!!」
といった事態が発生します。
従ってこの回路は小さいLEDで電流も小さくてよい時に使用します。

この回路形式を「Hレベルドライブ」といったり「ソースドライブ」、日本語では「正論理」
などと呼びます。

dio2_2.gif

今回の図は先ほどと少し違っています。抵抗値は同じく270Ωとしましょう。
出力ポートからLレベル出力。つまり0Vを出力したとします。
電流は、水と同じで電圧の高いほうから低いほうに流れますので、+電源Vccから 出力ポートに向かって電流が流れます。

出力ポートはLレベルを出力する時には電流を吸い込むほうに働きます。
これが前回説明した「吸い込み電流」のことです。

この回路の場合はLEDの電流は電源(Vcc)から直接供給されているので
「電圧が下がる」といった事態は発生しません。

もちろん出力ポートに大電流を流し込んだらICが壊れてしまいますが、
10mAくらいなら流し込んでもOKです。

出力ポートにLレベルを出力すること。すなわち、ソフトウェアから0を書き込むことで LEDが点灯します。1を書き込むと、出力ポートがHになり電源電圧5V近くに
なりますのでLEDは消灯します。

この回路形式を「Lレベルドライブ」といったり「シンクドライブ」、日本語では「負論理」
などと呼びます。

LED点灯実験

CAT68701にはボード上にLEDが1個乗ってますので実験にはハンダゴテもLEDも不要です。
ブロック回路図を広げてください。

dio2_3.gif

電流制限抵抗は図には省かれていますが実際には付いています。
LEDの方向を見て考えると判るのですが、「Hレベルドライブ」の回路になっています。
LEDが小さいのでHレベルドライブでも十分LEDを点灯させることができます。
Hレベルドライブですから出力ポートのビット15に1を書くと、LEDが点灯します。

では実際にコードを書いて見ます。
デバイスドライバは前回から引き続き組み込んであるとします。

#include <stdio.h>
#include <fcntl.h>
#include "paradrv.h"

int main(){
  int fd;
  unsigned short data,old; 

  fd=open("/dev/cat68701-para",O_RDWR);
  if(fd<0){
    perror("");
    exit();
  }
  while(1){
    printf("LED ON\n");
    old=ioctl(fd,PARA_GETOUTPUTDATA,0);
    data = old | 0x8000;  // <−−ビット15を1にする
    write(fd,&data,2);
    sleep(1);

    printf("LED OFF\n");
    old=ioctl(fd,PARA_GETOUTPUTDATA,0);
    data = old & ~0x8000; // <−−ビット15を0にする
    write(fd,&data,2);
    sleep(1);
  }
  close(fd);
}

出力画面

LED ON
LED OFF
LED ON
LED OFF
ledonoff.gif

見事にLEDが点滅していますね。

スイッチからの入力

今度は入力を考えて見ます。

dio2_4.gif

図のように入力ポートにスイッチと抵抗をつけます。
スイッチがONになると電源(Vcc)と入力ポートがつながり、入力ポートはHレベルになります。
これをソフトウェアから読むと「1」が読み出せます。
スイッチを離したとき、入力ポートの値が不定にならないように、グランド(0V)側に引っ張り下げる
抵抗をつけます。これを「プルダウン抵抗」と呼びます。
プルダウン抵抗は値は適当なのですが通常は4.7K〜100KΩの間で選択します。
10KΩをつけとけば妥当でしょう。

この回路はスイッチを押している間が「1」。スイッチを離している間が「0」になります。

dio2_5.gif

今度は逆にスイッチをグランド側につけてみます。
スイッチを押している間は入力ポートがグランドに接続され、「0」になります。
スイッチを離したとき、入力が不定にならないよう、電源側に引っ張り上げる抵抗
「プルアップ抵抗」が付いています。
これも10KΩくらいが妥当と思います。

この回路はスイッチを押している間が「0」、離している間が「1」になります。

実際の回路では後者の「スイッチをグランド側につける」回路が多用されます。
理由はいろいろあります。

  1. スイッチのところまで電源を引っ張らなくてよい。
  2. Hレベルは「2V〜5V」、それに対してLレベルは「0V〜0.8V」と範囲が狭いので、
    Lを意味のある信号(負論理)で統一したほうがノイズに対して強くなる

などが主な理由です。

スイッチ入力実験

CAT68701には入力スイッチも付いていますので、半田ごて使わずに入力の実験ができます。
またブロック回路図を開いてください。

dio2_7.gif

入力ポートのビット12〜15にスイッチがつながっています。
スイッチがONになるとグランドに接続され「0」が入力されます。
またスイッチがOFFの時は5Vにプルアップされて「1」が入力されます。

#include <stdio.h>
#include <fcntl.h>
#include "paradrv.h"
int main(){
  int fd;
  unsigned char data[2];
  fd=open("/dev/cat68701-para",O_RDWR);
  if(fd<0){
    perror("");
    exit();
  }
  while(1){
    read(fd,data,2);
    printf("%02x\n",(data[1]>>4) & 0xf);
    sleep(1);
  }
  close(fd);
}

DIPSWの1をONにしてある状態で(自動ブートに設定してあるから)でプログラムを実行すると
以下の出力が出ます。

0e
0e
0e

以上がデジタルIOの本当の基礎になります。
次回からは半田ごてを使ってセンサーなどを取り込んでみます。

Last-modified: 2006-01-19 (木) 16:38:07 (5399d)