/* задача опpоса сети HART-модем */ #include "complex.h" #include "screen.h" extern word_s setting(analog *a_ptr,float work_f); extern void koeff_sc(analog *a_ptr); extern byte * z_db(byte *x_db,int len); extern word_s numrec, lenrec, fh, N_MAN; extern char *recfil; void inf_IOCTL(word_s); #pragma aux inf_IOCTL = "mov ax,4400h "\ "int 21h "\ "mov dh,0 "\ "or dl,20h "\ "mov ax,4401h "\ "int 21h "\ modify [eax edx ebx] \ parm [bx] ; void write_IOCTL(word_s,char *, word); #pragma aux write_IOCTL = "mov ax,4403h "\ "int 21h "\ modify [eax] \ parm [bx] [edx] [cx] ; void read_IOCTL(word_s,char *, word); #pragma aux read_IOCTL = "mov ax,4402h "\ "int 21h "\ modify [eax] \ parm [bx] [edx] [cx] ; word_s ready(word_s h); byte ioctl[]= { 0x14,0x00,0x60,0x00,0x02,0x00,0x80,0x00 }; /* 0x03 */ byte cmd_0[]={ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, 0x02,0x80,0x00,0x00,0x00 }; byte cmd_1[]={ 0xff,0xff,0xff,0xff,0xff, 0x82,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00 }; float var_dat[16]; byte flag_scan[16]; /*-------------------------------------------------------------------*/ void taskHART(controller *ptr_c) { word_s h,i,j,kz,ks,val; // word sg,of; analog *ptr_a; byte work[6]; float *pf,vf; byte *ask, *ans; if(ptr_c->period==0) { ptr_c->kz=1; kz_com(1,ptr_c); return; } h=open("HART~",O_BINARY|O_RDWR); if(h < 0) { eprintf(RED_,"Не открылся драйвер HART~"); ptr_c->kz=-1; kz_com(-1,ptr_c); return; } if((ask = (byte *)calloc(1,256))==NULL) { eprintf(RED_,"TASKHART.C - Мало памяти"); return; } ans=ask+128; /* IOCTL - получить информацию о внешнем устройстве */ /* и установить дескриптор устройства в двоичный режим */ inf_IOCTL(h); // _asm { // mov ax,4400h // mov bx,h // int 21h // mov dh,0 // or dl,20h // mov ax,4401h // int 21h // } /* записать управляющие данные в устройство */ // sg=(word)((long)ioctl>>16); // of=(word)ioctl; write_IOCTL(h,ioctl,8); // _asm { // mov ax,4403h // mov bx,h // mov cx,8 // push ds // mov dx,sg // mov ds,dx // mov dx,of // int 21h // pop ds // } /*------------* Цикл опpоса ---------------------------------*/ while(!endrun) { #if (DOG_TIMER==1) tsk_outp(0x443,30); #elif (DOG_TIMER==2) tsk_inp(0x43); tsk_inp(0x443); #endif wait_flag_set(ptr_c->flag, 0L); clear_flag(ptr_c->flag); for(i=0; i<16; i++) { flag_scan[i]=0xff; var_dat[i]=1000010.0; } for(i=0, ptr_a=ptr_c->a_ptr; i < ptr_c->num_ap; i++, ptr_a++) { if(ptr_a->mod_cod==M_INP) continue; if(ptr_a->nolog) continue; if(flag_scan[ptr_a->nomin_var+1]) { flag_scan[ptr_a->nomin_var+1]=0; if(!ptr_a->set_cod) { memcpy(ask,cmd_0,sizeof(cmd_0)); ask[21]=(ptr_a->nomin_var+1)|0x80; for(j=20; j<24; j++) ask[24] ^= ask[j]; kz=write(h,ask,sizeof(cmd_0)); if(kz <= 0) { ptr_c->kz=ptr_a->nomin_var+1; kz_com(ptr_a->nomin_var+1,ptr_c); ptr_a->novalid=1; continue; } while(!ready(h)) t_delay(5L); kz=read(h,ans,128); if(kz==19) { ks=0; for(j=0; j<18; j++) ks ^= ans[j]; } if(kz != 19 || ans[18] != ks) { ptr_c->kz=ptr_a->nomin_var+1; kz_com(ptr_a->nomin_var+1,ptr_c); ptr_a->novalid=1; continue; } work[0]=ans[7]|0x80; work[1]=ans[8]; work[2]=ans[15]; work[3]=ans[16]; work[4]=ans[17]; memcpy(&ptr_a->set_cod,work,5); } memcpy(ask,cmd_1,sizeof(cmd_1)); memcpy(ask+6,&ptr_a->set_cod,5); for(j=5; j<13; j++) ask[13] ^= ask[j]; kz=write(h,ask,sizeof(cmd_1)); if(kz <= 0) { ptr_c->kz=ptr_a->nomin_var+1; kz_com(ptr_a->nomin_var+1,ptr_c); ptr_a->novalid=1; continue; } while(!ready(h)) t_delay(5L); kz=read(h,ans,128); if(kz==16) { ks=0; for(j=0; j<15; j++) ks ^= ans[j]; } if(kz != 16 || ans[9] != 0 && ans[9] != 0x08 || ans[15] != ks) { ptr_c->kz=ptr_a->nomin_var+1; kz_com(ptr_a->nomin_var+1,ptr_c); ptr_a->novalid=1; continue; } ptr_c->kz=0; kz_com(0,ptr_c); work[0]=ans[14]; work[1]=ans[13]; work[2]=ans[12]; work[3]=ans[11]; pf=(float *)work; var_dat[ptr_a->nomin_var+1]=*pf; } if(var_dat[ptr_a->nomin_var+1] > 1000000.0) { ptr_a->novalid=1; continue; } ptr_a->novalid=0; ptr_a->var_tech=var_dat[ptr_a->nomin_var+1]; vf=ptr_a->var_tech; if(ptr_a->var_tech < ptr_a->min_sc) { vf = ptr_a->min_sc; ptr_a->novalid=1; } if(ptr_a->var_tech > ptr_a->max_sc) { vf = ptr_a->max_sc; ptr_a->novalid=1; } if(!ptr_a->no_uchet) ptr_a->var_tech=vf; /*************/ val=(float)ADC_SC*(vf-ptr_a->min_sc)/(ptr_a->max_sc-ptr_a->min_sc)+0.5; if(val < 0) val=0; else if(val > ADC_SC) val=ADC_SC; ptr_a->dif_var = 1; ptr_a->var_cod = val; if(ptr_a->min_reg && val < ptr_a->min_reg) ptr_a->bound_reg = 1; else if(ptr_a->max_reg && val > ptr_a->max_reg) ptr_a->bound_reg = 2; else ptr_a->bound_reg = 0; if(ptr_a->min_al && val < ptr_a->min_al) ptr_a->bound_al = 1; else if(ptr_a->max_al && val > ptr_a->max_al) ptr_a->bound_al = 2; else ptr_a->bound_al = 0; /* if(ptr_a->var_cod < 20 || ptr_a->var_cod > ADC_SC-20) ptr_a->novalid=1; */ } } } /*-----------------------------------------------------------------*/ word_s ready(word_s h) { // word sg,of; byte rio[2]; /* чтение управляющих данных из устройства */ rio[0]=0; // sg=(word)((long)rio>>16); // of=(word)rio; read_IOCTL(h,rio,1); // _asm { // mov ax,4402h // mov bx,h // mov cx,1 // push ds // mov dx,sg // mov ds,dx // mov dx,of // int 21h // pop ds // } return rio[0]; } //------------------------------ Выдача сообщения об ошибке опроса --------------------- word_s kz_mesage_HART(controller *pc,word_s kz,word_s chn,word_s kz_old) { char *ps; if(pc->nom_ord!=chn || kz_old!= kz) { switch(kz) { case -1 : ps="HART-модем %d: Не установлен драйвер"; break; default : ps="HART-модем %d, датчик %2d: Нет связи"; break; } fgtext(RED_,280,337,ps,pc->nomcontr,kz); } return(pc->nom_ord); } //------------------------------ Вставка описателей параметров для контроллера void insert_A_HART(analog * a_ptr) { word_s i, work_i; float work_f; byte *x_db; for(i=0; i < numrec; i++, a_ptr++) { read(fh, recfil, lenrec); a_ptr->novalid = 1; strncpy(a_ptr->cipher, (x_db = recfil + 1), 9); strncpy(a_ptr->name, (x_db+= 9), 25); strncpy(a_ptr->unit, (x_db+= 25), 9); sscanf(x_db+= 9, "%1hd", &work_i); a_ptr->type_sc = (byte)work_i; sscanf(z_db(x_db+= 1,8), "%8f", &a_ptr->min_sc); sscanf(z_db(x_db+= 8,8), "%8f", &a_ptr->max_sc); koeff_sc(a_ptr); sscanf(z_db(x_db+= 8,8),"%8f",&work_f); a_ptr->min_reg = setting(a_ptr,work_f); sscanf(z_db(x_db+= 8,8),"%8f",&work_f); a_ptr->max_reg = setting(a_ptr,work_f); sscanf(z_db(x_db+= 8,8),"%8f",&work_f); a_ptr->min_al = setting(a_ptr,work_f); sscanf(z_db(x_db+= 8,8),"%8f",&work_f); a_ptr->max_al = setting(a_ptr,work_f); sscanf(z_db(x_db+= 8,2),"%2hd",&work_i); a_ptr->nomin_var = (byte)(work_i-1); sscanf(x_db+= 2,"%1hd",&work_i); a_ptr->sum_ysr = work_i; sscanf(x_db+= 1,"%1hd",&work_i); a_ptr->type_mech=(byte)work_i; if(a_ptr->type_mech==M_INP) { if(a_ptr->k_scale > 0) a_ptr->novalid = 0; a_ptr->type_mech=0; a_ptr->mod_cod=M_INP; N_MAN += 1; } } }