Моделювання генератора періодичних коливань на основі лямбда-діода

Інформація про навчальний заклад

ВУЗ:
Національний університет Львівська політехніка
Інститут:
Не вказано
Факультет:
КН
Кафедра:
Кафедра електронні обчислювальні машини

Інформація про роботу

Рік:
2005
Тип роботи:
Лабораторна робота
Предмет:
Моделювання

Частина тексту файла (без зображень, графіків і формул):

МІНІСТЕРСТВО ОСВІТИ І НАУКИ УКРАЇНИ Національний Університет “Львівська політехніка” Кафедра “Електронні обчислювальні машини” Лабораторна робота №1 з дисципліни “МОДЕЛЮВАННЯ” на тему : ” Моделювання генератора періодичних коливань на основі лямбда-діода” Коляса Р. Р. Львів – 2005 Мета роботи: Розробити програму для візуального відображення динаміки процесів в коливній системі, проаналізувати поведінку генератора при різних числових значеннях параметрів елементів схеми, визначити області збудження генератора. Загальні відомості: Для отримання незгасаючих коливань в генераторах необхідно за допомогою зовнішніх елементів компенсувати втрати енергії в коливній системі. Це досягається за допомогою підсилювачів, охоплених позитивним зворотнім зв’язком, або за допомогою елементів, на вольт-амперних характеристиках яких існує або створена певним чином ділянка із від’ємним диференційним опором. До таких елементів належать, зокрема, тунельні діоди, в яких (внаслідок тунелювання електронів між зонами на прямій вольт-амперній характеристиці) виникає ділянка, для якої із збільшенням прикладеної до діода напруги, струм через діод зменшується (діод характеризується від’ємним диференційним опором). Іншим прикладом елемента із від’ємним диференційним опором є лямбда-діод. Такий діод може бути створений шляхом включення двох польових транзисторів із каналами типу n та p наступним чином:  Рис 1. Аналог лямбда діода, складений із двох польових транзисторів різної структури. Вольт-амперна характеристика діода (рис. 2) нагадує грецьку букву  (лямбда), на ній існує ділянка із додатнім диференційним опором АБ та ділянка із від’ємним диференційним опором БД. В околі точки Б характеристика діода близька до квадратичної, а при подальшому зростанні прикладеної напруги струм через діод спадає до нуля (точка Д).  Рис 2. Вольт-амперна характеристика лямбда-діода.  Рис. 3. Схема генератора коливань на основі лямбда діода. Генератор складається із джерела живлення V1, лямбда діода D1, коливного контуру R1, C1, L1, де резистор R1 імітує опір навантаження. Такий автогенератор може бути використаний як генератор гармонійних коливань в достатньо широкому діапазоні частот – від одиниць герц до сотень мегагерц. Для надійного самозбудження генератора напругу живлення доцільно вибрати на середині ділянки із від’ємним диференційним опором, що відповідає точці С воль-амперної характеристики діода. Для моделювання схеми необхідно описати вольт-амперну характеристику лямбда-діода. Зручно скористатись поліноміальною апроксимацією відносно точки Б, яка відповідає максимуму струму, що протікає через діод:   де К – порядок апроксимаційного поліному,  - коефіцієнти апроксимації,  - напруга на діоді, що відповідає максимальному значенню струму. Коефіцієнти  можна знайти із експериментально виміряної вольт-амперної характеристики діода, використовуючи метод найменших квадратів. Метод найменших квадратів ґрунтується на тому, що сума квадратів відхилень між експериментально виміряними () та розрахунковими () точками вольт-амперної характеристики повинна бути мінімальною:   де – кількість виміряних точок вольт-амперної характеристики діода. Оскільки в точці екстремуму значення градієнта функції  рівне нулеві, то продиференціювавши  за , отримуємо систему лінійних рівнянь відносно коефіцієнтів :   Систему (3) можна розв’язати за допомогою відомих чисельних методів, зокрема за допомогою методу Гауса або методу LU-розкладу (перевагу доцільно віддати останньому методу). Порядок полінома визначається експериментально, припускаючи при цьому, що максимальна похибка апроксимації не повинна перевищувати 1% - 2% від максимального значення струму, що протікає через лямбда-діод. Обчисливши апроксимаційні коефіцієнти , можна визначити значення струму в залежності від напруги між виводами діода. Для моделювання генератора коливань необхідно записати систему диференційних рівнянь у формі Коші, скориставшись законом Кірхгофа. Розв’язок отриманої системи можна побудувати за допомогою методів чисельного інтегрування. При розробці програми чисельного інтегрування доцільно передбачити можливість автоматичного вибору кроку інтегрування під час роботи програми. Текст програми: #include <vcl.h> #pragma hdrstop #include "Unit1.h" #include <stdio.h> #include <math.h> #include <stdlib> #include <math.h> #include <NRUTIL.H> #define N 76 //Кількість експериментальних даних //--------------------------------------------------------------------------- #pragma package(smart_init) #pragma resource "*.dfm" TForm1 *Form1; //--------------------------------------------------------------------------- #define NR_END 1 #define FREE_ARG char* #define NRANSI #define TINY 1.0e-20; int K; //Порядок апроксимаційного поліному float *Ue=vector(1,N); float *Ie=vector(1,N); float Ub,*Y,I; float **matrix(long nrl, long nrh, long ncl, long nch) /* allocate a float matrix with subscript range m[nrl..nrh][ncl..nch] */ { long i, nrow=nrh-nrl+1,ncol=nch-ncl+1; float **m; /* allocate pointers to rows */ m=(float **) malloc((size_t)((nrow+NR_END)*sizeof(float*))); if (!m) nrerror("allocation failure 1 in matrix()"); m += NR_END; m -= nrl; /* allocate rows and set pointers to them */ m[nrl]=(float *) malloc((size_t)((nrow*ncol+NR_END)*sizeof(float))); if (!m[nrl]) nrerror("allocation failure 2 in matrix()"); m[nrl] += NR_END; m[nrl] -= ncl; for(i=nrl+1;i<=nrh;i++) m[i]=m[i-1]+ncol; /* return pointer to array of pointers to rows */ return m; } float *vector(long nl, long nh) /* allocate a float vector with subscript range v[nl..nh] */ { float *v; v=(float *)malloc((size_t) ((nh-nl+1+NR_END)*sizeof(float))); if (!v) nrerror("allocation failure in vector()"); return v-nl+NR_END; } int *ivector(long nl, long nh) /* allocate an int vector with subscript range v[nl..nh] */ { int *v; v=(int *)malloc((size_t) ((nh-nl+1+NR_END)*sizeof(int))); if (!v) nrerror("allocation failure in ivector()"); return v-nl+NR_END; } void nrerror(char error_text[]) /* Numerical Recipes standard error handler */ { /*fprintf(stderr,"Numerical Recipes run-time error...\n"); fprintf(stderr,"%s\n",error_text); fprintf(stderr,"...now exiting to system...\n");*/ exit(1); } void lubksb(float **a, int n, int *indx, float b[]) { int i,ii=0,ip,j; float sum; for (i=1;i<=n;i++) { ip=indx[i]; sum=b[ip]; b[ip]=b[i]; if (ii) for (j=ii;j<=i-1;j++) sum -= a[i][j]*b[j]; else if (sum) ii=i; b[i]=sum; } for (i=n;i>=1;i--) { sum=b[i]; for (j=i+1;j<=n;j++) sum -= a[i][j]*b[j]; b[i]=sum/a[i][i]; } } void ludcmp(float **a, int n, int *indx, float *d) { int i,imax,j,k; float big,dum,sum,temp; float *vv; vv=vector(1,n); *d=1.0; for (i=1;i<=n;i++) { big=0.0; for (j=1;j<=n;j++) if ((temp=fabs(a[i][j])) > big) big=temp; if (big == 0.0) nrerror("Singular matrix in routine ludcmp"); vv[i]=1.0/big; } for (j=1;j<=n;j++) { for (i=1;i<j;i++) { sum=a[i][j]; for (k=1;k<i;k++) sum -= a[i][k]*a[k][j]; a[i][j]=sum; } big=0.0; for (i=j;i<=n;i++) { sum=a[i][j]; for (k=1;k<j;k++) sum -= a[i][k]*a[k][j]; a[i][j]=sum; if ( (dum=vv[i]*fabs(sum)) >= big) { big=dum; imax=i; } } if (j != imax) { for (k=1;k<=n;k++) { dum=a[imax][k]; a[imax][k]=a[j][k]; a[j][k]=dum; } *d = -(*d); vv[imax]=vv[j]; } indx[j]=imax; if (a[j][j] == 0.0) a[j][j]=TINY; if (j != n) { dum=1.0/(a[j][j]); for (i=j+1;i<=n;i++) a[i][j] *= dum; } } free_vector(vv,1,n); } void free_vector(float *v, long nl, long nh) /* free a float vector allocated with vector() */ { free((FREE_ARG) (v+nl-NR_END)); } int readdata() { FILE *f; int i; f=fopen("D:\data.txt","rb"); if(f!=NULL) { for(i=1;i<=N;i++) { fscanf(f,"%f",&Ue[i]); fscanf(f,"%f",&Ie[i]); //printf("%lf\n",Ue[i]); } return 1; } else { //printf("Unnable open file for reading :-("); return 0; } } int findindexUb(float* ptr, int size) { int i,j=1; float max=*ptr; for(i=1;i<=size;i++) if(ptr[i]>max) { max=ptr[i]; j=i; } return j; } float F(float U) { float I; I=Y[1]; for(int i=2;i<=K;i++) I+=Y[i]*pow(U-Ub,i-1); return I; } void derivs(float x, float *y,float *dydx) { dydx[1]=1e+6 * (F(4.8-y[1])-y[2]-y[1]/(5e+3)); dydx[2]=y[1]/10e-3; return; } void rk4(float y[], float dydx[], int n, float x, float h, float yout[], void (*derivs)(float, float [], float [])) { int i; float xh,hh,h6,*dym,*dyt,*yt; dym=vector(1,n); dyt=vector(1,n); yt=vector(1,n); hh=h*0.5; h6=h/6.0; xh=x+hh; for (i=1;i<=n;i++) yt[i]=y[i]+hh*dydx[i]; (*derivs)(xh,yt,dyt); for (i=1;i<=n;i++) yt[i]=y[i]+hh*dyt[i]; (*derivs)(xh,yt,dym); for (i=1;i<=n;i++) { yt[i]=y[i]+h*dym[i]; dym[i] += dyt[i]; } (*derivs)(x+h,yt,dyt); for (i=1;i<=n;i++) yout[i]=y[i]+h6*(dydx[i]+dyt[i]+2.0*dym[i]); free_vector(yt,1,n); free_vector(dyt,1,n); free_vector(dym,1,n); } __fastcall TForm1::TForm1(TComponent* Owner) : TForm(Owner) { Image1->Canvas->Pen->Color=clBlack; Image1->Canvas->Rectangle(0, 0, Image1->Width, Image1->Height); Memo1->Text="Натисніть кнопку Stage1."; Edit1->Text=5; } //--------------------------------------------------------------------------- void __fastcall TForm1::Button1Click(TObject *Sender) { float **a,*b; float **B; float maxerror=0,Ib; AnsiString str; K=Edit1->Text.ToInt(); Image1->Canvas->Pen->Color=clBlack; Image1->Canvas->Rectangle(0, 0, Image1->Width, Image1->Height); Button2->Enabled=TRUE; Label4->Visible=TRUE; Label5->Visible=TRUE; Label6->Visible=FALSE; Label7->Visible=FALSE; Image1->Canvas->Pen->Color=clBlue; Image1->Canvas->Rectangle(250, 30, 260, 40); Image1->Canvas->Pen->Color=clRed; Image1->Canvas->Rectangle(250, 49, 260, 59); B=matrix(1,K,1,K); Y=vector(1,K); readdata(); /*for(int i=1;i<=N;i++) str.cat_printf("%f%c%c",Ie[i],13,10); */ int indexmax=findindexUb(Ie,N); Ub=Ue[indexmax]; Ib=Ie[indexmax]; //--------------------Calculate B-------------------------- for(int l=1;l<=K;l++) for(int m=1;m<=K;m++) { B[l][m]=0; if(l+m-2==0) B[l][m]=N; else for(int j=1;j<N;j++) B[l][m]+=pow(Ue[j]-Ub,l+m-2); } //--------------------Calculate Y-------------------------- Y[1]=0; for(int j=1;j<N;j++) Y[1]+=Ie[j]; for(int l=2;l<=K;l++) { Y[l]=0; for(int j=1;j<N;j++) Y[l]+=pow(Ue[j]-Ub,l-1)*Ie[j]; } int *indx=ivector(1,K); float d; /* for(int i=1;i<=K;i++) { for(int j=1;j<=K;j++) str.cat_printf("%15.5f ",B[i][j]); str.cat_printf("%c%c",13,10); } str.cat_printf("%c%c",13,10); for(int i=1;i<=K;i++) str.cat_printf("%15.5f%c%c",Y[i],13,10); */ ludcmp(B,K,indx,&d); lubksb(B,K,indx,Y); /* str.cat_printf("%c%c",13,10); for(int i=1;i<=K;i++) str.cat_printf("%15.5f%c%c",Y[i],13,10); */ for(int j=1;j<=N;j++) { I=Y[1]; for(int i=2;i<=K;i++) I+=Y[i]*pow(Ue[j]-Ub,i-1); float curerror=((I-Ie[j])/Ib)*100; (fabs((double)curerror)>fabs((double)maxerror))?(maxerror=curerror):(maxerror); str.cat_printf("%c%cF=%15.7f, Ie=%15.7f, per=% 15.6f",13,10,I,Ie[j],((I-Ie[j])/Ib)*100); str.cat_printf("%c%c",13,10); } AnsiString errorstr; errorstr.cat_printf("%7.5f \%",maxerror); Edit2->Text=errorstr; Memo1->Text=str; Image1->Canvas->MoveTo(0,Image1->Height); Image1->Canvas->Pen->Color=clBlue; for(int i=1;i<=N;i++) Image1->Canvas->LineTo(5*Ue[i]*10,Image1->Height-1.5*Ie[i]*10e+4); Image1->Canvas->MoveTo(0,Image1->Height); Image1->Canvas->Pen->Color=clRed; for(int i=1;i<=N;i++) Image1->Canvas->LineTo(5*Ue[i]*10,Image1->Height-1.5*F(Ue[i])*10e+4); str=""; str.cat_printf("%.3e",Y[1]); for (int i=2;i<=K;i++) str.cat_printf(", %.3e",Y[i]); Edit3->Text=str; } //--------------------------------------------------------------------------- void __fastcall TForm1::Button2Click(TObject *Sender) { AnsiString str; float *y=vector(1,2); float *dydx=vector(1,2); float x; float h=2*3.1415*sqrt(10e-2*1e-6)/60; float *yout=vector(1,2); Label4->Visible=FALSE; Label5->Visible=FALSE; Label6->Visible=TRUE; Label7->Visible=TRUE; Image1->Canvas->Pen->Color=clBlack; Image1->Canvas->Rectangle(0, 0, Image1->Width, Image1->Height); Image1->Canvas->MoveTo(0,Image1->Height/4); Image1->Canvas->Pen->Color=clBlue; str.cat_printf(" U I%c%c",13,10); x=0; y[1]=0;y[2]=0; for(int i=0;i<Image1->Width/3;i++) { derivs(x,y,dydx); rk4(y,dydx,2,x,h,y,derivs); Image1->Canvas->LineTo(3*i, Image1->Height/4-y[2]*10000); str.cat_printf("% f | % f%c%c", y[1],y[2],13,10); } Memo1->Text=str; Image1->Canvas->MoveTo(0,Image1->Height*3/4); Image1->Canvas->Pen->Color=clRed; x=0; y[1]=0;y[2]=0; for(int i=0;i<Image1->Width/3;i++) { derivs(x,y,dydx); rk4(y,dydx,2,x,h,y,derivs); Image1->Canvas->LineTo(3*i, Image1->Height*3/4-y[1]*100); } } //--------------------------------------------------------------------------- void __fastcall TForm1::Button3Click(TObject *Sender) { Form1->Close(); } Результат виконання програми:  Висновки: На даній лабораторній роботі ми дослідили принцип роботи лямбда-діода, а також здобули практичних навиків в моделюванні фізичних процесів засобами мови С++, використовуючи метод Рунне-Кутти.
Антиботан аватар за замовчуванням

13.02.2013 14:02-

Коментарі

Ви не можете залишити коментар. Для цього, будь ласка, увійдіть або зареєструйтесь.

Ділись своїми роботами та отримуй миттєві бонуси!

Маєш корисні навчальні матеріали, які припадають пилом на твоєму комп'ютері? Розрахункові, лабораторні, практичні чи контрольні роботи — завантажуй їх прямо зараз і одразу отримуй бали на свій рахунок! Заархівуй всі файли в один .zip (до 100 МБ) або завантажуй кожен файл окремо. Внесок у спільноту – це легкий спосіб допомогти іншим та отримати додаткові можливості на сайті. Твої старі роботи можуть приносити тобі нові нагороди!
Нічого не вибрано
0%

Оголошення від адміністратора

Антиботан аватар за замовчуванням

Подякувати Студентському архіву довільною сумою

Admin

26.02.2023 12:38

Дякуємо, що користуєтесь нашим архівом!