цифровые измерительные приборы. Национальный технический университет украины киевский политехнический институт кафедра систем автоматизированного проектирования
Скачать 0.83 Mb.
|
Листов2000 СОДЕРЖАНИЕ
П1. Листинг разработанной программы, реализующей методику расчета { Программа расчета активных RC-фильтров нижних частот } { с аппроксимацией частотных характеристик по Баттерворту } { ФЭЛ НТУУ "КПИ" - Киев 2000 } Program ARC; Uses Crt,Graph; Const R0 = 1e+5; { нормирующий коэффициент } MAX_ORDER = 50; { максимальный порядок фильтра } POINTS = 400; { количество точек для расчета АЧХ } atd_file = 'filter.atd'; tab_file = 'filter.tab'; txt_file = 'filter.txt'; Type complex = record { комплексное число } im : double; re : double; end; ShemType = (invert,MOS,bikvadrat); { тип схемной реализации звена } section = record { описание звена } shem : ShemType; { тип схемы } R1,R2,R3,R4,C1,C2:double; { номиналы компонентов схемы } Q : double; { добротность } end; Var Fc : double; { частота среза } F1 : double; { граничная частота полосы задерживания } Af : double; { макс. неравномерность в полосе пропускания } Bf : double; { мин. затухание в полосе задерживания } F0 : double; { нормирующая частота } N : integer; { порядок фильтра } H : double; { числитель передаточной функции } Hi : double; { числитель передаточной функции каждого звена } sigma0:double; { радиус полуокружности на которой находятся полюса } Poles : array[1..MAX_ORDER div 2 + 1] of complex; {массив полюсов} Sections: array[1..MAX_ORDER div 2 + 1] of section; {массив звеньев} AFC : array[1..POINTS] of double; {массив АЧХ} sect : integer; {кол-во звеньев} low_freq :double; { нижняя граница частоты для расчета АЧХ } high_freq:double; { верхняя граница частоты для расчета АЧХ } ch : char; Function Lg(x:double):double; { десятичный логарифм } var result:double; begin result:=Ln(x)/2.30258509299405E+0000; { Lg(x)=Ln(x)/Ln(10)} Lg:=result; end; Function Pow10(x:double):double; { 10 в степени x } var result:double; begin result:=exp(x*2.30258509299405E+0000); pow10:=result; end; Function Pow(a:double;x:double):double; { pow(a,x)=a^x } var result:double; begin if (a<=0) then Halt(1); result:=exp(x*ln(a)); pow:=result; end; Procedure _Add(a:complex; b:complex; var c:complex);{комплексное сложение} begin c.re:= a.re + b.re; c.im:= a.im + b.im; end; Procedure _Sub(a:complex; b:complex; var c:complex);{комплексное вычитание} begin c.re:= a.re - b.re; c.im:= a.im - b.im; end; Procedure _Mult(a:complex; b:complex; var c:complex);{комплексное умножение} begin c.re:= a.re*b.re - a.im*b.im; c.im:= a.re*b.im + a.im*b.re; end; Function _Abs(a:complex):double; { модуль комплексного числа } var result:double; begin result:=sqrt(sqr(a.re)+sqr(a.im)); _Abs:=result; end; Procedure _Div(a:complex; b:complex; var c:complex);{комплексное деление} begin b.im:=-b.im; _Mult(a,b,c); c.re:= c.re/(sqr(b.re)+sqr(b.im)); c.im:= c.im/(sqr(b.re)+sqr(b.im)); end; Procedure LowPassFilter_Parameters;{ ввод исходных данных для расчета } var ch : char; error : boolean; begin error:=true; while error do begin ClrScr; TextColor(LIGHTGREEN); writeln('Ввод исходных данных для расчета ARC-ФНЧ'); writeln('----------------------------------------'); GoToXY(1,4); write('Частота среза Fc, Гц : '); read(Fc); writeln; writeln('Неравномерность коэф. передачи '); write('в полосе пропускания Aф, дБ : '); read(Af); writeln; writeln('Граничная частота полосы'); write('задерживания F1, Гц : '); read(F1); writeln; writeln('Минимальное затухание '); write('в полосе задерживания Bф, дБ : '); read(Bf); writeln; TextColor(LIGHTRED); if (Fc<=0) or (F1<=0) then writeln ('Ошибка в исходных данных : Fc<=0 или F1<=0') else if (Af<=0) or (Bf<=0) then writeln ('Ошибка в исходных данных : Aф <=0 или Bф <=0') else if Af>=Bf then writeln ('Ошибка в исходных данных : Aф >= Bф !') else if Fc>F1 then writeln ('Ошибка в исходных данных : Fc >= F1 !') else error:=false; writeln('Нажмите Enter');ch:=#255; while ch<>#13 do ch:=Readkey; TextColor(LIGHTGREEN); end; end; Procedure LowPassFilter_Norming;{ нормирование частот } begin F0:=Fc; Fc:=1; F1:=F1/F0; end; Procedure LowPassFilter_Batterworth_Order; { расчет порядка фильтра } var order:double; begin order:=0.5*lg((pow10(0.1*Bf)-1)/ (pow10(0.1*Af)-1))/ lg(F1); if order>MAX_ORDER then begin TextColor(LIGHTRED); writeln('Программа не может рассчитать фильтр'); writeln('Требуемый порядок фильтра превышает ',MAX_ORDER); writeln('Требуется порядок фильтра = ',order); writeln('Нажмите Enter');ch:=#255; while ch<>#13 do ch:=Readkey; TextColor(LIGHTGREEN); Halt(1); end; if order<=0 then begin TextColor(LIGHTRED); writeln('Программа не может рассчитать фильтр'); writeln('Получен отрицательный или нулевой порядок фильтра = ',order); writeln('Нажмите Enter');ch:=#255; while ch<>#13 do ch:=Readkey; TextColor(LIGHTGREEN); Halt(1); end; N:=Trunc(order)+1; if (N mod 2 = 1) then sect:= N div 2 + 1 else sect:= N div 2; end; Procedure LowPassFilter_Batterworth_Sigma0;{расчет радиуса полуокружности} begin sigma0:=pow(pow10(0.1*Af)-1,-1/(2*N)); end; Procedure LowPassFilter_Batterworth_H;{расчет числителя передаточной функции} begin H := 1.0/sqrt(pow10(0.1*Af)-1); Hi:=H; end; Procedure LowPassFilter_Batterworth_Poles;{расчет полюсов фильтра} var i:integer; begin for i:=1 to sect do begin poles[sect-i+1].re:= - sigma0 * sin ((2*i-1)*Pi/(2*N)); poles[sect-i+1].im:= - sigma0 * cos ((2*i-1)*Pi/(2*N)); end; { при нечетном N звену первого порядка соответствует poles[1]} end; { выбор схемной реализации и расчет номиналов } Procedure LowPassFilter_Building; var i : integer; C : double; delta : double; beta : double; gamma : double; scale : double; D:double; begin { C задается таким образом, чтобы при денормировании получить 1.0} C:=(2*pi*f0)/(pow10(Trunc(lg(f0))+1.0)); i:=1; { при нечетном N звену первого порядка соответствует poles[1]} if (N mod 2 = 1) then {построение звена первого порядка} begin delta:= -poles[1].re; sections[1].shem := invert; {на инвертирующем ОУ} sections[1].C1 := C; sections[1].R1 := 1/(C*Hi); sections[1].R2 := 1/(C*delta); i:=2; Hi:=1; end; while i<=sect do {построение звена второго порядка} begin beta := -2*poles[i].re; gamma:= sqr(poles[i].re)+sqr(poles[i].im); sections[i].Q:=sqrt(gamma)/beta; if sections[i].Q<=10 then with sections[i] do begin shem := MOS; {с многопетлевой обратной связью} C1 := C; scale:= 1.001*4*gamma*(Hi/gamma+1)/(beta*beta); C2 := C1*scale; D := beta*beta*C2*C2 - 4*C1*C2*gamma*(Hi/gamma+1); R2 := 2*(Hi/gamma+1)/(beta*C2 + sqrt(D)); R1 := R2*gamma/Hi; R3 := 1.0/(C1*C2*R2*gamma); end else with sections[i] do begin shem := bikvadrat; {биквадратное звено} C1 := C; R4 := 1.0/C1; R1 := 1.0/(Hi*C1*C1*R4); R2 := 1.0/(beta*C1); R3 := 1.0/(R4*C1*C1*gamma); end; i:=i+1; Hi:=1; end; end; { денормирование электрических параметров } Procedure LowPassFilter_Denorming; var i:integer; begin for i:=1 to sect do begin sections[i].R1:= sections[i].R1 * R0; sections[i].R2:= sections[i].R2 * R0; sections[i].R3:= sections[i].R3 * R0; sections[i].R4:= sections[i].R4 * R0; sections[i].C1:= sections[i].C1 / (R0*2*pi*f0); sections[i].C2:= sections[i].C2 / (R0*2*pi*f0); end; end; Procedure LowPassFilter_Info;{ вывод результатов расчета фильтра} var i,j:integer; f:text; begin Assign(f,txt_file); Rewrite(f); ClrScr; writeln(' Результаты расчета ФНЧ с аппроксимацией АЧХ по Баттерворту '); writeln('------------------------------------------------------------------------------'); writeln('Исходные данные : Частота среза Fc = ',Fc*F0:10:4,' Гц'); writeln(' Неравномерность Аф = ',Af :10:4,' дБ'); writeln(' Граничная частота F1 = ',F1*F0:10:4,' Гц'); writeln(' Затухание BФ = ',Bf :10:4,' дБ'); writeln('------------------------------------------------------------------------------'); writeln('порядок,тип звена Q С1,мкФ С2,мкФ R1,кОм R2,кОм R3,кОм R4,кОм '); writeln('------------------------------------------------------------------------------'); writeln(f,' Результаты расчета ФНЧ с аппроксимацией АЧХ по Баттерворту '); writeln(f,'------------------------------------------------------------------------------'); writeln(f,'Исходные данные : Частота среза Fc = ',Fc*F0:10:4,' Гц'); writeln(f,' Неравномерность Аф = ',Af :10:4,' дБ'); writeln(f,' Граничная частота F1 = ',F1*F0:10:4,' Гц'); writeln(f,' Затухание BФ = ',Bf :10:4,' дБ'); writeln(f,'------------------------------------------------------------------------------'); writeln(f,'Порядок фильтра = ',N); writeln(f,'Количество звеньев = ',sect); writeln(f,'------------------------------------------------------------------------------'); for i:=1 to sect do begin j:= whereY; if sections[i].shem=invert then begin gotoxy( 1,j);writeln('1 инверт.ОУ'); gotoxy(24,j);writeln(sections[i].C1*1.0e+6:8:4); gotoxy(42,j);writeln(sections[i].R1/1.0e+3:8:3); gotoxy(51,j);writeln(sections[i].R2/1.0e+3:8:3); writeln(f,'Звено первого порядка'); writeln(f,'на инвертирующем ОУ '); writeln(f,'C1=',sections[i].C1*1.0e+6:10:4,' мкФ'); writeln(f,'R1=',sections[i].R1/1.0e+3:10:4,' кОм'); writeln(f,'R2=',sections[i].R2/1.0e+3:10:4,' кОм'); writeln(f,'---------------------'); end; if sections[i].shem=MOS then begin gotoxy( 1,j);writeln('2 звено МОС'); gotoxy(15,j);writeln(sections[i].Q:8:4); gotoxy(24,j);writeln(sections[i].C1*1.0e+6:8:4); gotoxy(33,j);writeln(sections[i].C2*1.0e+6:8:4); gotoxy(42,j);writeln(sections[i].R1/1.0e+3:8:3); gotoxy(51,j);writeln(sections[i].R2/1.0e+3:8:3); gotoxy(60,j);writeln(sections[i].R3/1.0e+3:8:3); writeln(f,'Звено второго порядка'); writeln(f,'с многопетлевой ОС '); writeln(f,'Q =',sections[i].Q:10:4); writeln(f,'C1=',sections[i].C1*1.0e+6:10:4,' мкФ'); writeln(f,'C2=',sections[i].C2*1.0e+6:10:4,' мкФ'); writeln(f,'R1=',sections[i].R1/1.0e+3:10:4,' кОм'); writeln(f,'R2=',sections[i].R2/1.0e+3:10:4,' кОм'); writeln(f,'R3=',sections[i].R3/1.0e+3:10:4,' кОм'); writeln(f,'---------------------'); end; if sections[i].shem=bikvadrat then begin gotoxy( 1,j);writeln('2 биквадрат.'); gotoxy(15,j);writeln(sections[i].Q:8:4); gotoxy(24,j);writeln(sections[i].C1*1.0e+6:8:4); gotoxy(42,j);writeln(sections[i].R1/1.0e+3:8:3); gotoxy(51,j);writeln(sections[i].R2/1.0e+3:8:3); gotoxy(60,j);writeln(sections[i].R3/1.0e+3:8:3); gotoxy(69,j);writeln(sections[i].R4/1.0e+3:8:3); writeln(f,'Звено второго порядка'); writeln(f,'биквадратное '); writeln(f,'Q =',sections[i].Q:10:4); writeln(f,'C1=',sections[i].C1*1.0e+6:10:4,' мкФ'); writeln(f,'R1=',sections[i].R1/1.0e+3:10:4,' кОм'); writeln(f,'R2=',sections[i].R2/1.0e+3:10:4,' кОм'); writeln(f,'R3=',sections[i].R3/1.0e+3:10:4,' кОм'); writeln(f,'R4=',sections[i].R4/1.0e+3:10:4,' кОм'); writeln(f,'---------------------'); end; if (j = 20) then begin TextColor(LIGHTRED); writeln('Нажмите Enter, чтобы посмотреть остальные звенья '); ch:=#255; while ch<>#13 do ch:=Readkey; TextColor(LIGHTGREEN); ClrScr; GoToXY(1,1); writeln('------------------------------------------------------------------------------'); writeln('порядок,тип звена Q С1,мкФ С2,мкФ R1,кОм R2,кОм R3,кОм R4,кОм '); writeln('------------------------------------------------------------------------------'); end; end; writeln('------------------------------------------------------------------------------'); writeln('Порядок фильтра = ',N); writeln('Количество звеньев = ',sect); writeln('------------------------------------------------------------------------------'); Close(f); TextColor(LIGHTRED); writeln('Нажмите Enter');ch:=#255; while ch<>#13 do ch:=Readkey; TextColor(LIGHTGREEN); end; { расчет АЧХ спроектированного фильтра } Procedure LowPassFilter_AFC; var g:text; i,j:integer; f,df,w:double; K :complex; pp :complex; Hi , delta : double; beta, gamma : double; begin Assign(g,tab_file); Rewrite(g); writeln(g,'Таблица значений ЛАЧХ фильтра нижних частот:'); writeln(g,'--------------------------------------------'); writeln(g,' Частота Ку '); writeln(g,'----------------------------'); low_freq :=1.0; high_freq:=F1*F0*2.0; df:=high_freq/POINTS; f:=0.0; j:=1; while j<=POINTS do begin w:=2*pi*f; K.re :=1; K.im :=0; for i:=1 to sect do begin if sections[i].shem=invert then begin with sections[i] do begin Hi:=1/(R1*C1); delta:=1/(R2*C1); end; K.re :=K.re*Hi; K.im :=K.im*Hi; pp.re:= delta; pp.im:= w; _Div(K,pp,K); end; if sections[i].shem=MOS then begin with sections[i] do begin Hi :=1/( R1*R3*C1*C2 ); beta :=( 1/R1 + 1/R2 + 1/R3 )/C2; gamma:=1/(R2*R3*C1*C2); end; K.re :=K.re*Hi; K.im :=K.im*Hi; pp.re:=gamma - w*w; pp.im:=beta*w; _Div(K,pp,K); end; if sections[i].shem=bikvadrat then begin with sections[i] do begin Hi :=1/(R1*R4*C1*C1); beta :=1/(R2*C1); gamma:=1/(R3*R4*C1*C1); end; K.re :=K.re*Hi; K.im :=K.im*Hi; pp.re:=gamma - w*w; pp.im:=beta*w; _Div(K,pp,K); end; end; AFC[j]:=20*lg(_Abs(K)); writeln(g,f:8:2,' Гц ',AFC[j]:8:2,' дБ '); f:=f+df; j:=j+1; end; Close(g); end; {создание файла задания для моделирования АЧХ} Procedure LowPassFilter_ALLTED; var f:text; i:integer; k:integer; { узел для входа текущего звена } r:integer; c:integer; qq:integer; begin Assign(f,atd_file); Rewrite(f); writeln(f,'OBJECT; '); writeln(f,'SEARCH PRAM; '); writeln(f,'CIRCUIT ARCFLT; '); writeln(f,'Ein(1,0)=1; '); k:=1; r:=1; c:=1; qq:=1; for i:= 1 to sect do begin if sections[i].shem=invert then with sections[i] do begin writeln(f,'R',r,'(',k ,',',k+1,')=',R2/1e+3:10:6,';'); r:=r+1; writeln(f,'R',r,'(',k+1,',',k+2,')=',R1/1e+3:10:6,';'); r:=r+1; writeln(f,'C',c,'(',k+1,',',k+2,')=',C1*1e+9:10:6,';'); c:=c+1; writeln(f,'Q',qq,'(0,',k+1,',0,',k+2,')=k140ud12.oulm;'); qq:=qq+1; k:=k+2; end; if sections[i].shem=MOS then with sections[i] do begin writeln(f,'R',r,'(',k ,',',k+1,')=',R1/1e+3:10:6,';'); r:=r+1; writeln(f,'R',r,'(',k+1,',',k+3,')=',R2/1e+3:10:6,';'); r:=r+1; writeln(f,'R',r,'(',k+1,',',k+2,')=',R3/1e+3:10:6,';'); r:=r+1; writeln(f,'C',c,'(',k+2,',',k+3,')=',C1*1e+9:10:6,';'); c:=c+1; writeln(f,'C',c,'(',k+1,',', 0,')=',C2*1e+9:10:6,';'); c:=c+1; writeln(f,'Q',qq,'(0,',k+2,',0,',k+3,')=k140ud12.oulm;'); qq:=qq+1; k:=k+3; end; if sections[i].shem=bikvadrat then with sections[i] do begin writeln(f,'R',r,'(',k ,',',k+1,')=',R1/1e+3:10:6,';'); r:=r+1; writeln(f,'R',r,'(',k+1,',',k+4,')=',R2/1e+3:10:6,';'); r:=r+1; writeln(f,'R',r,'(',k+1,',',k+2,')=',R3/1e+3:10:6,';'); r:=r+1; writeln(f,'R',r,'(',k+2,',',k+3,')=',R4/1e+3:10:6,';'); r:=r+1; writeln(f,'R',r,'(',k+3,',',k+6,')=',R4/1e+3:10:6,';'); r:=r+1; writeln(f,'R',r,'(',k+4,',',k+5,')=',R4/1e+3:10:6,';'); r:=r+1; writeln(f,'C',c,'(',k+1,',',k+4,')=',C1*1e+9:10:6,';'); c:=c+1; writeln(f,'C',c,'(',k+5,',',k+6,')=',C1*1e+9:10:6,';'); c:=c+1; writeln(f,'Q',qq,'(0,',k+1,',0,',k+4,')=k140ud12.oulm;'); qq:=qq+1; writeln(f,'Q',qq,'(0,',k+5,',0,',k+6,')=k140ud12.oulm;'); qq:=qq+1; writeln(f,'Q',qq,'(0,',k+3,',0,',k+2,')=k140ud12.oulm;'); qq:=qq+1; k:=k+6; end; end; writeln(f,'Gn(',k,',0)=0; '); writeln(f,'& '); writeln(f,'TASK; '); writeln(f,'DC; '); writeln(f,'AC; '); writeln(f,'TF K1=V',k,'/UEin;'); writeln(f,'CONST LFREQ=',low_freq /1.0e+6:10:6,';'); writeln(f,'CONST UFREQ=',high_freq/1.0e+6:10:6,';'); writeln(f,'LPLOT DB.K1,PH.K1;'); writeln(f,'& '); writeln(f,'END; '); Close(f); end; Procedure LowPassFilter_Plot; var Dr: Integer; Mode: Integer; i:integer; A,max,scale:double; st:string; begin Dr := VGA; Mode:=2; InitGraph(Dr,Mode,'c:\bp\bgi'); SetGraphMode(2); max:=AFC[1]; for i:=1 to POINTS do if Abs(AFC[i])>max then max:=Abs(AFC[i]); max:=(Round(max) div 10 + 1 )*10; scale:=400/(max+5); SetColor(LIGHTGRAY); Rectangle(100,20,100+POINTS,420); A:=0; while A<=max do begin Line(100,20+Round((A+5)*scale),100+POINTS,20+Round((A+5)*scale)); Str(-Round(A):4,st); OutTextXY(60,10+Round((A+5)*scale),st); A:=A+10; end; SetColor(WHITE); OutTextXY(60,10,'K, дБ'); A:=0; SetColor(LIGHTGRAY); while A<=high_freq do begin i:= Round(POINTS*A/high_freq); Line(100+i,20,100+i,420); Str(Round(A):4,st); OutTextXY(80+i,430,st); A:=A+2*pow10(Trunc(Lg(high_freq/2))); end; SetColor(WHITE); OutTextXY(130+POINTS,430,'f, Гц'); SetColor(LIGHTGREEN); for i:=1 to POINTS-1 do Line(100+i,20+Round(scale*(5-AFC[i])),101+i,20+Round(scale*(5-AFC[i+1]))); OutTextXY(100,460,'Press any key to exit'); readkey; CloseGraph; end; Begin ClrScr; TextColor(LIGHTGREEN); GoToXY(20, 9); writeln('---------------------------------------------'); GoToXY(20,10); writeln('Программа расчета ARC - фильтра нижних частот'); GoToXY(20,11); writeln(' с аппроксимацмей АЧХ по Баттерворту '); GoToXY(20,12); writeln('---------------------------------------------'); GoToXY(20,17); writeln(' X.X. XXXXX '); GoToXY(20,18); writeln(' студент гр. ДА-XX'); GoToXY(20,19); writeln(' ФЭЛ НТУУ "КПИ" '); GoToXY(20,24); writeln(' Киев 2000 '); TextColor(LIGHTCYAN+BLINK); GoToXY(20, 1); write(' Нажмите Enter '); ch:=#255; while ch<>#13 do ch:=Readkey; TextColor(LIGHTGREEN); LowPassFilter_Parameters; LowPassFilter_Norming; LowPassFilter_Batterworth_Order; LowPassFilter_Batterworth_H; LowPassFilter_Batterworth_Sigma0; LowPassFilter_Batterworth_Poles; LowPassFilter_Building; LowPassFilter_Denorming; LowPassFilter_Info; LowPassFilter_AFC; LowPassFilter_ALLTED; LowPassFilter_Plot; End. |