街中で見かけて「グッときた人」の思い出

デバイスに電圧を印加するための電源の制御を、プログラミングを作成して行おうとしています。

PCと電源はパラレルポートでつながっています。
電源とデバイスはDサブコネクタでつながっています。
電源内でデバイスに印加する電圧を制御しています。

パラレルポートへのアクセスですが、PortTalkというドライバ
を使用すればいいということは分かっていますが具体的に
どう使用すればいいか教えてください。

また下記のソースが何言語で書かれているか、
これを理解するには何を(例:C言語、WINAPIなど)勉強すればいいかを教えてください。参考URLなどを教えていただければさらに助かります。

void outportb(unsigned int portid,unsigned char value){
_asm mov edx,portid
_asm mov al,value
_asm out dx,al

部分的にでもわかる方がいれば回答お願いします。

A 回答 (3件)

> なにが足りないのか原因を追求中ですが、未だ解決できていません。



main 関数の下に記述された関数(Voltage)が呼ばれてないようです。

ご提示なされているコードが全てであれば、仮りに関数(Voltage)が呼ばれて
いても直接 I/O にアクセスしたことによるエラーになると思われます。

> #include <stdio.h >
>
> int main()
> {
> int input,addr;
(省略)
> printf("input___%d\n",input);
> return 0;
> }
>
> int CurrentAddress;

giveio.sys を使う前提でのコード(mainとその上部分)を書いてみまたした、
上記の引用部分と置き換えてみてください。
giveio.sys については、ご存じかと思われますが、次のサイトなどをご参照下さい。

giveio.sys インストール手順
http://homepage1.nifty.com/jr4qpv/giveio.htm

# 古い scanf はお薦めできませんがあくまでデバッグ目的ということで
# 必要であればより安全な方法にしてください。

※ インデントはしてません。
----------------------------------------------------------
/* require header */
#include <stdio.h>
#include <conio.h>
#include <string.h>
#include <windows.h>

/* prototype */
void Voltage(int ,int);

/* global valiable */
int CurrentAddress;

int main()
{
int input, addr;
char buffer[32];
HANDLE hGiveIO = INVALID_HANDLE_VALUE;

printf("input___ ");
scanf("%d", &input);

printf("addr___ ");
scanf("%d", &addr);

/* confirmation */
printf("** confirmation **\n");
printf("address %d\ninput %d\n", addr, input);
printf("are you ready? (yes/no): ");
scanf("%d", &buffer);
if(!strncmp(buffer, "yes", 3))
{
printf("canceled!\n");
return 0;
}

/* open giveio */
hGiveIO = CreateFileA("\\\\.\\giveio", GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if(hGiveIO == INVALID_HANDLE_VALUE)
{
fprintf(stderr, "Can not open GiveIO!\n");
return -1;
}
/* close giveio */
CloseHandle(hGiveIO);

/* call Voltage */
Voltage(input, addr);
return 0;
}
// ここから下に D40DI のデータシートにあると思われる
// コードを記述してください。
----------------------------------------------------------

Visual C++ 2005 Express Edition と SDK があればコンパイルが通ると思います。

# あくまで参考としてコードを提示させて頂きますが、自己責任でお願い致します。
# 僭越ですが、以下のことに留意されたほうがよろしいかと思います。
# 以下は余計なことなのですが。
# この D40DI なのではないかと思われますが、そうでしょうか?
# http://www.agiloptics.com/documents/D40DI_DataSh …
# データシートを見ただけの印象でしかありませんが。
# ブロック図を見る限り、D/A変換にて電圧制御する仕組みのようですね?
# くれぐれもパラレルの出力がタイミング波形通りとなるかどうかご確認されてから
# 実機(D40DI)に接続されたほうがよろしいかと思います。
# 本来は専門家か製造元にお尋ねになるほうが安全かと思われます。
    • good
    • 0
この回答へのお礼

早速のご回答ありがとうございます。

ご指摘のURLのD40DIです。
動作はPCからのデジタル信号をパラレルポートを通して入力し
アンプで増幅してアナログ信号として出力しているはずです。

実機にはパラレルポートの出力が入力通りか確認してから
接続する予定です。

現段階でgiveioを導入することがうまくいってないので
そこから頑張ってみます。

お礼日時:2008/03/25 15:23

> 私はVixualC++2005 Express Editionを使用したのが


> エラーの原因となった可能性はあるのでしょうか?

どのような方法でビルトなされたかわからないので、細かいことは言えま
せんが、SDK は導入されてますでしょうか?

CreateFile は windows.h というヘッダを必要としますが VC++ 2005 の場合は
別途に SDK(Microsoft Windows Software Development Kit) が必要になります。

SDK と VC+2005 などで検索なされば出ると思いますが
http://okwave.jp/qa2352816.html

> void outportb(unsigned int portid,unsigned char value)

これは Windows の _outp と同様の動作をするもので

portid がポート番号(パラレルなどの)
value がポートへ書き込む値(0x00 から 0xff の 8 ビットのデータ)

のように思いますが?

# 他でご質問なされているように MS-DOS からなら、そのままポートが
# 叩けると思いますが、WindowsXP などのコマンドプロンプトからは
# おそらくなにかの手段(デバイスドライバ等での操作)をとらないと
# 不可能かと思われます。

> とりあえずはアセンブラ入門の勉強を始めようと思っています。

はい、がんばってください。
    • good
    • 0
この回答へのお礼

ご回答ありがとうございます。
また、お礼が遅くなり申し訳ありません。

いろいろ試してみたところ
他の関数と組み合わせることでプログラミング自体は動くようですが
実際にパラレルポートのピンの電圧をテスターではかってみると
制御できていないようです。
以下に作成したプログラムを載せています。

#include <stdio.h >

int main()
{
int input,addr;

printf("input___");
scanf("%d", &input);
printf("input___%d\n",input);

printf("addr___");
scanf("%d", &addr);
printf("addr___%d\n",addr);

printf("input___%d\n",input);
return 0;
}

int CurrentAddress;

/* To address any computer port*/
void outportb(unsigned int portid,unsigned char value){
_asm mov edx,portid
_asm mov al,value
_asm out dx,al
}

/* To address the control bits(C0-C4)*/

void Control(unsigned char value){outportb((unsigned int)0x037A,value);}


/* To address the parallel port data bits(D0-D7)*/

void Data(unsigned char value){outportb((unsigned int)0x378,value);}


/* To write out an address to the D40DI*/

void Address(unsigned char input){
Control(2); Data(input); Control(0);
CurrentAddress = input; //Save the current address as a global
}


/* To out a voltage to the D40DI*/

void Voltage(int input,int addr){
Address(0x80 | CurrentAddress); //Set the MSB on the addr as a clock
Control(1); Data(input); Control(0); //set the data buffer
Address(0x80 | addr); //Setup the address
Address(addr); //clock it in
}


以上です。
おそらく最後のVoltage関数のinputとaddr
(チャンネルを指定する)変数を
入力すれば指定電圧に制御できるプログラムだと思いますが、
inputの値を変えても前記したようにパラレルポートの電圧に
変化はありませんでした。

なにが足りないのか原因を追求中ですが、未だ解決できていません。
お力添えできれば宜しくお願致します。

お礼日時:2008/03/24 20:42

部分的にしかわからなくて申し訳ないのですが……


読ませて頂いた感じからすると Windows 端末から操作されると思すので
それを前提に記述させて頂きます。

> PortTalkというドライバ

これは直接 I/O ポートの操作を可能とするドライバのようですね?
直接ポートを叩きたいということであれば giveio でも可能だと思います。

> 具体的にどう使用すればいいか

PortTalk は使ったことはありませんが、giveio であれば、ドライバを
インストールして、WINAPI で CreateFile を呼んでから outp などで
ポートに制御コマンドを送れば良かったと思います。

giveio については以下の URL を見てください。

WindowsXP/2000/NTでパラレルポート制御
http://www1.bbiq.jp/kougaku/IO_parallel.html

> 下記のソースが何言語

C 言語とアセンブラ(インラインアセンブラ)ですね。

> これを理解するには何を(例:C言語、WINAPIなど)勉強すればいいか

C言語とアセンブリ言語の知識が必要かと思います。
それと制御端末の OS の知識、OS が Windows なら WINAPI だと思います。
アセンブリ言語の場合は CPU によって異なるので制御端末の CPU に
何が使われているかが判っている必要があります。

一般的な Windows 端末であれば 8086 系のアセンブリ言語かと思います。

アセンブラ入門
http://www5c.biglobe.ne.jp/~ecb/assembler/assemb …

アセンブリ入門
http://wisdom.sakura.ne.jp/programming/asm/index …

※ アセンブラとアセンブリは同じ意味です。

ちなみに制御コマンドの仕様がわかっているのであれば、貼り付けされた
ソースを読み解かなくても先に記述した giveio と outp や inp で制御
可能かと思います。

余計なことを申し上げてすみませんが、電圧を印加されるということ
なので実際の装置は接続せずに、デバックの段階で所望の制御コマンドが
出力されているかを何かでモニタしたほうがよろしいかと思います。
    • good
    • 0
この回答へのお礼

大変丁寧なご回答ありがとうございます。
また、お礼が遅くなったことお詫び申し上げます。

ご回答中にあったgiveioについては
以前から試してはいたのですが
下記に示すようなエラーが出ますので
PortTalkを使うことにしようとしました。

なおWindowsXP/2000/NTでパラレルポート制御のURLでは
VisualC++6.0を使用していましたが
私はVixualC++2005 Express Editionを使用したのが
エラーの原因となった可能性はあるのでしょうか?


1>------ ビルド開始: プロジェクト: 080311, 構成: Debug Win32 ------
1>コンパイルしています...
1>stdafx.cpp
1>コンパイルしています...
1>080311.cpp
1>.\080311.cpp(53) : fatal error C1010: プリコンパイル ヘッダーを検索中に不明な EOF が見つかりました。'#include "stdafx.h"' をソースに追加しましたか?
1>ビルドログは "file://c:\Documents and Settings\JEOL\My Documents\Visual Studio 2005\Projects\080311\080311\Debug\BuildLog.htm" に保存されました。
1>080311 - エラー 1、警告 0
========== ビルド: 0 正常終了、1 失敗、0 更新、0 スキップ ==========

とりあえずはアセンブラ入門の勉強を始めようと思っています。

お礼日時:2008/03/11 10:39

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!