計測制御技術ラウンジ >> GPIB技術ラウンジ 全部 1- 最新50

C言語での作成方法

1 名前: TERA 投稿日:2003/12/11(木) 17:00 ID:V3a0whpg
お世話になります。

TI社のNAT7210というデバイスを用いた計測基板を(他事業所で)作成しました。
CPUはALTERA社のデバイスで開発ツールはNIOSで測定部等は作成されています。
GPIB部を作成してくれと言われたのですが、GPIBに関してはまったくの初心者で
何をどうしたらよいか分かりません。
たとえば、測定データを接続されているPCに送信する場合など、どこのメモリ
のどのコマンドを使ってよいのか分かりません。
(もちろんライブラリはありません)
コマンドメッセージや、レジスタマップなどを見てもどのタイミングで、
どのように制御したら良いのか…。
アドレスレジスタが2個持っているといっても、メモリ上は同じ番地にあるような
感じがするし。。。
送受信プログラムはC言語で開発します。

初心者向けの書籍やサイトがあれば紹介願います。

2 名前: 匿名488 投稿日:2003/12/11(木) 19:37 ID:???
私は NAT9914 (NAT7210 の 9914 ピン互換版)しか
知りませんが、おそらく基本動作は

1)割り込み発生で NAT9914 の状態変化を知る
2)割り込み要因解析(リスナ?トーカ?シリアルポール等)
3)2)に応じて状態遷移、もしくはバイトリード、バイト書き込み

のようになると思います。
コントローラになることがなければ、すべてのアクションは
(SRQ を除いて)コントローラである PC から起こります。
これはデータの送受の方向にかかわらず、です。

端末側ではひたすら NAT9914 の状態変化を関知して、
それへの対応をする、という形になると思います。

NEC uPD7210/TMS9914 の資料やソースコードがあれば参考に
なるのではないかと思います。

どちらのマニュアルも日本語版があったと思いますが、
石自体がディスコンですので、メーカからの入手は困難
かもしれません。

NAT9914/7210 のマニュアルは英語ですが、処理の流れの
チャートがたしか付録?に載っていたと思います。

GPIB についてまったく初めてであれば、
トランジスタ技術のバックナンバーの GPIB 関連記事や、
このページの Amazon の広告にある岡村さんの本
を図書館などで探されるとよいかも。

3 名前: TERA 投稿日:2003/12/15(月) 14:08 ID:m8gydATg
匿名488さんレス有難うございました。
資料を探し回った結果、サンプルフローが見つかりました。
それと、図書館に『PC9801GP-IB 活用法』という本が
有りましたので、勉強中です。(サンプルBASICプログラムがある)
ひとつ分からないのですが、本デバイスにはライトレジスタとリードレジスタの
2つ内蔵されているらしいのですが、BASICではOUTステートメントや
INステートメントでアクセスできるそうなのですが、Cでは例えば
下記のように記述すればアクセスできるのでしょうか?
要するにリードレジスタとライトレジスタはアドレスが同じなので
どのように制御したらよいか分かりません。
分かる方居ましたらご教授願います。

#define  my_gpib ((t_gpib*)0x2000)) // GPIB_Memory
typedef struct
{
int ival1; //2000H〜2003H
int ival2; //2004H〜2007H
}t_gpib;

my_gpib sendreg,recvreg ;

void main()
{
int rval;
"リードレジスタ1Rの読み込み"
rval = sendreg->ival1 ;
rval >>=8;
"ライトレジスタ1Wの書き込み"
recvreg->ival1 = 0x01;
}

4 名前: TERA 投稿日:2003/12/15(月) 14:59 ID:mfgRR25k
追記です。
C言語にinp関数とoutp関数があります。
これがBASICのINP、OUTに対応するような気がします。
この関数でコード書かれた方いませんでしょうか?

5 名前: 匿名488 投稿日:2003/12/15(月) 16:14 ID:???
>要するにリードレジスタとライトレジスタはアドレスが同じ

 これは、「レジスタ」という名称から、メモリを想像
 されているのだと思います。
 たしかに「レジスタ」そのものはメモリ相当だとは思いますが、リードアクセス時と
 ライトアクセス時で別の領域が割り当てられるので、
 (わかりにくいですが)同じアドレスで大丈夫です。

 ただし、いくつかの拡張レジスタの中には、
 あらかじめアドレスを特定のレジスタに書き込むことで
 複数の拡張レジスタを使い分けている物があります。

 そのようなレジスタに書き込みする際には、

 out レジスタ選択レジスタ?,レジスタ番号指示データ
 out 共有レジスタアドレス,データ

 のように、
 読み出しの際にも

 out レジスタ選択レジスタ?,レジスタ番号指示データ
 in  R0,共有レジスタアドレス

 のようにしなければいけないとおもいます。

 なお、この2つの命令の間で他のタスクに制御が
 うつるとレジスタ指定が壊れますので
 (2つのシーケンスは不可分)
 そのあたりに配慮する必要があります。

 うっかり忘れると、原因不明のバグに悩まされることに
 なります。

