Author: Somebody
Last saved by: bako
Company: BME-MMT

IEC busz alapú laboratóriumi mérőrendszer vizsgálata

1. IEC busz áttekintés

A PC vezérelt, IEC busz alapú SIEMENS mérőrendszer esetünkben a következő műszerekből áll: tápegység, függvénygenerátor, multiméter. Ezek az IEC buszon beszélő vagy hallgató funkciót látnak el, a PC betölti a rendszervezérlő szerepet is. 
A rendszervezérlő a busz parancs módjában jelöli  ki a következő adatátviteleket vezérlő beszélőt, valamint az adatokat fogadó hallgató(ka)t. A szerepek kiosztása után a vezérlő a buszt adat módba váltja. Ekkor a kijelölt beszélő küldi az adatokat a kijelölt hallgató(k) számára. Az utolsó adat átvitele után a vezérlő ismét parancsmódba kapcsolja a buszt.
A soronkívüli kiszolgálást igénylő egységek megszakítást kérhetnek, melyet a vezérlő fogad és szolgál ki. A vezérlő a megszakításkérőt a berendezések állapotbájtjának/bitjének soros vagy a párhuzamos lekérdezésével azonosítja. 

Az IEC busz 16 jele a következő:

DIO 1..8	data I/O:	parancs, adat, cím, állapot átvitel 

ATN	attention:	busz parancs/adat mód
EOI	end or identify:	utolsó adat, ill. busz parancs/adat mód 

DAV 	data valid:	adat érvényes, busz hand-shake /hs/
NRFD	not ready for data:	nem kész adat fogadásra, busz hs
NDAC	no data accepted:	nem kész az adat fogadással, busz hs

REN	remote enable:	távvezérlés engedélyezés
IFC	interface clear:	IEC interfészek törlése
SRQ	service request:	megszakítás kérés

GND	ground:	digitális föld

Minden jel TTL szintű, negatív logikában értelmezett. A buszon az adatok 7 bitesek, a 8. bit a paritás. A SRQ, NRFD, NDAC vonalakat, valamint párhuzamos lekérdezés alkalmazása esetén a DIO 1..8 vonalakat huzalozott VAGY kapcsolat kialakítására alkalmas eszközzel kell meghajtani. Minden készülék csatlakozásnál a busz vonalai a +5V-hoz 3K-val, a GND-hez 6k2-vel le vannak zárva. A megengedhető kábelhossz 2m készülékenként, ill. max. 20m. Ekkor az adatátviteli sebesség max. 250 Kbyte/s a buszon lévő készülékek sebességétől függően. A készülékek max. száma 15.

ATN 	EOI	A buszon lévő adat értelmezése:
 0	0	közönséges adat
 0	1	utolsó adat
 1	0	parancs
 1	1	párhuzamos lekérdezésre adott állapot bitek

Ha ATN=1, EOI=0, akkor a buszon lévő adat parancs ill. cím, a következõ tábla szerint.

Spec. hallgató cím a korábbi kijelölések törlésére: 01 11111 = UNL, unlisten, lecímzés. 
Beszélő címzés törlése: 00 11111 = UNT.

DIO	7  6  5  4...1	command		   parancs
	0  0  0  ut.kód	addressed: 		minden címzett hallgatónak
	0  0  1  ut.kód	universal: 		minden készüléknek
	0  1  .   cím	listener address:	hallgató kijelölés
	1  0  .   cím	talker address: 	beszélő kijelölés
	1  1  . cím/kód	secondary: 		szekunder cím/utasítás

Egy tipikus adatátviteli folyamat:

A vezérlő adatátvitelt kezdeményez, ATN=1, EOI=0:

ATN	Mnemonik	Jelentés
 1	UNL		unlisten:		lecímzés 
 1	LAD1		listener address1:	hallgató címzés
 1	.... 		....
 1	LADn		listener addressn:	hallgató címzés
 1	TAD		talker address:		beszélő címzés
 0	DAB1		data byte1:		adatbájt, a beszélő küldi
 .	...		...
 0	DABn		data byten:		utolsó adatbájt, EOI=1
 1	UNL		unlisten:  		következő ciklus kezdete 

Minden berendezés az SRQ vonalon kér(het) megszakítást. A vezérlő azonosíthatja a megszakítást kérőt a berendezések állapotbájtjainak soros lekérdezésével.

Soros lekérdezés: /serial polling, SP/. ATN=1, EOI=0.

