Навеяно предыдущей темой. Там еще цветочки. Как вам такое:
void measure(void) {
static BYTE phst, amup;
static SBYTE phcnt, enas;
static SWORD swm;
static SWORD cmax[ADC_ARRAY_CHANS], cmin[ADC_ARRAY_CHANS];
static SWORD cpos[ADC_ARRAY_CHANS], cneg[ADC_ARRAY_CHANS];
static SWORD i,j,k,n[ADC_ARRAY_CHANS], izp,izn;
static WORD cavr[ADC_ARRAY_CHANS];
static str_ac_phph_par freq, dphi;
static BYTE err[ADC_ARRAY_CHANS];
static float diph; // äèñêðåòà èçìåðåíèÿ ôàçû
static float Cfv;
switch(adc.stm) {
case AST_START: //---------------------------------------------
start_measure();
break;
case AST_READY: //---------------------------------------------
adc.nam=adc.ng;
for(j=0; j<ADC_ARRAY_CHANS; j++) {
cmax[j]=0x8000; cmin[j]=0x7FFF; amup=1;
for(i=0; i<ADC_BUF_LEN; i++) { swm=adc.ab[i][j];
if(adc.acdef[j][adc.nam].inv) swm=((~swm) & 0x03FF);
if(swm&0x0200 && adc.acdef[j][adc.nam].bip) swm|=0xFC00;
adc.abuf[i][j]=swm;
if(swm>cmax[j]) cmax[j]=swm;
if(swm<cmin[j]) cmin[j]=swm; }
if(cmax[j] >= AMPLIFY_UP_COD ||
cmin[j] <=-AMPLIFY_UP_COD) amup=0; }
if(amup && !adc.ovf.fcd &&
adc.ng==ADC_AMPLIFY_1 &&
(adc.ovf.stin<0 || adc.ovf.stin>=STAY_AMPLIFY_1) &&
pcd.oper!=OPER_START) pcd.nampl=ADC_AMPLIFY_10;
adc.ng=pcd.nampl;
for(i=0; i<ADC_VALUE_CHANS; i++) adc.vbuf[i]=adc.vb[i];
if(adc.ovf.stin>=0 && adc.ovf.stin<CYCLES_OVF_REG-1) adc.ovf.stin++;
else { int i,j;
adc.ovf.stin=-1; adc.ovf.stcn=0;
for(j=0; j<ADC_ARRAY_CHANS; j++)
for(i=0; i<CYCLES_OVF_REG; i++)
if(adc.ovf.star[i][j]) adc.ovf.stcn=i+1; }
adc.stm=AST_START;
mead.stc=STC_EXTRA;
break;
default: break; }
switch(mead.stc) {
case STC_EXTRA:
for(j=0; j<ADC_ARRAY_CHANS; j++) { err[j]=0;
if(cmax[j]<MIN_VALID_COD) { err[j]=ERR_AC_NOPOS;
if(cmax[j]<-MIN_VALID_COD)
err[j]=ERR_AC_DCNEG;
if(cmin[j]>-MIN_VALID_COD) err[j]=ERR_AC_NOVOLT; }
else
if(cmin[j]>-MIN_VALID_COD) { err[j]=ERR_AC_NONEG;
if(cmin[j]>MIN_VALID_COD) err[j]=ERR_AC_DCPOS; } }
phst=0; j=0;
mead.stc=STC_PHASE;
break;
case STC_PHASE: //---------------------------------------------
//---zero cross detect
enas=(n[j]==0)?0:adc.inz[j][n[j]-1]; // çíàê ïðåäûäóùåãî ïåðåõîäà
switch(phst) {
case 0:
for(k=0; k<ADC_ZERO_MAXNUM; k++) adc.inz[j][k]=0;
n[j]=0; i=0; izp=0; izn=0; phcnt=0;
phst=1;
break;
case 1:
if(phcnt<0)
if(phcnt<=-ONE_SIGN_LEN) { izp=-i; if(vira(i,j)>=0) { phcnt=1; phst=2; } }
else if(vira(i,j)<0 && enas>=0) phcnt--; else phcnt=1;
else
if(phcnt>=ONE_SIGN_LEN) { izp=i; if(vira(i,j)<0) { phcnt=-1; phst=2; } }
else if(vira(i,j)>=0 && enas<=0) phcnt++; else phcnt=-1;
goto l_next_i;
case 2:
if(izp>0) { if(vira(i,j)<0) phcnt--; else phcnt=1;
if(phcnt<=-ONE_SIGN_LEN) { izn=ONE_SIGN_LEN-i; phst=3; } }
else { if(vira(i,j)>=0) phcnt++; else phcnt=-1;
if(phcnt>=ONE_SIGN_LEN) { izn=i-ONE_SIGN_LEN; phst=3; } }
goto l_next_i;
case 3:
if(izp!=0 && izn!=0) { swm=swabs(izp+izn);
adc.inz[j][n[j]]=(swm>ONE_SIGN_LEN)?-izn:(izp-izn)/2; }
n[j]++; if(n[j]<ADC_ZERO_MAXNUM) { izp=0; izn=0; phcnt=0; phst=1; }
else { j++; if(j<ADC_ARRAY_CHANS) phst=0; else phst=4; }
break;
case 4:
// ÷àñòîòà ñåòè 50 Ãö
adc.lnt=0; freq.is=0; freq.val=0.f;
for(j=0; j<ADC_ARRAY_CHANS; j++) if(err[j]==0) {
if(n[j]==3) { izp=swabs(adc.inz[j][0]); izn=swabs(adc.inz[j][2]);
adc.lnt=izn-izp+2;
freq.val=1.f/((float)adc.lnt*0.00025f);
break; } }
if(!freq.is)
for(j=0; j<ADC_ARRAY_CHANS; j++) if(err[j]==0) {
if(n[j]==2) { izp=swabs(adc.inz[j][0]); izn=swabs(adc.inz[j][1]);
adc.lnt=izn-izp+1;
freq.val=0.5f/((float)adc.lnt*0.00025f);
adc.lnt*=2; break; } }
далее еще несколько страниц той же функции