VYSOKÁ ŠKOLA POLYTECHNICKÁ JIHLAVA Katedra elektrotechniky a informatiky
Program pro výpočet přenosů v numerickém tvaru bakalářská práce
Autor: Pavel Jiránek Vedoucí práce: Ing. Bohumil Brtník, Ph.D. Jihlava 2011
ABSTRAKT Bakalářská práce se zabývá vytvořením programu pro frekvenční analýzu lineárního obvodu numerickým algoritmem. Tato aplikace je konzolová a při vkládání komunikuje interaktivně, tj. dialogovým způsobem: otázka- odpověď výběrem z nabídky. Výstupem programu je tabulka s výsledky frekvenční analýzy. U tohoto algoritmu je výstup pouze v numerické podobě. Program je napsán v programovacím jazyce C++ ve vývojovém prostředí DEV- C++.
Klíčová slova Numerický, algoritmus, frekvenční, analýza, C++
ABSTRACT The Bachelor thesis deals with creation program for a frequency analysis of a linear circuit by a numerical algorithm. This is console application and communicates interactively when data are inserted – it means the application communicates by the dialogue way: a question – a answer is chosen from proposal. The result of the program is a table with results of frequency analysis. The result of this algorithm is only in a numeric form. The program is written in the programming language called C++ in the development environment DEVC++.
KEYWORDS Numerical, algorithm, frequency, analysis, C++
PODĚKOVÁNÍ Rád bych tímto poděkoval vedoucímu bakalářské práce, Ing. Bohumilu Brtníkovi, Dr., za cenné rady a připomínky, kterých se mi při psaní této práce dostalo.
PROHLÁŠENÍ Prohlašuji, že předložená bakalářská práce je původní a zpracoval/a jsem ji samostatně. Prohlašuji, že citace použitých pramenů je úplná, že jsem v práci neporušil/a autorská práva (ve smyslu zákona č. 121/2000 Sb., o právu autorském, o právech souvisejících s právem autorským a o změně některých zákonů, v platném znění, dále též „AZ“). Souhlasím s umístěním bakalářské práce v knihovně VŠPJ a s jejím užitím k výuce nebo k vlastní vnitřní potřebě VŠPJ . Byl/a jsem seznámen/a s tím, že na mou bakalářskou práci se plně vztahuje AZ, zejména § 60 (školní dílo). Beru na vědomí, že VŠPJ má právo na uzavření licenční smlouvy o užití mé bakalářské práce a prohlašuji, že s o u h l a s í m s případným užitím mé bakalářské práce (prodej, zapůjčení apod.). Jsem si vědom/a toho, že užít své bakalářské práce či poskytnout licenci k jejímu využití mohu jen se souhlasem VŠPJ, která má právo ode mne požadovat přiměřený příspěvek na úhradu nákladů, vynaložených vysokou školou na vytvoření díla (až do jejich skutečné výše), z výdělku dosaženého v souvislosti s užitím díla či poskytnutím licence. V Jihlavě dne 1.6.2011 ...................................................... Podpis
Obsah 1
Úvod................................................................................................................................ 7
2
Rozbor zadání a cílů ....................................................................................................... 9
3
Popis výpočtu ................................................................................................................ 10 3.1
3.1.1
Princip metody ................................................................................................ 10
3.1.2
Úprava metody ................................................................................................ 11
3.2 4
C++......................................................................................................................... 15
4.1.1
Informace o jazyku C++ ................................................................................. 15
4.1.2
Proč C++ ......................................................................................................... 15
4.2
Můj program........................................................................................................... 16
4.2.1
Zadání počtu uzlů............................................................................................ 16
4.2.2
Zadávání prvků a jejich hodnot ...................................................................... 17
4.2.3
Zápis prvků do matic ...................................................................................... 28
4.2.4
Hlavní výpočet ................................................................................................ 33
4.2.5
Ukázka spuštěného programu ......................................................................... 39
Testování programu ...................................................................................................... 42 5.1
Výpočet konkrétního příkladu................................................................................ 42
5.1.1
Můj program ................................................................................................... 42
5.1.2
Program SNAP ............................................................................................... 44
5.2 6
Redukce rozměru matice ........................................................................................ 12
Popis programu ............................................................................................................. 15 4.1
5
Zobecněná metoda uzlových napětí ....................................................................... 10
Porovnání výsledků ................................................................................................ 45
Závěr ............................................................................................................................. 47 6.1
Zhodnocení práce ................................................................................................... 47
6.2
Možnosti dalšího rozšíření aplikace ....................................................................... 47
7
Seznam použité literatury ............................................................................................. 48
8
Seznam citací ................................................................................................................ 49
1 Úvod Při rozhodování jaké téma bakalářské práce si zvolím, jsem měl na výběr naprogramovat nějakou aplikaci, nebo postavit elektronický přípravek. Programování a elektronikou se zabývám již od střední školy a tak jsem hledal téma, které by spojovalo obě oblasti. Nakonec po dlouhém váhání jsem zvolil první variantu a vybral si téma od pana inženýra Brtníka, napsat program pro frekvenční analýzu lineárního obvodu jednoduchou metodou. Program by měl umět počítat se součástkami jako jsou rezistor, kapacita, cívka, tranzistor, trioda, operační zesilovač (ideální i reálný), transimpedanční zesilovač, konvejor, ... Vlastní aplikace bude konzolová a při vkládání dat reprezentujících obvodové prvky a mezní kmitočty pro analýzu bude komunikovat interaktivně, tj. dialogovým způsobem : otázka-odpověď výběrem z nabídky, což snižuje možnost chybného zadání vstupních dat. Výstupem aplikace bude tabulka s výsledky frekvenční analýzy. U tohoto algoritmu je výstup pouze v numerické podobě, na rozdíl například od symbolického, nebo semisymbolického algoritmu, kde jsou výsledky uvedené jako rovnice. Ty se mohou vyplnit konkrétními hodnotami a dovedou nás také k numerickým výsledkům. V přípravě k samotnému psaní programu bylo zapotřebí spočítat si několik příkladů na papír a pochopit celou metodu výpočtu. Ta vychází ze zobecněné metody uzlových napětí, kterou jsme probírali v předmětu Elektrické obvody 1, tudíž mám v této problematice již částečný přehled. Díky této metodě dostaneme matici n x n prvků. Tu následně postupně zredukujeme Gaussovou eliminační metodou na rozměr 2 x 2, díky čemuž počítáme determinant maximálně druhého řádu a algoritmus je tak jednodušší. Pro naprogramování aplikace jsem si vybral programovací jazyk C++, se kterým jsem se seznámil v předmětech Programování 2, Programování 3 a Programování 4 vyučovaných na Vysoké škole polytechnické Jihlava a přijde mi pro tuto problematiku nejvhodnější. Co se týče „konkurence“ tak existuje například program SNAP, který umí počítat všechny tři výše uvedené metody. Jeho velká nevýhoda je ta, že je počítá postupně, tzn., že nejdříve z modelu obvodu vypočte symbolický, z tohoto semisymbolický a až z tohoto numerický 7
výsledek. Mnou napsaný program bude počítat přímo numerický výsledek, tím bych měl dosáhnout přesnějšího výsledku.
8
2 Rozbor zadání a cílů Jak již plyne ze zadání, program bude umět provést frekvenční analýzu lineárního obvodu. Tedy po zadání součástek, uzlů a hodnot vypočítat napěťové zesílení (Au), napěťové zesílení v decibelech (AudB) a vstupní impedanci (Zi) v případě, že obvod nemá reaktanční prvky, nebo napěťové zesílení (Au), napěťové zesílení v decibelech (AudB), vstupní impedanci (Zi), fázi, výstupní kapacitu (C) a uvést frekvenci (F), pokud obvod obsahuje aspoň jeden frekvenčně závislý prvek. Frekvenčně závislý prvek je například kondenzátor nebo cívka. Bylo by vhodné zmínit, co to vlastně je lineární obvod. Lineárním obvodem se rozumí takový elektrický obvod, který je složen z lineárních součástek, tedy součástek, jenž mají lineární volt-ampérovou charakteristiku, tzn. že proud jimi procházející je přímo úměrný napětí [1]. Vlastní algoritmus výpočtu vychází ze zobecněné metody uzlových napětí. Výsledná vodivostní matice se tedy získá součtem vodivostních matic jednotlivých obvodových prvků. Tato matice se zredukuje Gaussovou eliminační metodou na rozměr 2 x 2 a vypočítají se dané hodnoty.
9
3 Popis výpočtu 3.1 Zobecněná metoda uzlových napětí 3.1.1 Princip metody Princip metody budu vysvětlovat na jednoduchém příkladu. Máme jednoduchý obvod se třemi rezistory a třemi uzly:
Obrázek 1 schéma obvodu
Červenými čísly jsou označeny jednotlivé uzly. Zde vidíme, že uzel 1. je vstupní a uzel číslo 3. je výstupní. Nyní vytvoříme vodivostní matice všech prvků. Rezistor R1 je zapojen mezi uzel 1 a 2, matice rezistoru R1 tedy bude vypadat následovně:
Obrázek 2 matice R1
Podobně rezistor R2, který je zapojen mezi uzly 2 a 3 bude mít vodivostní matici:
Obrázek 3 matice R2
10
A poslední R3 je zapojen mezi druhý a zemnící uzel, tedy:
Obrázek 4 matice R3
Vodivostní matici celého obvodu dostaneme součtem dílčích matic jednotlivých prvků:
Obrázek 5 součet matic
Obrázek 6 výsledná matice
Napěťové zesílení obvodu je obecně dáno:
. Po dosazení dostaneme:
Napěťový přenos Au se tedy rovná:
3.1.2 Úprava metody Pro potřebu programu je metoda lehce upravena a to tak, že při zadávání se výstupní uzel označí číslem 2. a zem se označí číslem o jednotku větší než je počet uzlů (zem se v běžné 11
praxi označuje jako 0. uzel). Tedy pro příklad uvedený výše vypadá označení uzlů následovně:
Obrázek 7 schéma obvodu 2
Označení výstupního uzlu číslem 2 není náhodné, je to z důvodu redukce výsledné vodivostní matice na rozměr 2x2, která bude popsána později. Označení země číslem 4 (v tomto případě) je z čistě programového důvodu. Hodnoty prvků se zadávají mezi uzel 3 a 4, tedy do matice do 3. a 4. řádku respektive sloupku. Čtvrtý řádek se pak vynechává. Tato úprava bude také popsána později.
3.2 Redukce rozměru matice Pro vyčíslení determinantů je tu možnost převést libovolně složitý obvod na jednoduchý dvojbran, u kterého je první uzel vstupní a druhý uzel výstupní.
Obrázek 8 dvojbran
Tento dvojbran můžeme popsat rovnicemi:
Pokud jde o dvojbran nezatížený, tak je I2=0. Rovnice popisující dvojbran budou následující: 12
Z těchto dvou rovnic dostaneme jednu rovnici:
Tím jsme dostali základní vztah pro výpočet přenosu postupnou redukcí uzlů obvodu, které nejsou připojeny ke vnějším částem obvodu. To znamená, že matice je o rozměru 2x2.
Obrázek 9 vnitřní uzel obvodu
Vzhledem k tomu, že se dvojbran ostatních součástek dotýká pouze ve dvou uzlech (1. a 2.), jsou ostatní budící proudy nulové a pokud je dvojbran nezatížený, potom i I2=0. Potom můžeme napsat soustavu rovnic:
Kde matice soustavy vypadá takto:
Obrázek 10 matice soustavy
13
Z poslední rovnice můžeme vyjádřit U3:
U3 pak dosadíme do zbylých dvou rovnic:
Tyto rovnice se popíší maticí soustavy:
Obrázek 11 matice soustavy o řád nižší
Tato matice je již o řád nižší, tím došlo k vyloučení proměnné U3. Obecně můžeme napsat, že pro prvek yij matice nižšího řádu platí:
Obvod s n uzly, který má matici n x n, můžeme opakováním tohoto postupu nahradit dvojbranem. Proto již při sestavování obvodu očíslujeme obvodové uzly tak, aby vstupní uzel měl označení 1., výstupní 2. a vnitřní uzly měly poslední čísla.[3]
14
4 Popis programu 4.1
C++
4.1.1 Informace o jazyku C++ Jedná se o objektově orientovaný programovací jazyk vyvinutý Bjarnem Stroustupem v Bellových laboratořích AT&A rozšířením jazyka C. C++ podporuje několik programovacích stylů: Procedurální programování Objektově orientované programování Generické programování Nejedná se tedy o jazyk čistě objektový. Od roku 1980 byl pro tento jazyk používán název „C with Classes“ což v překladu znamená „C s třídami“. Název C++, který vymyslel Rick Mascitti, se používá od léta roku 1983. Dva plusy (což je operátor inkrementace) zdůrazňují evoluční povahu změn oproti jazyku C. Ač se jazyk vyvíjel již od počátku 80. let, tak první oficiální norma C++ byla přijata v roce 1998, další v roce 2003 (INCITS/ISO/IEC 14882-2003). V roce 2006 a 2007 byly přijaty některé aktualizace [2].
4.1.2 Proč C++ Programovací jazyk C++ jsem si vybral z toho důvodu, že s ním pracuji již několik let a vyhovuje mi. Prvně jsem se s ním seznámil již na střední škole, kde jsme dělali jen velmi jednoduché programy. Znalosti jsem si prohloubil na Vysoké škole polytechnické Jihlava na předmětech Programování 2, Programování 3, Programování 4, Ovládání zařízení pomocí PC a Numerické metody. 15
4.2 Můj program 4.2.1 Zadávání počtu uzlů Zadávání počtu uzlů je řešeno samostatnou funkcí nazvanou zadavani_uzlu(), která je volána z hlavního programu. V této funkci je uživatel vyzván k zadání počtu uzlů obvodu. Zde je třeba nezapomenout na drobné rozdíly od „klasické“ zobecněné metody uzlových napětí a to ty, že je nutné označit zemnící uzel o jednotku větším číslem než je počtu uzlů (obvykle se tento uzel označuje číslicí 0) a výstupní uzel číslem 2. Tyto rozdíly byly popsány na straně 11 v kapitole 3.1.2.
int zadavani_uzlu() { system("cls"); //příkaz pro vyčištění obrazovky cout<<endl<< "\tZadavani poctu uzlu"<<endl; cout<<"___________________________________________"<<endl<<endl; cout<< "Maximalni pocet uzlu je 15"<< endl; cout<< "Zadejte pocet uzlu: "; uzly = kontr_int(); //zadávání hodnot je řešeno samostatnou funkcí //z důvodu ošetření vstupů, bude vysvětlena níže cout << endl; if(uzly >= 2 && uzly <= 15) //podmínka pro porovnání hodnoty v proměnné { //uzly return uzly; //pokud je podmínka splněna, vrátí se počet uzlů }else { zadavani_uzlu(); //pokud podmínka splněna není, volá se funkce } //znovu }
Funkce pro zadání počtu uzlů nám tedy vrátí počet uzlů v obvodu, který se následně vypíše na obrazovku. Zároveň se volá funkce pro zadávání prvků.
16
//volání funkce pro zadání počtu uzlů v obvodu. Ten je //tedy uložen v proměnné uzly system("cls"); //příkaz pro vyčištění obrazovky cout<<endl<<"\tZadavani.prvku"<<endl; cout<<"_________________________________________________"<<endl<<endl; cout<<"Pocet uzlu: "<
"<"<
4.2.2 Zadávání prvků a jejich hodnot Pro zadávání prvků je zde několik funkcí. První je zadavani_prvku(), která dle zadaného prvku vybere příslušnou funkci pro zadání uzlů a hodnot. Toto rozdělování je řešené obyčejným „switchem“. Ten vybere další funkci podle číselného kódu zadané součástky. void zadavani_prvku(){ int prvek_zadavani; cout<<"Zadejte kod prvku:\n 1=R, 2=G, 3=L, 4=C, 5=TRI, 6=TRH, 7=TRY, 8=ZPN, 9=IOZ, 10=ROZ, 11=KON, 12=TIZ " <<endl; prvek_zadavani = kontr_int(); //zadávání hodnot je řešeno samostatnou funkcí //z důvodu ošetření vstupů, bude vysvětlena níže switch(prvek_zadavani) //switch vybírá funkci dle zadané součástky { case 1: //resistivni prvky-rezistor resistivni_prvky_a_ZPN(prvek_zadavani); break; case 2: //resistivni prvky-vodivost resistivni_prvky_a_ZPN(prvek_zadavani); break; case 3: //reaktivni prvky prvky-cívka reaktivni_prvky(prvek_zadavani); break; case 4: //reaktivni prvky prvky-kondenzátor reaktivni_prvky(prvek_zadavani); break; 17
case 5: //trioda if(uzly>=3) //pokud obvod má aspoň tři uzly, přejde se dále TRY_TRH_TRI(prvek_zadavani); else //pokud nemá obvod aspoň 3 uzly, tak ji nelze zadat { cout << "TRI lze vlozit do obvodu, ktery ma nejmene 3 uzly!!!"; cout<<endl; zadavani_prvku(); } break; case 6: //tranzistor zadávaný h-parametry if(uzly>=3) // pokud obvod má aspoň tři uzly, přejde se dále TRY_TRH_TRI(prvek_zadavani); else //pokud nemá obvod aspoň 3 uzly, tak ho nelze zadat { cout << "TRH lze vlozit do obvodu, ktery ma nejmene 3 uzly!!!"; cout<<endl; zadavani_prvku(); } break; case 7: //tranzistor zadávaný y-parametry if(uzly>=3) // pokud obvod má aspoň tři uzly, přejde se dále TRY_TRH_TRI(prvek_zadavani); else //pokud nemá obvod aspoň 3 uzly, tak ho nelze zadat { cout << "TRY lze vlozit do obvodu, ktery ma nejmene 3 uzly!!!"; cout<<endl; zadavani_prvku(); } break; case 8: //zdroj proudu řízený napětím if(uzly>=4) //pokud obvod má aspoň čtyři uzly, přejde se dále resistivni_prvky_a_ZPN(prvek_zadavani); else // pokud nemá obvod aspoň 4 uzly, tak ho nelze zadat { cout << "ZPN lze vlozit do obvodu, ktery ma nejmene 4 uzly!!!"; cout<<endl; zadavani_prvku(); } break; 18
case 9: //ideální operační zesilovač if(uzly>=3) // pokud obvod má aspoň tři uzly, přejde se dále resistivni_prvky_a_ZPN(prvek_zadavani); else // pokud nemá obvod aspoň 3 uzly, tak ho nelze zadat { cout << "idealni OZ lze vlozit do obvodu, ktery ma nejmene 3 uzly!!!"; cout<<endl; zadavani_prvku(); } break; case 10: //reálný operační zesilovač if(uzly>=3) // pokud obvod má aspoň tři uzly, přejde se dále zadat resistivni_prvky_a_ZPN(prvek_zadavani); else // pokud nemá obvod aspoň 3 uzly, tak ho nelze zadat { cout << "realny OZ lze vlozit do obvodu, ktery ma nejmene 3 uzly!!!"; cout<<endl; zadavani_prvku(); } break; case 11: //konvejor if(uzly>=3) // pokud obvod má aspoň tři uzly, přejde se dále zadat resistivni_prvky_a_ZPN(prvek_zadavani); else // pokud nemá obvod aspoň 3 uzly, tak ho nelze zadat { cout << "konvejor lze vlozit do obvodu, ktery ma nejmene 3 uzly!!!"; cout<<endl; zadavani_prvku(); } break; case 12: //transimpedanční zesilovač if(uzly>=4) // pokud obvod má aspoň čtyři uzly, přejde se dále zadat resistivni_prvky_a_ZPN(prvek_zadavani); else // pokud nemá obvod aspoň 4 uzly, tak ho nelze zadat { cout << "transimpedanční zesilovač lze vlozit do obvodu, ktery ma nejmene 4 uzly!!!" <<endl; zadavani_prvku(); } break; 19
Funkce zadavani_prvku() tedy dle zadaného číselného kódu součástky volá příslušnou funkci pro další kroky. Například pro rezistor, vodivost, zdroj proudu řízený napětím, ideální operační zesilovač, reálný operační zesilovač, konvejor a transimpedanční zesilovač, tedy pro rezistivní prvky (bez tranzistorů a triody), volá funkci resistivni_prvky_a_ZPN(int prvek). Tato funkce na začátku zvýší počítadlo rezistivních prvků o jedničku, zavolá funkci pro zadání uzlů a hodnot součástek a pak vypíše kontrolní výpis zadaných prvků. Po kontrolním výpisu zavolá příslušnou funkci pro zápis hodnot do matice W. void resistivni_prvky_a_ZPN(int prvek) { n++; //inkrementace počítadla rezistivních prvků uzly_hodnota(prvek); //volání funkce pro zadání hodnot a uzlů součástek switch(prvek) //dle zadávané součástky se vypíše kontrolní výpis zadaných hodnot { case 1: cout << n+m << ".soucastka R" <<endl; //rezistor cout << "mezi uzly: " << uzel1_1 << ", " << uzel1_2<<endl; cout << "hodnota: "<
20
cout << "G0: "<
Pro tranzistor zadávaný h nebo y-parametry a triodu je zde funkce TRY_TRH_TRI(int_prvek). Tyto tři součástky by mohly být v předešlé funkci, ale z důvodu přehlednosti jsou ve funkci jiné. void TRY_TRH_TRI(int prvek) { n++; //inkrementace počítadla rezistivních prvků uzly_hodnota(prvek); //volání funkce pro zadání hodnot a uzlů součástek Y11=0; //nulování Y prvků Y12=0; Y21=0; Y22=0; if(prvek == 6) //TRH { cout << "Zadejte H parametry: " << endl; //zadávání h parametrů cout << "H11: "; H11 = kontr_float(); //zadání parametru H11 cout << endl; cout << "H12: "; H12 = kontr_float(); //zadání parametru H12 cout << endl; cout << "H21: "; H21 = kontr_float(); //zadání parametru H21 cout << endl; cout << "H22: "; H22 = kontr_float(); //zadání parametru H22 cout << endl; //při zadávání tranzistoru h-parametry se tyto //parametry musí přepočítat na y-parametry prepocet_na_Y_parametry(); // volá se tedy příslušná funkce, která bude } // popsána níže else if(prvek == 7) { //TRY cout << "Zadejte Y parametry: " << endl; cout << "Y11: "; Y11 = kontr_float(); //zadání parametru Y11 cout << endl; cout << "Y12: "; Y12 = kontr_float(); //zadání parametru Y12
22
cout << "Y21: "; Y21 = kontr_float(); cout << "Y22: "; Y22 = kontr_float(); cout << endl;
//zadání parametru Y21 //zadání parametru Y22
} else if(prvek == 5) { //TRI cout << "S= "; s_TRI = kontr_float(); //zadání strmosti triody cout << endl; cout << "Ri= "; ri_TRI = kontr_float(); //zadání vnitřního odporu triody cout << endl; Y22=1/ri_TRI; //přepočty pro zadání do matice Y11=Y12=0; Y21=s_TRI; } switch(prvek) { //kontrolní výpisy zadaných součástek case 5: //TRI cout << n+m << ".soucastka TRI" <<endl; cout << "mezi uzly: " << uzel1 << ", " << uzel2 << ", " << uzel3<<endl; cout << "S= " << s_TRI << "A*V^-1 Ri= " << ri_TRI << "R" << endl; break; case 6: //TRH cout << n+m << ".soucastka TRH" <<endl; cout << "mezi uzly: " << uzel1 << ", " << uzel2 << ", " << uzel3<<endl; cout << "H parametry:" <<endl; cout << " H11: "<< H11 << " H12: " << H12 << endl; cout << " H21: "<< H21 << " H22: " << H22 << endl; break; case 7: //TRY cout << n+m << ".soucastka TRY" <<endl; cout << "mezi uzly: " << uzel1 << ", " << uzel2 << ", " << uzel3<<endl; cout << "Y parametry:" <<endl; cout << " Y11: "<< Y11 << " Y12: " << Y12 << endl; cout << " Y21: "<< Y21 << " Y22: " << Y22 << endl; break; } zapis_do_matice_W_TR(prvek); //volání funkce pro zápis do matice 23
Nakonec funkce volá funkci zapis_do_matice_W_TR(prvek) pro zápis prvku do matice W. Pro cívku a kondenzátor je zavolána funkce reaktivni_prvky(int prvek), která je v principu stejná jako dvě předešlé funkce. void reaktivni_prvky(int prvek) { m++; //inkrementace počítadla reaktivních prvků uzly_hodnota(prvek); //volání funkce pro zadání hodnot a uzlů součástek switch(prvek) { case 3: //cívka cout << n+m << ".soucastka L" <<endl; cout << "mezi uzly: " << uzel1_1 << ", " << uzel1_2<<endl; cout << "hodnota: "<
void uzly_hodnota(int prvek) //zadavani uzlu a hodnot { if(prvek==1 || prvek==2 || prvek==3 || prvek==4) //R,G,L,C { do { cout << "Zadejte prvni uzel: "; uzel1_1 = kontr_int(); //zadání prvního uzlu cout << endl << "Zadejte druhy uzel: "; uzel1_2 = kontr_int(); //zadání druhého uzlu cout << endl; if(uzel1_1 == uzel1_2) cout<<"Nemuzou byt stejne uzly!"<<endl<<endl; if(uzel1_1 > uzly || uzel1_2 > uzly || uzel1_1 <= 0 || uzel1_2 <= 0) cout<<"Byly zadany neexistujici uzly!"<<endl<<endl; }while(uzel1_1 > uzly || uzel1_2 > uzly || uzel1_1 == uzel1_2 || uzel1_1 <= 0 || uzel1_2 <= 0); //ošetření zadaných hodnot do { cout << "Zadejte hodnotu: "; hodnota = kontr_float(); //zadávání hodnot je řešené pomocnou funkcí //kvůli ošetření cout << endl; }while(hodnota <= 0); } else if(prvek==5 || prvek==6 || prvek==7 || prvek==9 || prvek==10 || prvek==11) //TRI, TRH, TRY, IOZ, ROZ, KON { do{ cout << "Zadejte prvni uzel: "; uzel1 = kontr_int(); //zadání prvního uzlu cout << endl; cout << "Zadejte druhy uzel: "; uzel2 = kontr_int(); //zadání druhého uzlu cout << endl; cout << "Zadejte treti uzel: "; uzel3 = kontr_int(); //zadání třetího uzlu cout << endl; if(uzel1 == uzel2 || uzel1 == uzel3 || uzel2 == uzel3) cout<<"Nemuzou byt stejne uzly!"<<endl<<endl; 25
if(uzel1 > uzly || uzel2 > uzly || uzel3 > uzly || uzel1 <= 0 || uzel2 <= 0 || uzel3 <= 0) cout<<"Byly zadany neexistujici uzly!"<<endl<<endl; }while(uzel1 > uzly || uzel2 > uzly || uzel3 > uzly || uzel1 <= 0 || uzel2 <= 0 || uzel3 <= 0 || uzel1 == uzel2 || uzel1 == uzel3 || uzel2 == uzel3); //ošetření zadaných hodnot if(prvek==11) // KON { do { cout << "Zadejte hodnotu: "; hodnota = kontr_float(); //zadání vstupní vodivosti konvejoru cout << endl; }while(hodnota <= 0); } else if (prvek==9) //IOZ { hodnota = 1000000; //ideální operační zesilovač má nekonečně velké hodnota2 = 1000000; //zesílení a nekonečně velký výstupní odpor, } // proto se u něj hodnoty nezadávají a jsou již else if (prvek==10) //nastaveny { //ROZ do { cout << "Zadejte G0: "; hodnota = kontr_float(); //zadání výstupní vodivosti operačního cout << endl; //odřádkování }while(hodnota <= 0); do { cout << "Zadejte A: "; hodnota2 = kontr_float(); //zadání zesílení operačního zesilovače cout << endl; }while(hodnota2 <= 0); } } else if(prvek==8 || prvek==12) //ZPN, TIZ {
26
do{ cout << "Zadejte prvni uzel: "; uzel1_1 = kontr_int(); //zadání prvního uzlu cout << "Zadejte druhy uzel: "; uzel1_2 = kontr_int(); //zadání druhého uzlu cout << endl; cout << "Zadejte treti uzel: "; uzel2_1 = kontr_int(); //zadání třetího uzlu cout << endl; cout << "Zadejte ctvrty uzel: "; uzel2_2 = kontr_int(); //zadání čtvrtého uzlu cout << endl; if(uzel1_1==uzel1_2 && uzel1_1==uzel2_1 && uzel1_1==uzel2_2) cout<<"Nemuzou byt stejne uzly!"<<endl<<endl; if(uzel1_1 > uzly || uzel1_2 > uzly || uzel2_1 > uzly || uzel2_2 > uzly) cout<<"Byly zadany neexistujici uzly!"<<endl<<endl; if(uzel1_1 <= 0 || uzel1_2 <= 0 || uzel2_1 <= 0 || uzel2_2 <= 0) cout<<"Byly zadany neexistujici uzly!"<<endl<<endl; }while(uzel1_1 > uzly || uzel1_2 > uzly || uzel2_1 > uzly || uzel2_2 > uzly || uzel1_1 <= 0 || uzel1_2 <= 0 || uzel2_1 <= 0 || uzel2_2 <= 0 || (uzel1_1==uzel1_2 && uzel1_1==uzel2_1 && uzel1_1==uzel2_2)); //ošetření zadaných hodnot if(prvek==8){ //ZPN do{ cout << "Zadejte hodnotu: "; hodnota = kontr_float(); //zadání strmosti ZPN cout << endl; }while(hodnota <= 0); } else if (prvek==12){ //TIZ do{ cout << "Zadejte GI: "; hodnota = kontr_float(); //zadání vstupní impedance cout << endl; }while(hodnota <= 0); do{ cout << "Zadejte G0: "; hodnota2 = kontr_float(); //zadání výstupní impedance cout << endl; }while(hodnota2 <= 0); }}} 27
U tranzistorů, které jsou zadány h-parametry se tyto parametry musí přepočítat na yparametry. K tomu slouží funkce prepocet_na_Y_parametry(), která se volá ve funkci TRY_TRH_TRI(int prvek). void prepocet_na_Y_parametry() { Y11=1/H11; Y12=-(H12/H11); Y21=H21/H11; Y22=H22-(H12*(H21/H11)); } Každé zadávání hodnot, ať už se jedná o zadávání čísel uzlů, nebo hodnot součástek, je ošetřeno proti zadání písmen nebo znaků. Toto ošetření zajišťují funkce kontr_float() pro proměnné typu float a kontr_int() pro proměnné typu int. float kontr_float() { float a; cin >> a; while(cin.fail()) { cin.clear(); cin.ignore(); cin >> a; } return a; }
//zadání hodnoty //podmínka se provádí dokud je na vstupu nějaká chyba //vymazání vstupu //ignorování vstupu //nové zadání hodnoty //funkce vrací zadanou hodnotu
Funkce kontr_int() je téměř stejná jako výše uvedená funkce kontr_float() jen s tím rozdílem, že proměnná a je typu int a ne typu float.
4.2.3 Zápis prvků do matic Abychom se mohli dopracovat k výsledku je zapotřebí zadávané prvky ukládat do matic. Matice jsou zde dvě. Matice W pro rezistivní prvky a matice V pro prvky reaktanční. Do těchto matic se zapisuje vždy v jedné z šesti níže uvedených funkcí. Na konci každé této 28
funkce se zavolá funkce dotaz(), která se nás zeptá, zda chceme pokračovat v zadávání dalších součástek. Bude popsána později. Pro zapsání hodnot do matice W u prvků R, G a ZPN je vytvořena funkce zapis_do_matice_R_G_ZPN(): void zapis_do_matice_R_G_ZPN() //zápis prvků R, G, ZPN { W[uzel2_1][uzel1_1] = W[uzel2_1][uzel1_1] + hodnota; //uložení hodnoty W[uzel2_1][uzel1_2] = W[uzel2_1][uzel1_2] - hodnota; W[uzel2_2][uzel1_1] = W[uzel2_2][uzel1_1] - hodnota; W[uzel2_2][uzel1_2] = W[uzel2_2][uzel1_2] + hodnota; dotaz(); //volání funkce dotaz() } Tato funkce tedy uloží zadanou hodnotu součástky mezi zvolené uzly. Na následujících obrázcích je vidět rozložení vývodů.
Obrázek 12 rezistor/ vodivost
U rezistoru (vodivosti) nezáleží na pořadí zadávaných uzlů. Zde jen platí, že uzel2_1=uzel1_1 a uzel2_2=uzel1_2.
Obrázek 13 ZPN
U prvku ZPN již na pořadí zadávaných prvků záleží: uzel1_1 odpovídá vstupu A, uzel1_2 B, uzel2_1 výstupu C a uzel2_2 D. Funkce zapis_do_matice_W_TR(int prvek) zajišťuje uložení hodnot pro součástky TRH, TRY a TRI do matice W, vypadá následovně:
29
void zapis_do_matice_W_TR(int prvek) { if(prvek == 6 || prvek == 7)//pokračuj, pokud je ukládaný prvek TRH nebo TRY { W[uzel1][uzel1] = W[uzel1][uzel1] + Y11; //uložení hodnoty W[uzel1][uzel2] = W[uzel1][uzel2] + Y12; W[uzel1][uzel3] = W[uzel1][uzel3] - Y11 - Y12; } W[uzel3][uzel3] = W[uzel3][uzel3] + Y11 + Y12 + Y21 + Y22; //uložení hodnoty W[uzel2][uzel1] = W[uzel2][uzel1] - Y21 - Y22; W[uzel2][uzel3] = W[uzel2][uzel3] + Y21; W[uzel2][uzel2] = W[uzel2][uzel2] + Y22; W[uzel3][uzel1] = W[uzel3][uzel1] - Y11 - Y21; W[uzel3][uzel2] = W[uzel3][uzel2] - Y12 - Y22; dotaz();
//volání funkce dotaz()
} Na začátku této funkce vidíme podmínku. Ta je zde z toho důvodu, že tranzistor se zadává trochu jinak než trioda. Pro triodu se tedy podmínka neprovede. Proměnná uzel1 odpovídá bázi, uzel2 kolektoru a uzel3 emitoru. Proměnná Y11 odpovídá parametru y11, Y12 parametru y12, atd. Pro vývody tranzistoru platí: uzel1 = B, uzel2 = C, uzel3 = D.
Obrázek 14 tranzistor
Zadané hodnoty pro operační zesilovač se vkládají do matice funkcí zapis_do_matice_ROZ(). Tato funkce je stejná jak pro ideální, tak pro reálný operační zesilovač. Rozdíl je v zadávaných hodnotách. U ideálního OZ jsou hodnoty již přednastaveny.
30
void zapis_do_matice_ROZ() { W[uzel3][uzel1] = W[uzel3][uzel1] + (hodnota * hodnota2); W[uzel3][uzel2] = W[uzel3][uzel2] - (hodnota * hodnota2); W[uzel3][uzel3] = W[uzel3][uzel3] + hodnota; dotaz();
//uložení hodnoty
//volání funkce dotaz()
} Proměnná hodnota odpovídá výstupní vodivosti G0 a hodnota2 zesílení Au operačního zesilovače.
Obrázek 15 operační zesilovač
Hodnoty prvku konvejor se do matice W ukládají funkcí zapis_do_matice_KON(): void zapis_do_matice_KON() { W[uzel1][uzel1] = W[uzel1][uzel1] - hodnota; W[uzel3][uzel1] = W[uzel3][uzel1] - hodnota; W[uzel1][uzel2] = W[uzel1][uzel2] + hodnota; W[uzel3][uzel2] = W[uzel3][uzel2] + hodnota; dotaz(); //volání funkce dotaz() }
//uložení hodnoty //hodnota = vstupní //vodivost
Zde proměnná uzel1 odpovídá B, uzel2 C a uzel3 D.
Obrázek 16 konvejor
Předposlední funkce pro ukládání zadaných hodnot transimpedančního zesilovače má název zapis_do_matice_TIZ():
31
void zapis_do_matice_TIZ() { W[uzel1_1][uzel1_1] = W[uzel1_1][uzel1_1] - hodnota; W[uzel2_1][uzel1_1] = W[uzel2_1][uzel1_1] - hodnota; W[uzel1_1][uzel1_2] = W[uzel1_1][uzel1_2] + hodnota; W[uzel2_1][uzel1_2] = W[uzel2_1][uzel1_2] + hodnota; W[uzel2_2][uzel2_1] = W[uzel2_2][uzel2_1] + hodnota2; W[uzel2_2][uzel2_2] = W[uzel2_2][uzel2_2] - hodnota2; dotaz(); //volání funkce dotaz() }
//uložení hodnoty
U prvku TIZ platí to, co u ZPN: uzel1_1 = A, uzel1_2 = B, uzel2_1 = C a uzel2_2 = D. Dále proměnná hodnota = vstupní impedance a hodnota2 = výstupní impedance.
Obrázek 17 transimpedanční zesilovač
Poslední z těchto šesti funkcí je funkce zapis_do_matice_L_C(int prvek). Jak již název napovídá, slouží pro ukládání hodnot prvků do pole H[] a čísel uzlů do pole G[][]. void zapis_do_matice_L_C(int prvek) { if(prvek==3)uzel1_1=-uzel1_1; //záporná hodnota přiřazená B označuje //induktivní reaktanci H[m] = hodnota; //uložení hodnoty prvku do pole H[] G[m][1] = uzel1_1; //uložení prvního uzlu G[m][2] = uzel1_2; //uložení druhého uzlu dotaz(); //volání funkce dotaz() } Pro pořádek zde uvádím i schematickou značku (s rozložením vývodů) jednoho z reaktančních prvků, kondenzátoru. U cívky ani u kondenzátoru nezáleží na pořadí zadávaných uzlů.
32
Obrázek 18 kondenzátor
Jak již jsem zmínil výše, každá z těchto výše popsaných funkcí nakonec volá funkci dotaz(). Jedná se o jednoduchou funkci, která se nás jen zeptá, zda chceme zadat další součástku. Pokud zadáme volbu „y“ budeme pokračovat v zadávání. Při zvolení volby „n“ vkládání součástek končí a program přejde k vlastnímu výpočtu.
4.2.4 Hlavní výpočet Z důvodu větší přehlednosti je hlavní výpočet rozdělen do dvou funkcí. První je hlavni_vypocet() a druhá gausselim(). void hlavni_vypocet() { float fNula=0, fMin=0, fMax=0, fDelta=0; //deklarace a definice proměnných float omega, pom; //deklarace proměnných float p, q, r, s, v, w, x, cko, au, au_log, kapacita, faze; int uz1, uz2; int n, z; if(m>0) //pokud obvod nemá reaktanční prvky, přeskočí to { cout<<"Zadejte fmin: "; fMin = kontr_float(); //zadávání minimální hodnoty frekvence fNula = fMin; cout<<"Zadejte fmax: "; fMax = kontr_float(); //zadávání maximální hodnoty frekvence cout<<"Zadejte delta f: "; fDelta = kontr_float(); //zadávání delta frekvence cout <<endl<< "F0:\tAu:\t20log(Au):\tZin:\tCin:\tfaze:\t"<<endl; } //tisk hlavičky tabulky výsledků Ve funkci hlavni_vypocet() hned po deklaraci potřebných proměnných následuje podmínka, která se provede pouze v případě, že zadaný obvod obsahuje jeden a více reaktančních prvků (kondenzátor, cívka). V této podmínce se zadávají hodnoty minimálního kmitočtu, maximálního kmitočtu a delta f. Delta f určuje hodnotu kmitočtu, po které se provádí výpočet. Například při fMin = 1, fMax = 10 a fDelta = 1 se výpočet provede pro kmitočty 33
1Hz, 2Hz,…10Hz. Na konci této podmínky je tisk hlavičky tabulky výsledných hodnot. V případě přítomnosti reaktivních prvků v obvodu se tedy vypočítá napěťové zesílení (Au), vstupní impedance (Zin), vstupní kapacita (Cin) a fáze (faze). do{ //počátek vyklu Do-While omega = 6.2831853072 * fNula; //omega = 2*π*fNula for(int i=1;i0) //pokud obvod nemá reaktanční prvky, přeskočí to { for(int i=1;i<=m;i++) //cyklus od 1 do počtu reaktančních prvků { pom = H[i]*omega; //výpočet hodnoty reaktančního prvku uz1 = G[i][1]; //první uzel uz2 = G[i][2]; //druhý uzel if(uz1 < 0) //pokud je uz1 záporné { pom = -(1/pom); //výpočet vodivosti induktoru pom = 1/omega*L uz1 = abs(uz1); //abs - vrátí absolutní hodnotu proměnné uz1 } V[uz1][uz1] = V[uz1][uz1] + pom; //plnění matice V reaktančními V[uz1][uz2] = V[uz1][uz2] - pom; //prvky V[uz2][uz1] = V[uz2][uz1] - pom; V[uz2][uz2] = V[uz2][uz2] + pom; } }
34
Výše popsaná podmínka je opět pouze pro případ, že obvod obsahuje nějaký reaktanční prvek. Zde se tedy vynásobí hodnota v poli H[] proměnnou omega, dále se do proměnných uz1 a uz2 uloží čísla uzlů. Pokud je uz1 se záporným znaménkem, tak se jedná o cívku, neboť zápornou hodnotou se označuje již při vkládání. Vypočítá se tedy vodivost induktoru. Pro ni platí vztah:
Záporné znaménko se z proměnné uz1 odstraní funkcí abs(), která vrátí absolutní hodnotu čísla. Nakonec se hodnoty uloží do matice V. Rozmístění hodnot v matici je stejné jako u rezistoru, resp. vodivosti. gausselim(); //volání funkce pro redukci matic p=U[2][1]; q=U[2][2]; r=V[2][1]; s=V[2][2]; w=-(p*q)-(r*s); x=(p*s)-(q*r); au=(sqrt(w*w+x*x))/(q*q+s*s); //výpočet zesílení au_log = 0; au_log = 20*(log10(au)); //výpočet zesílení v dB faze = 57.2957795128*(atan(x/w)); //výpočet fázového posuvu if(w<0) //podmínka pro určení, zda je fázový { //posuv kladný nebo záporný if(x<0) { faze = faze - 180; }else if(x>=0) { faze = faze + 180; } } kapacita = V[1][1]/omega; //výpočet vstupní kapacity r=0; r = 1 / (U[1][1] + 1e-38); //výpočet vstupní impedance r = fabs(r); //vrátí absolutní hodnotu r
35
Na začátku této části funkce se volá funkce gausselim(), která zredukuje matice U a V na rozměr 2x2. Z takto zredukovaných matic se již vypočítá zesílení dle vztahu:
Dále se také vypočte zesílení v dB:
fázový posuv:
vstupní kapacita:
a vstupní impedance:
if(m>0) { //pokud obvod má reaktanční prvky, provede výpis vypočtených hodnot printf("%.0f\t%.4f\t%.4f\t%.4f\t%.4f\t%.4f\t\n", fNula, au , au_log, r, kapacita, faze); } else //pokud obvod nemá reaktanční prvky, provede tuto podmínku { cout << "_____________________"<<endl; cout << "Au = "<< au <<endl; //výpis vypočtené hodnoty zesílení cout << "Au(dB) = "<< au_log <<endl; // výpis vypočtené hodnoty zesílení v dB cout << "Z = "<< r <<endl<<endl; //výpis vypočtené hodnoty vstupní } // impedance 36
fNula = fNula + fDelta;
//výpočet další hodnoty kmitočtu
}while((fNula-0.01*fNula) <= fMax); cout<<endl<<endl; }
//kontrola, zda aktuální kmitočet stále //náleží do intervalu
V poslední části funkce hlavni_vypocet() se provede již jen výpis, který je rozdílný pro obvod s reaktančními prvky a pro obvod bez reaktančních prvků, dále se vypočte další hodnota kmitočtu a překontroluje se, zda tato hodnota stále patří do zadaného intervalu . Jestliže patří, výpočet se opakuje s touto novou hodnotou. Pokud nepatří, výpočet se ukončí a čeká se na ukončení programu. Zbývá ještě popsat tu nejzajímavější část programu. Tou je bez pochyby funkce gausselim(). Tato funkce nám zajistí zredukování teoreticky libovolně veliké čtvercové matice na rozměr 2x2. Princip redukce již byl vysvětlen v kapitole 3.2. float gausselim() { float p=0, q=0, r=0, s=0, v=0, w=0, x=0; //deklarace a definice proměnných int b=0, c=0, N=uzly; //deklarace a definice proměnných for(int a=N-1;a>=2;a--) //hlavní cyklus funkce, od počtu uzlů-1 do 2 { b=0; p=fabs(U[a][a]) + fabs(V[a][a]); //do p se uloží prvek v hlavní diagonále for(int i=a; i>=3; i--) //dva cykly pro procházení obou matic { //cykly postupují od prvku vpravo dole for(int j=a; j>=3; j--) { q=fabs(U[i][j]) + fabs(V[i][j]); //do q se uloží prvek z matic if(p
dalšího prvku matic. Pokud je tato hodnota větší než prvek v hlavní diagonále, dojde k prohození řádků a sloupků. Toto prohazování vypadá následovně: if(b!=0) //pokud je b nenulové, dojde k provedení podmínky { for(int i=1; i<=a; i++) //záměna řádků { p=U[b][i]; //do p si uložíme hodnotu z jednoho řádku q=V[b][i]; U[b][i]=U[a][i]; //na jeho místo uložíme hodnotu z dalšího řádku V[b][i]=V[a][i]; U[a][i]=p; //do druhého řádku uložíme hodnotu z prvního řádku V[a][i]=q; } for(int i=1; i<=a; i++) //záměna sloupců { p=U[i][c]; //do p si uložíme hodnotu z jednoho sloupku q=V[i][c]; U[i][c]=U[i][a]; //na jeho místo uložíme hodnotu z dalšího sloupku V[i][c]=V[i][a]; U[i][a]=p; //do druhého řádku uložíme hodnotu z prvního sloupku V[i][a]=q; } } p=U[a][a]; q=V[a][a]; r=p*p + q*q; //výpočet prvku z hlavní diagonály for(int i=1; i<=a-1; i++) //cyklus prochází maticemi U a V { //a počítá potřebné hodnoty s=(U[i][a]*p + V[i][a]*q)/r; v=(V[i][a]*p - U[i][a]*q)/r; for(int j=1; j<=a-1; j++) //cyklus prochází maticemi { U[i][j]=U[i][j]-U[a][j]*s+V[a][j]*v; //vlastní výraz pro redukování je //rozdělen do tří částí V[i][j]=V[i][j]-U[a][j]*v-V[a][j]*s; } } } } V úseku kde se prohazují řádky/sloupce je z důvodu větší přehlednosti okomentováno prohazování jen u matice U, u matice V by byl popis téměř shodný. Na konci této funkce proběhne vlastní redukce obou matic najednou (vysvětlení redukce viz. 3.2). 38
4.2.5 Ukázka spuštěného programu Po spuštění programu nás aplikace nejprve přivítá, vypíše název programu, jeho autora a jím studovaný obor.
Obrázek 19 úvodní obrazovka
Po stisknutí libovolné klávesy přistoupíme k zadání celkového počtu uzlů. Princip rozložení uzlů v obvodu je popsán v kapitole 3.1.2.
Obrázek 20 zadání počtu uzlů
39
Zadáme počet uzlů a stiskneme Enter. V dalším kroku již vkládáme jednotlivé součástky obvodu. Nejprve se zadá kód prvku (na obrázku například rezistor). Následně čísla uzlů, mezi kterými leží a nakonec jeho hodnota. Hodnoty součástek se zadávají v základních jednotkách.
Obrázek 21 vložení rezistoru
Po zadání všech údajů o daném prvku a stisknutí klávesy Enter, dojde ke kontrolnímu výpisu zadaných hodnot. Po tomto kroku se nás program zeptá, zda chceme zadávat další součástku. Jestliže nechceme pokračovat v zadávání, tak zvolíme volbu „n“. Tím se přejde k dalšímu kroku a to vypsání výsledných hodnot (v případě pouze rezistivních prvků v obvodu), nebo zadání minimální frekvence, maximální frekvence a vypsání výsledných hodnot (v případě přítomnosti minimálně jednoho frekvenčně závislého prvku v obvodu).
40
Obrázek 22 vypsání výsledných hodnot
41
5 Testování programu 5.1 Výpočet konkrétního příkladu 5.1.1 Můj program Program byl otestován na spoustě příkladů. Zde pro ukázku uvedu výpočet jednoho z nich a to Wienova článku. Máme tedy schéma zapojení:
Obrázek 23 Wienův můstek
Na ukázku uvedu vložení jen dvou součástek, pro další dvě by byl postup obdobný. Nejprve zadáme celkový počet uzlů v obvodu, v našem případě máme uzly 4. Následně budeme vkládat prvky obvodu. Vložení kondenzátoru C1 mezi první a třetí uzel:
42
Obrázek 24 zadávání kapacity
Vložení vodivosti G1 mezi třetí a druhý uzel:
Obrázek 25 zadávání vodivosti
Vkládání další prvků by tedy proběhlo obdobně jako předešlých dvou. Po zadání všech součástek a vzhledem k tomu, že máme v obvodu dokonce dva reaktanční prvky, musíme ještě zadat hodnoty frekvence. Poté se nám již zobrazí výsledek frekvenční analýzy obvodu. Viz.
43
Obrázek 26 výsledek
5.1.2 Program SNAP V programu SNAP by vypadal výpočet Wienova můstku následovně: Nejprve se obvod vytvoří vkládáním a propojováním součástek v Editoru.
Obrázek 27 Editor
44
Poté se v záložce „Analysis“ vybere položka „SNAP“. Tím dojde k otevření programu SNAP a vlastnímu výpočtu obvodu.
Obrázek 28 SNAP
Výsledky v numerickém tvaru jsou v programu SNAP v podobě grafu. Na obrázku „Obrázek 28“ je uveden výsledek pro napěťové zesílení v dB.
5.2 Porovnání výsledků V předešlé podkapitole byla ukázka práce dvou programů na zapojení Wienova můstku. Jako první byl uveden výpočet mým programem. Z obrázku s výslednými hodnotami můžeme vidět, že při frekvenci f=1Hz má obvod napěťové zesílení AudB=-12.2971dB. Program SNAP při stejné frekvenci vypočítal hodnotu AudB=-12,31dB. Na těchto dvou výsledcích vidíme rozdíl přibližně dvou setin. Pro porovnání byl výpočet proveden i ručně na papír. Zde se došlo k hodnotě AudB=-12,2758dB při frekvenci f=1Hz. Dovolím si tedy tvrdit, že můj program dosahuje o trochu přesnějšího výsledku než program SNAP. Možné vysvětlení odlišného výsledku programu SNAP by mohlo být to, že program SNAP nejprve symbolickým algoritmem dojde k symbolickému výsledku, tedy výsledku který neobsahuje konkrétní hodnoty prvků obvodu, dále prostým dosazením hodnot prvků získá semisymbolický výsledek. Až z tohoto výsledku získá numerický výsledek numerickým
45
algoritmem. Celá tato „cesta“ k výsledku v numerickém tvaru je zobrazena na následujícím obrázku:
Obrázek 29 cesty k výsledkům
Můj program provádí výpočet cestou „III“, tedy přímo, ne přes symbolický a semisymbolický výpočet.
46
6 Závěr 6.1 Zhodnocení práce Cílem bakalářské práce bylo napsat program pro frekvenční analýzu lineárního obvodu, který bude využíván k výukovým účelům na Vysoké škole polytechnické Jihlava. Podle požadavků zadávajícího umí program počítat se součástkami jako jsou rezistor, kapacita, cívka, tranzistor, trioda, operační zesilovač (ideální i reálný), transimpedanční zesilovač, konvejor, ... Hlavní výhoda tohoto programu je jednoduchost a větší přesnost výpočtu, než které dosahuje například konkurenční program Snap. Jistou nevýhodou může být pouze konzolová verze programu a výstup jen samotných čísel. Bylo by vhodné udělat výstup třeba v podobě grafu, což by se u konzolové verze dělalo obtížně.
6.2 Možnosti dalšího rozšíření aplikace Jak již bylo napsáno výše, rozšířením programu by mohla být grafická verze, kde by se elektrický obvod zadával podobně jako v programu SNAP a to vkládáním grafických prvků představujících vlastní obvodové prvky, které by se následně spojovaly. Další možnost rozšíření byla také zmíněna výše, výstupní hodnoty výpočtu by se mohly prezentovat v podobě grafu a nejen tabulky jako je to v mnou vytvořené verzi.
47
7 Seznam použité literatury [1]. BIOLEK, Dalibor. Navrhování elektronických obvodů počítačem : Počítačové modelování, analýza a simulace. Brno, 2004. 260 s. Skripta. VA Brno. Dostupné z WWW: . [2]. BRTNÍK, Bohumil. Elektrické obvody I.. Jihlava, 2007. 153 s. Skripta. Vysoká škola polytechnická Jihlava. [3]. BRTNÍK, Bohumil. Simulace elektronických obvodů. Jihlava, 2010. 77 s. Skripta. Vysoká škola polytechnická Jihlava. [4]. HEROUT, Pavel. Učebnice jazyka C. České Budějovice : Kopp, 2009. 280 s. ISBN 978-80-7232-383-8. [5]. PRATA, Stephen. Mistrovství v C++. Brno : COMPUTER PRESS, 2007. 957 s. ISBN 978-80-251-1749-1. [6]. OLŠÁK, Petr. Lineární algebra. Praha, 2000. 127 s. Skripta. ČVUT. [7]. NEDOMA, Josef. Matematika I.. Brno : CERM,s.r.o., 2001. 74 s. Skripta. VUT.
48
8 Seznam citací [1]. Praktická elektronika. In Wikipedia : the free encyclopedia [online]. St. Petersburg (Florida) : Wikipedia Foundation, 2006-05-11, last modified on 2011-01-14 [cit. 2011-04-27].
Dostupné
z
WWW:
. [2]. C++. In Wikipedia : the free encyclopedia [online]. St. Petersburg (Florida) : Wikipedia Foundation, 20.6.2004, last modified on 6.12.2010 [cit. 2011-05-09]. Dostupné z WWW: . [3]. BRTNÍK, Bohumil. Simulace elektronických obvodů. Jihlava, 2010. 77 s. Skripta. Vysoká škola polytechnická Jihlava.
49