ATN	Mnemonik	Jelentés
 1	UNL		unlisten:		lecímzés 
 1	SPE		serial poll enable:	soros lekérdezés mód
 1	TAD		talker address:		következő beszélő
 0	data	 	status byte:		állapot bájt
vissza a beszélő kijelölésre, amíg van hátra berendezés
 1	SPD		serial poll disable:	soros lekérdezés tiltás

A megszakítást kérő azonosítása párhuzamos lekérdezéssel /paralell polling, PP/:
ATN=1, EOI=1, adat: egy berendezés egy adatvonalat hajt meg.

A vezérlő felprogramoz egy berendezést PP-re: 

ATN	Mnemonik	Jelentés
 1	LAD		listener address:	hallgató címzés
 1	PPC		PP configure: 		párh. lek. konfig. következik
 1	PPE		PP enable: 		párh. lek. konfigurálás
					 	vonal és aktív szint kijelölés
 1	PPD		PP disable: 		párh. lek. konf. vége
 1	UNL		unlisten:		lecímzés

2. IEC berendezések működtetése a BEDSIE program segítségével
Az IEC buszt a PC IEC illesztő kártyája segítségével vezérelhetjük. A kártyát egy rezidens drájver működteti. A BEDSIE.EXE program egy egyszerű interaktív kezelői felület, mely segítségével a rendelkezésre álló funkciókat kipróbálhatjuk. A BEDSIE-vel kipróbált funkcióknak megfelelő függvények egy C könyvtárban rendelkezésre állnak az IEC busz programozott kezeléséhez.
DEVICE=C: \ BEDSIE\SIEC.SYS a CONFIG.SYS-ben: IEC drájver indítás.
C:\BEDSIE\BEDSIE program indítás. Nyilak: függvény választás, Enter: indítás.

BEDSIE függvények és használatuk:
i_init, boardnumber=0	IEC kártya inícializálás
i_assign_auto	IEC berendezések jegyzékbe vétele
i_send 2 -1  VOLTAGE 1,5  0 A tápegység 1. csatorna beállítása 5 V-ra. Készülék parancs szöveg küldése csak a 2 című hallgatónak. -1 a hallgatói címlista vége jel. Az utolsó 0 az adatátviteli mód /nem IT-s/.
i_send 2 -1  STANDBY 1,OFF  0 A csatorna bekapcsolása.
i_send 2 -1  VOLTAGE? 0 A beállított kimeneti feszültségek lekérdezése. A válasz a következő függvénnyel kapható:
i_receive 2 100  0  Adat kiolvasás a 2 című egységből. Max. 100 bájt, 0 adatátviteli módban.
Innentől csak a készülék parancsokat leírva:
CLIMIT 1, 0.2 Áram-határ beállítása az 1. csatornán 0.2 A-ra.
CURRENT 1, 0.1 Névleges áram beállítása az 1. csatornán 0.1 A-ra.
*SRE 2 A tápegység állapotregiszter 2. bitje engedélyezi az ERC regiszterben bekövetkezett esemény jelzését SRQ kéréssel.
ERCE 1 engedélyezi az ERC regiszter legalsó bitjének változását, amit az 1. csatorna névleges áram túllépése okoz.
1. csatorna rövidzárása /csak nyugodtan!/ -> SRQ LED kigyullad.
i_testsrq	SRQ vizsgálat
Soros lekérdezés:
i_spoll 2 -1 A válasz a tápegység STB bájtja, benne a 2 értékű bit 1.
A SRQ ok megszüntetése /a zárlat megszüntetése után/:
i_send 2 -1  ERC? 0  és i_receive 2 -1  2  0   
Párhuzamos lekérdezés konfigurálás:
i_conf 2 5 1 A 2 című berendezés az 5. adatvonalat 1-be hajtja PP esetén, ha kiszolgálást kér.
i_send 2 -1  *PRE 2 0 A PRE regiszter 2 értékű bitje okozhatja a konfigurált PP bit beállítását. 
Párhuzamos lekérdezés:
i_ppoll megadja a PP bájtot, benne az 5. biten a tápegység állapotjelző bitje.

3. Az IEC busz működésének vizsgálata logikai analizátorral
Az IEC busz jeleit egy PC alapú logikai analizátorral vizsgáljuk. Az analizátor program a 12. gépen indítható: C:\ANAL\FDS.EXE.
Az analizátor paraméterei F1 leütése után állíthatók. A következő táblázat egy kedvező beállítást mutat. A triggert az 1. csatornára kötött DAV 0 szintje váltja ki.
CLOCK		INTERNAL
RATE			100 ns
THRESHOLD		+1.4  +1.4
TRIGGER		INTERNAL
	WORD
	XXXXXXXX	XXXXXX0X
	FILTER	100 ns
	POSITION  =T==========
	ENABLE	OFF
	OUTPUT	LOW