6 名前: 匿名488 投稿日:2003/12/15(月) 16:33 ID:???
該当する CPU/開発環境 について詳しくないのですが
inp/outp 命令があるなら、それが該当する可能性が高いです。

一般的には、I/O アドレッシングであれば専用命令で、
メモリマップド I/O であれば、メモリアクセス命令で
アクセスできます(ポインタにアドレスを直接代入するか
定数ポインタをキャスト。コンパイラの最適化による
省略等をふせぐため、volatile 修飾子をつけること)。
どちらになるのかは NAT がどのようにバスに接続されているか、
その形態によります。

該当メモリ空間へのウェイトの挿入を適切におこなってください。
最近の高速なバスにノーウェイトですると問題があるかもしれません。

これはハード設計時の注意なので、もし逆になっていたらもう遅いかもなのですが、
過去ログにもありますように、たしかこの石は
データバスの LSB-MSB のナンバリングが逆になっています。

バス幅が 16/32 bit の場合、アドレスバスのどこに接続しているか、
BigEndian か LittleEndian か、CPU バスがバイトアクセスをどのように
取り扱うか、などでアクセスすべきアドレスが変わります。
そのあたりも注意してください。

以上、一般論ですが、ご参考まで。

7 名前: 匿名488 投稿日:2003/12/15(月) 16:35 ID:???
>これはハード設計時の注意なので、もし逆になっていたらもう遅いかもなのですが、
>過去ログにもありますように、たしかこの石は
>データバスの LSB-MSB のナンバリングが逆になっています。

NAT9914 だけかもしれません。
ちゃんとしらべていませんので、マニュアルをご参照ください。

8 名前: 匿名488 投稿日:2003/12/15(月) 17:14 ID:???
>>7
どうやら NAT7210 はマトモですね。

#NAT9914 は、元になった TMS9914 が逆になってるんでしょう(おそらく)。
#お騒がせしました。

9 名前: TERA 投稿日:2003/12/16(火) 10:01 ID:mfgRR25k
お世話になります。皆さん詳しい説明有難うございます。
どうも私は『レジスタ』というものの解釈を勘違いしているような気がします。
もうすこし学習してみます。

さて、レス6に回答下さった内容ですが↓↓↓
>一般的には、I/O アドレッシングであれば専用命令で、
>メモリマップド I/O であれば、メモリアクセス命令で
>アクセスできます(ポインタにアドレスを直接代入するか
>定数ポインタをキャスト。コンパイラの最適化による
>省略等をふせぐため、volatile 修飾子をつけること)。
>一般的には、I/O アドレッシングであれば専用命令で、
"I/O アドレッシング"と"メモリマップド I/O"の区別が
分かりません。
ハード設計者に聞くとおそらく後者だと思うので、メモリアクセスで、
コードを書いていこうと思います。
既存のADコンバータ部のコードを見るとどうもメモリアクセス命令(?)
で書かれているようなので、真似てやってみます。

参考までにその既存のADコンバータコントローラ部の記述を
書いておきます。
勘違いがあればご指摘願います。


*** ADCコントロール部レジスタマップは下記となっている ***
アドレス レジスタ名
1100h  ADコントロール
1120h  ディレイ1
1124h  ディレイ2
1128h  ディレイ3
112Ch  ディレイ4
1130h  ディレイ5
1134h  ディレイ6
1180h  ADデータ1
1184h  ADデータ2
1188h  ADデータ3
118Ch  ADデータ4
1190h  ADデータ5
1194h  ADデータ6

============ 既存コード ============

#define na_wml_if ((void *)0x00001000) // altera_avalon_user_defined_interface
#define na_adc ((np_adc *)(na_wml_if+0x0100))  // ADC Controller
typedef volatile struct
{
unsigned ctl;
unsigned chena;
unsigned hole_a[6];
unsigned dly[6];
unsigned hole_b[18];
int data[6];
} np_adc;

