|
このページは「24環境」の情報です 第7回 ハードウェア入門1.DIOの基礎の基礎 †海老原祐太郎
2002/9/1
最近ロボットコンテストが盛んですネ。 0と1をハードウェアで表す †タイトルの「DIOの基礎の基礎」のDIOとはデジタルI/Oの略です。 0V〜0.8Vを「L」、2V〜5Vを「H」を意味すると取り決めたものを「TTLレベル」と呼びます。 TTLレベル出力 †デジタル出力ポート(TTLレベル出力) 出力端子から電流が流れ出ます(吐き出し電流) 出力がLのときは0V(に近い)電圧が出ます。 出力端子に向かって電流が流れ込みます(吸い込み電流) 出力なのに「L出力の時は電流が入ってくる」、というのは今はピンと来ないと思いま すが、 じゃ、早速実験してみます。CAT68701にはTTLレベル出力ポートが13ビット分あります。 出力ポート0の電圧(上記緑印)をテスターで測ってみます。 「L」出力の電圧 0.1mv
「H」出力の電圧 5.11V
(電圧が5Vを超えてるのはそもそも電源が5.11V位なのだろう。汗)
TTLレベル入力 †デジタル入力ポート(TTLレベル入力) 入力端子に 2V〜5Vの電圧を入力すると「H」と認識されます。 入力端子に 0V〜0.8Vの電圧を入力すると「L」と認識されます。 IP-0に「L」レベルを入力する
入力ポート表示プログラム(後述)の出力 1111011111111110 ^ここが0になってる IP-0に「H」レベルを入力する
入力ポート表示プログラム(後述)の出力 1111011111111111 ^ここが1になってる ソフトウェアとハードウェアの連結 †ここでもう一度下の図を見てください。真ん中の 2列になっている端子の図は今までと同じです。 出力ポートは0xb4007400番地に割り当てられています。 *((unsigned volatile short *)0xb4007400L) = data;~ [#c749cc86] 入力ポートはアドレス 0xb4007000番地に割り当てられています。 data = *((unsigned volatile short *)0xb4007000L);~ 入出力デバイスドライバ †単に *((unsigned volatile short *)0xb4007400L) = data;~ [#u9844ee1] と書けば 0xb4007400番地にマッピングされている出力ポートにL/Hレベルを /* * CAT68701 internal pararel port driver "para.c" * for linux-2.4.x siries kernel * Copyright Feb/2000 Linux-koubou (si-linux.com) * written by Y.Ebihara */ #define MODULE #define __KERNEL__ #define DEFAULT_MAJOR_NUM 242 #define DEVNAME "para" #include "paradrv.h" #include <linux/module.h> #include <linux/fs.h> #include <asm/uaccess.h> static unsigned int para_major=DEFAULT_MAJOR_NUM; static unsigned short para_temp=0; /* -------------------------------------------------------- */ /* file operation */ /* -------------------------------------------------------- */ static int para_open(struct inode *inode, struct file *filp){ int minor=MINOR(inode->i_rdev); if(minor != 0){ printk("<1>para open() error"); return -1; } MOD_INC_USE_COUNT; return 0; } static int para_close(struct inode *inode, struct file *filp){ MOD_DEC_USE_COUNT; return 0; } static int para_read(struct file *filp, char *user_buf,size_t count,loff_t *ppos){ unsigned short data; data = *((unsigned volatile short *)0xb4007000L); // <−−ここでハードから入力している copy_to_user(user_buf,&data,2); /* 2byte */ filp->f_pos += 2; return 2; } static int para_write(struct file *filp, const char *user_buf,size_t count,loff_t *ppos){ unsigned short data; copy_from_user(&data,user_buf,2); *((unsigned volatile short *)0xb4007400L) = data; // <−−ここでハードへ出力している para_temp = data; /* save current output data */ filp->f_pos += 2; return 2; } static int para_ioctl(struct inode *inode, struct file *filp, unsigned int request, unsigned long arg){ int minor=MINOR(inode->i_rdev); if(minor != 0){ printk("ioctl error\n"); return -1; } switch(request){ case PARA_GETOUTPUTDATA: return para_temp; } return 0; } static struct file_operations para_fops = { open: para_open, /* open */ read: para_read, /* read */ write: para_write, /* write */ ioctl: para_ioctl, /* ioctl */ release: para_close /* close */ }; /* -------------------------------------------------------- */ /* driver module load / unload */ /* -------------------------------------------------------- */ static int init_module(void){ printk("<1>para hello\n"); if(register_chrdev(para_major,DEVNAME,& para_fops) != 0){ printk("<1>para register fail\n"); unregister_chrdev(para_major,DEVNAME); return -1; } return 0; } static void cleanup_module(void){ printk("<1>para goodby\n"); if(unregister_chrdev(para_major,DEVNAME) != 0){ printk("<1>para unregister fail\n"); } } コンパイル $ sh3-linux-gcc -I/カーネルソースを展開したディレクトリ/include -O2 -c paradrv.c 以下は CAT68701 で # insmod paradrv.o # cat /proc/devices Character devices: <略> 242 para キャラクタデバイス242番が確認できればOK # mknod /dev/cat68701-para c 242 0 ドライバを呼び出すユーザー空間プログラム †入力のサンプル (prog1a.c) #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){ unsigned short s; int i; read(fd,data,2); // ← デバイスドライバをコール(2バイト=16bit リード) s = (((unsigned short)data[1]<<8)&0xff00) + ((unsigned short)data[0] & 0xff); for(i=15; i>=0; i--) printf("%d",(s>>i)&1); printf("\n"); sleep(1); } close(fd); } 出力のサンプル (prog2.c) #include <stdio.h> #include <fcntl.h> #include "paradrv.h" int main(){ int fd,i; unsigned short data,old; fd=open("/dev/cat68701-para",O_RDWR); // ←デバイスドライバを開く if(fd<0){ perror(""); exit(); } while(1){ for(i=0; i<16; i++){ old=ioctl(fd,PARA_GETOUTPUTDATA,0); // ←ioctlで現在出力中の値をリード printf("olddata=%04x ",old); data = 1 << i; printf("newdata=%04x \n",data); write(fd,&data,2); // ← デバイスドライバをコール(2バイト=16bit ライト) sleep(3); } } close(fd); } prog1a.c や prog2.c は 普通に main() で始まるプログラムですからこれを改造して 今回のゴールは、ソフトウェアから出力ポートにH/Lレベルの電圧を出してみたり、 次回はもうちょびっとハード寄りの話をします。 |