CHANNEL NAMES
sorrendben: REN, DAV, RFD, DAC, SRQ, IFC, ATN, EOI
illetve az adatvonalak: DIO 1..8
Mérés indítás F2-re. 
100 ns felbontással jól látható egy-egy adatátviteli ciklus.
1 us felbontással egy hosszabb parancssor is az EOI=1-el.

4. IEC busz vizsgálata IEC busz-analizátorral

Az analizátor LCD kijelzőjén az IEC buszon lezajlott utasítások mnemonikjai, a cím kijelölések valamint a készülékfüggő parancs-stringek láthatók.
Az analizátor saját HELP-je alapján kezelhető. 

5. Átviteli karakterisztika mérése a SIEMENS mérőrendszer segítségével

A mellékelt listán látható TRANSFER program egy átviteli karakterisztika mérésére szolgáló berendezés LabWindows alapú kezelői felületét valósítja meg. A program továbbfejlesztése MS C7-ben történhet.

6. A mérési feadatok
1. A BEDSIE program segítségével próbálja ki a tápegység, a függvénygenerátor valamint a multiméter különböző parancsait!
Állítson be különböző kimeneti feszültségeket a tápegységen, mérje meg egy-egy csatorna kimeneti feszültségét a multiméter segítségével. Állítson be különböző nagyságú, frekvenciájú és jelalakú kimenőjelet a funkciógenerátoron!
2. Vizsgálja meg a megszakításkérés és a lekérdezés lehetőségeit! A tápegység áramlimit túllépésével megszakításkérést válthat ki. Végezze el a soros és a párhuzamos lekérdezést!
3. A PC alapú logikai analizátor segítségével vegye fel az adatátviteli ciklust vezérlő hand-shake jellegzetes idődiagramját. Vizsgálja meg egy teljes készülékparancs átvitelének menetét. Mi jelzi az utolsó adat átvitelét?
4. Az IEC analizátor segítségével vizsgálja meg, hogy mi történik az IEC buszon egyszerű adatátvitel, soros illetve párhuzamos lekérdezés esetén!
5. C fejlesztési környezetben vizsgálja meg a TRANSFER program működését. Imerkedjen meg a program fejlesztés - javítás lépéseivel!
6. Egészítse ki a programot  a tápegység megszakításkérés lekezelésével!
7. Egészítse ki a programot úgy, hogy alkalmas legyen egy hangfrekvenciás erősítő átviteli karakterisztikájának mérésére! 

7. Ellenörző kérdések
1. Mire szolgál az IEC busz?
2. Milyen fő funkciókkal rendelkezhetnek az IEC buszra kapcsolódó berendezések?
3. Mire szolgálnak az IEC busz DIO1..8 vonalai?
4. Mely vonalakon és miért kell huzalozott VAGY kialakítására alkalmas meghajtókat használni?
5. Hogyan van megoldva és miért szükséges a buszvonalak lezárása?
6. Hány hallgató illetve beszélő címezhető meg a rendszerben?
7. Hány hallgató ill. beszélő cím képezhető szekunder utasítás segítségével és hogyan?
7. Hány megszakításkérő lehet a rendszerben? Hogyan történhet azonosítása?
8. Hasonlítsa össze a párhuzamos és a soros lekérdezési módot!
9. Mire szolgál a BEDSIE program?
10. Melyek egy berendezés IEC buszon keresztül történő vezérlésének lépései? 

Interfész panel és objektum azonosító konstansok, TRANSFER.H 

#define  TR  0	// fõpanel
#define  TR_pbox  0	// alátét doboz
#define  TR_fbox  1	// alátét doboz
#define  TR_Graph  2	// grafikon
#define  TR_VoltageDC  3	// tápfeszültség ablak
#define  TR_ClimitDC  5	// áramlimit ablak
#define  TR_plusLED  7	// túláram LED
#define  TR_minusLED  8	// túláram LED
#define  TR_StartFREQ  11	// start frekvencia
#define  TR_EndFREQ  12	// vég frekvencia
#define  TR_StepNUM  13	// lépésszám
#define  TR_VoltageFUN  16	// jel csúcsérték
#define  TR_SWEEP  18	// SWEEP indítás
#define  TR_StandbyDC  19	// táp. kapcsoló.
#define  TR_StandbyFUN  20	// generátor kapcsoló
#define  TR_Attenuation  21	// dekadikus osztó
#define  TR_EXIT  22	// kilépés
#define  TR_COPY  23	// nyomtatás
#define  TR_SEND  24	// üzenet küldés
#define  TR_REC  25	// üzenet vétel
#define  IEC  1	// üzenet panel
#define  IEC_TXT  0	// szöveg ablak
#define  IEC_ADDR  1	// IEC cím
#define  IEC_result  2	// visszaadott érték
#define  IEC_error  3	// IEC hibajelzés
#define  IEC_MESS  4	// üzenet ablak