===========================
上記はヘッダファイルに定義されています。
各関数で、
np_adc *p = na_adc;
p->ctl = 1;
として、メモリを書き換えているようです。

10 名前: 匿名488 投稿日:2003/12/16(火) 18:19 ID:dRe0aymM
このコードから推察すると
おっしゃる通りメモリマップド I/O と思われます。

レジスタへのアクセスは、
ADC アクセスに倣って記述すればよいと思います。
構造体の展開(内部オフセット)に注意して記述すれば
大丈夫でしょう。

#もしあやしいようなら、アセンブルリストやデバッガの逆アセンブルソース等を
#みてコンパイラが正しいオフセットアドレスを吐いているか
#どうか確認してみてください。

11 名前: TERA 投稿日:2003/12/17(水) 11:13 ID:XI9LVRlU
お世話になります。
色々と回答有難うございました。
これから、メモリマップを見ながら、GPIBの手順に従って
送受信プログラムをコーディングしていこうと思います。
また何か不明点がありましたらよろしくお願いします。

12 名前: にしやま 投稿日:2003/12/17(水) 18:40 ID:FO4I9UIg
該当の環境での開発の結果のフィードバックを下さると、
同様に NAT を使用して開発される方の助けになると思います。

うまくいった点、きをつけなければいけなかった点など、
レポートをお待ちしています。

13 名前: TERA 投稿日:2003/12/24(水) 17:57 ID:9auS/EOs
お世話になります。
またまた質問ですが、分かる方いらっしゃいましたら
アドバイスよろしくお願いします。

NO.2の書き込みで、
>コントローラになることがなければ、すべてのアクションは
>(SRQ を除いて)コントローラである PC から起こります。
>これはデータの送受の方向にかかわらず、です。
>端末側ではひたすら NAT9914 の状態変化を関知して、
>それへの対応をする、という形になると思います。

の回答を頂きました。

今の構成は、コントローラはPCで、Interface社のPCI-4301ボードを
使用しています。
私の今作成している端末はコントローラになることはないので、
デバイスの状態変化を検知して送受信プログラムを書いています。
ここで、デバイスの状態変化というのは、NAT7210の割り込みステータス
レジスタ[1R]のDIビットとDOビットの状態を一定周期で見ています。
DI:データレジスタ[0R]の読込み要求
DO:ライトレジスタ[1W]への出力要求
この2ビットだけで、状態監視は可能なのでしょうか?

PCのPCI-4301ボードのコマンドには、"GpibReceive()"という
受信コマンドが用意されています。
PC側でこのコマンドを発行すれば、ここでいうDOビットが
立つという解釈でよろしいのでしょうか?
同じく"GpibSend()"という送信コマンドが用意されています。
PC側でこのコマンドを発行すれば、ここでいうDIビットが
立つという解釈なのでしょうか?

分かる方いらっしゃいましたらご教授願います。

14 名前: 匿名488 投稿日:2003/12/24(水) 19:54 ID:???
おそらくそれでいいと思いますが、
通常は自分自身がデータ送信側にあるのか(MTA)
データ受信側にあるのか(MLA)、現状でハンドシェイク
には関わらない状態なのか(OTA) も把握しておきます。

これはデータシーケンスの途中でバスが初期化されたり、
中断されたりした場合の例外処理をするためです。

バイトごとのデータ送出に際しては、最終データ送出前に
次バイトで EOI メッセージを出すためのコマンドを出したり、
受信時にバイトごとにハンドシェイクを止める設定の場合には
それを解除するコマンドが必要になったりします。

他にも GPIB バス上のメッセージに対するハンドラ
(IFC など)や、シリアルポールを使う場合には
それに対するハンドラ(もしくは送出ステータスの
レジスタへの設定)が必要になります。

15 名前: TERA 投稿日:2004/01/14(水) 15:37 ID:5/Essswo
お世話になります。
トランジスタ技術の1995年の10月から12月号の巻で、デバイスを
利用したGPIBの特集が有りました。特に10月号は送受信のプログラムまで
記述されていましたので、大変参考になり、ソースコードを解析しています。
今私が作成しているプログラムは、コントローラになることがないので、
送受信の部分だけを参考に作成すれば実現できそうに思えます。
今からプログラム組んで、基板にインストールして来週中には結果報告できると
思います。
また、何か不明点ありましたらよろしくお願いします。

新着レスの表示

名前 : E-mail(省略可) :

文責:計測制御技術ラウンジ, Powered by ©タカヒロ@みちのく掲示板 [12ch BBS 2.03]