IEC mérõrendszer DEMO program, TRANSFER.C 

#include "transfer.h"  /* panel konstansok */
#include <iecmsc.h>  /* IEC driver definiciók */
#include "userint.h"   /* grafikus felület kezelő LW függvények */
#include "math.h"
#include "string.h"
#include "stdio.h"
/*-----------------------------------------------------------------------------------------------------------*/
#define POWER_ADDR 2	/* tápegység IEC cím */
#define FUNC_ADDR 5 	/* funkciógenerátor IEC cím */
#define MULTI_ADDR 3	/* multiméter IEC cím */
#define WAIT 1	/* GetUserEvent vár */
#define NOWAIT 0	/* GetUserEvent nem vár */
/*-----------------------------------------------------------------------------------------------------------*/
int p,mp,pan,ctrl,intx,devaddr,res,powerV,powermA,funVpp,funatten,stepnum;
long startfr,endfr;
char buffer[100];	/* üzenet buffer */
int addrs[2];	/* cím tömb */
/*-----------------------------------------------------------------------------------------------------------*/
/* Függvények */
/*-----------------------------------------------------------------------------------------------------------*/
/* delay(0.1) sec!
/*PlotXY (panel, control ID, X array, Y array, numb. of points,
      4:double, 4:double, 0:line, 0:empty sq., 1: poin fr.,white:15);*/
/* sscanf(buf,"%f",&data); float data!*/
/*------------------------------------------------------------------------------------------------------------*/
/* IEC üzenet elküldése a bufferbõl, esetleg összeállítása is */
/*------------------------------------------------------------------------------------------------------------*/
int IECsend(int addr)
{
int len;

 SetCtrlVal(mp,IEC_error,0);	/* error ablak törlés */
 buffer[0]=0;	/* üzenet buffer törlés */
 SetCtrlVal(mp,IEC_TXT,buffer);	/* üzenet ablak törlés */

 InstallPopup(mp);	/* feltét panel megjelenítés */

 if (addr)	/* ha érvényes címmel hívták */
 {
  SetCtrlVal(mp,IEC_ADDR,addr);	/* cím kiírás */
  SetCtrlVal(mp,IEC_TXT,buffer);	/* készülék parancs kiírás */
  GetPopupEvent(1,&ctrl);	/* SAVE/QUIT megnyomásra vár */
 }
else  	/* ha 0 címmel hívták */
 {
  GetPopupEvent(1,&ctrl);	/* SAVE/QUIT megnyomásra vár */
  GetCtrlVal(mp,IEC_ADDR,&addr);	/* cím beolvasás */
  GetCtrlVal(mp,IEC_TXT,buffer); 	/* parancs szöveg beolvasás */
 };

 addrs[0]=addr;	/* cím lista töltés */
 len=strlen(buffer);	/* üzenet hossz */
 i_send(addrs,1,buffer,len,0);	/* üzenet küldés */

 SetCtrlVal(mp,IEC_TXT,"Message has been sent");      /* nyugta szöveg */ SetCtrlVal(mp,IEC_error,i_error);	/* IEC drájver hiba üzenet */

 buffer[0]=0;	/* buffer tölés */

 GetPopupEvent(1,&ctrl);	/* SAVE/QUIT megnyomásra vár */
 RemovePopup(mp);	/* feltét panel levétel */

} /* IECsend() */

/*-----------------------------------------------------------------------------------------------------------*/
/* IEC üzenet vétel */
/*-----------------------------------------------------------------------------------------------------------*/
int IECreceive(int addr)
{
int len,i;

 len=100;	/* max. üzenet hossz */
 for (i=0; i < len; i++) buffer[i]=0;	/* üzenet buffer törlés */

 SetCtrlVal(mp,IEC_TXT,buffer);	/* üzenet ablak törlés */
 SetCtrlVal(mp,IEC_error,0);	/* error ablak törlés */

 InstallPopup(mp);	/* feltét panel felrajzolás */

 if (!addr)	/* ha 0 címmel hívták */
 {
  GetPopupEvent(1,&ctrl);	/* SAVE/QUIT megnyomásra vár */
  GetCtrlVal(mp,IEC_ADDR,&addr); 	/* cím beolvasás */
 };

 i_receive(addr,buffer,len,0);	/* vétel az 'addr' beszélõtõl */

 SetCtrlVal(mp,IEC_TXT,buffer);	/* az üzenet kiírása az ablakba */	
 SetCtrlVal(mp,IEC_error,i_error);	/* IEC hibajelzés kiírása */

 GetPopupEvent(1,&ctrl);	/* SAVE/QUIT megnyomásra vár */

 RemovePopup(mp);	/* feltét panel törlése */

} /* IECreceive() */
/*-----------------------------------------------------------------------------------------------------------*/
/*-----------------------------------------------------------------------------------------------------------*/
/*-----------------------------------------------------------------------------------------------------------*/
void main()
/*-----------------------------------------------------------------------------------------------------------*/
{
int res,err,event;

res=i_init(0);	/* IEC vezérlõ kártya inícializálás */
if (res!=1) {MessagePopup("IEC board initialisation error");};

res=i_assign_auto();
if (i_error==-182) {MessagePopup("IEC bus timeout error");};

addrs[1]=-1;

p = LoadPanel ("TRANSFER.UIR", TR); 	/* fõpanel */
mp = LoadPanel ("TRANSFER.UIR", IEC); 	/* IEC adás-vétel panel */
SetActiveCtrl(TR_StandbyDC);

DisplayPanel (p);

while (1)
{
 GetUserEvent(WAIT,&pan,&ctrl);	/* eseményre vár */
 /* event=GetUserEvent(NOWAIT,&pan,&ctrl);  nem vár  */

 switch(ctrl)
  {
    case TR_EXIT: exit(0); break;	/* kilépés az EXIT gombbal */
   
  case TR_MESS: IECsend(0); break;	/* üzenet küldés a SEND gombbal */

  case TR_REC: IECreceive(0); break;	/* üzenet vétel a REC gombbal */

  case TR_StandbyDC:	/* tápegység ON-OFF kapcsoló */
    GetCtrlVal(p,TR_StandbyDC,&intx);

    if (intx) 	/* bekapcsolás */
    {
     GetCtrlVal(p,TR_VoltageDC,&powerV);
     GetCtrlVal(p,TR_ClimitDC,&powermA);

     sprintf(buffer,"VOLTAGE 3,%i; CURRENT 3,0.%i",powerV,powermA);
     IECsend(POWER_ADDR);
     sprintf(buffer,"CLIMIT 3,0.%i",powermA+1);
     IECsend(POWER_ADDR);
     sprintf(buffer,"VOLTAGE 5,%i; CLIMIT 5,0.%i",powerV,powermA);
     IECsend(POWER_ADDR);
     sprintf(buffer,"CLIMIT 5,0.%i",powermA+1);
     IECsend(POWER_ADDR);

     sprintf(buffer,"STANDBY 3,OFF; STANDBY 5,OFF");
     IECsend(POWER_ADDR);
    }
    else	/* kikapcsolás */
    {
     sprintf(buffer,"STANDBY 3,ON; STANDBY 5,ON");
     IECsend(POWER_ADDR);
    };
    break;

 case TR_StandbyFUN:	/* jelgenerátor ON-OFF kapcsoló */

    GetCtrlVal(p,TR_StandbyFUN,&intx);

    if (intx)	/* bekapcsolás */
    {
     GetCtrlVal(p,TR_VoltageFUN,&funVpp);
     GetCtrlVal(p,TR_Attenuation,&funatten);

     GetCtrlVal(p,TR_StartFREQ,&startfr);
     sprintf(buffer,"AMPLITUDE %i; ATTEN %i; FREQ %i",funVpp,funatten,startfr);
     IECsend(FUNC_ADDR);

     sprintf(buffer,"STANDBY OFF");
     IECsend(FUNC_ADDR);
    }
    else	/* kikapcsolás */
    {
     sprintf(buffer,"STANDBY ON");
     IECsend(FUNC_ADDR);
    };

    break;

 case TR_SWEEP:	/* SWEEP nyomógomb */

 break;

case TR_COPY: 

  break;	/* hardcopy */

  }/*switch*/
 }/*while*/
}/*main*/