/***********************************************   P+PNPP+ double junction type Photodiode for Solar Cell Application ************************************************ 2020年4月20日 現在 002 ************************************************* ************************************************ *********************************************************** Main Program の名称は void main( void ) です。 **********************************************************  NP 個の graph を描いて a.html に出力します。 **********************************************************  関数 PXPY( ) で Graphの各点の座標値を決定します。             for k=1 to NP and for i = 0 to N,   各点の座標値は XP[k][i]、YP[k][i]  に入ります。 **********************************************************   電位 V[j] for j = 0 to N の値を数値計算します。     変数 X の 区間 は [ 0, Xm ] です。       関数 dope ( ) 関数は  不純物濃度 D を 計算します。  ***********************************************************/ #include #include /***************************************************      出力 File の 定義   fpAA に 計算結果 data が aa.txt に出力されます。    他のFile はグラフ描画の為の補助 file です。     この program を実行する為には必要なものです。  そのまま変更しないで一緒に加えて実行してください。 ****************************************************/ FILE *fpAA; FILE *fpC; /**************************************************************/ /************************************** Graph を NP 個 描きます。 **************************************/ int NP=1; /************************************** 各Graphの点の数は N個です。  **************************************/ int N = 10000,N2 =5000,NN=100 ; double XP[10][10001],YP[10][10001],V[10001],VV[10002]; double DX,DXX,XX,YY; /************************************************** Graphの描画範囲(わく)の値を決定します  すなわち Graphの描画範囲を決定します。 ***************************************************/ double xx,yy ; double xmin=0,xmax=20,ymin=0,ymax=10; double xxmin[10],xxmax[10],yymax[10],yymin[10]; int nxx,nx1=100,nx2=600,nyy,ny1=50,ny2=1050 ; int i,j,k,m; /****************************************************/ /*******************************************      関数 PXPY( ) を定義して    Graphの各点の座標値を決定します。          for i_plot =1 to nfn and for i = 0 to N,      各点の座標 XP[k][i]、YP[k][i] を決定します。   Graph を描いて A(k).html に出力します。 i_plot = 1 の時は A1.html に       i_plot = 2 の時は A2.html に         .............................................. i_plot = 9 の時は A9.html に出力されます。 ***************************************************/ /******************************************** 反復計算の回数 hhhhhh の値を決めます *********************************************/ int hhhhhh=10000; /*********************************************/ /************************************************************/ /************************************************ Case 001 ************************************************/ double Ns=10000000,Na=10000,Nd=100; double X1 =4, X5 =7; /************************************************/ double Rs = 0.25, Ra = 2.5; double Xm=10; double D1,V1; double X2,V2,D2; double X4,D4,V4; double D5,V5; double kT = 0.0259, Esi = 648; double NDD,NAA,VMM; double X, D, Hole, VB; double XX1,XX2,XX3,XX4,XX5,XX6,XX7,XX8,XX9,XX10,XX11,XX12; double WW1,WW2,WW3,WW4,WW5; double Doo,QDD,QAA; double W,A; double ErrMax,X_ErrMax,Err,Drr; int i_ErrMax ; /***************************************************/ /************ GetXPYP ( ) の 初期変数設定です ****************/ /********************************************************* いろいろな値で掲載した事例の結果を記録しています。 *********************************************************** (1) Ns=10000000,Xs = 0.57,Na=3000,Xa=5,Nd=100,Xm=10,SCP=20; VB = 0.195 V, Vm = 0.310 V, Xj = 9.20 , Vo = 0.298 V, ; (2) Ns=10000000,Xs = 0.57,Na=3000,Xa=4,Nd=100,Xm=10,SCP=20; VB = 0.195 V , Vm = 0.801 V, Xj = 7.35 , Vo = 0.451 V, ; (3) Ns=10000000,Xs = 0.57,Na=100000,Xa=3,Nd=100,Xm=10,SCP=20; VB = 0.111 V , Vm = 0.624 V, Xj = 7.85 , Vo = 0.356 V, ; (4) Ns=10000000,Xs = 0.57,Na=500000,Xa=2.5,Nd=100,Xm=10,SCP=20; VB = 0.072 V , Vm = 0.878 V, Xj = 7.25 , Vo = 0.383 V, ; ***************************************************************/ /***********************************************   P+PNPP+ double junction type Photodiode for Solar Cell Application ( Line 246〜 ) ************************************************/ /*********************************************************** Main Program の名称は void main( void ) です。  NP 個の graph を描いて a.html に出力します。 関数 PXPY( ) を定義し、Graphの各点の座標値を決定します。             for k=1 to NP and for i = 0 to N,   各点の座標値は XP[k][i]、YP[k][i]  に入ります。   ***********************************************************/ /***********************************************   P+PNPP+ double junction type Photodiode for Solar Cell Application ( Line 855〜 ) ************************************************/ /*******************************************      関数 PXPY( ) を定義して    Graphの各点の座標値を決定します。          for k =1 to NP and for i = 0 to N,      各点の座標 XP[k][i]、YP[k][i] を決定します。   Graph を描いて A(k).html に出力します。 k = 1 の時は A1.html に       k = 2 の時は A2.html に         .............................................. k = 9 の時は A9.html に出力されます。 ***************************************************/ /********************************************************** ここからは PXPY ( ) の Program の Coding です。 **********************************************************/ /****************************************************    ここで、不純物濃度 D(X) の値を決めます。  Xss < 0.01 (μm) は、表面均一イオン打ち込みの深さです。     表面にさらにHole Accumultaion 領域を形成できます。        表面電界が生じないようにするには       さらに 表面が絶対空乏化しない濃度の               P++の 薄い 均一な 層を          形成する事も可能です。        ここでは Xss = 0 としていますが、           いろいろ変更可能です。     また、これは double ion 打ち込みの場合ですが、         single ion 打ち込みの場合も可能です。     また、 N type 基板でなく、P type 基板にして、        埋め込み N 層を deep ion 打ち込みで     Ndd exp ( - ( X - Xdd)/Xd ) とする事も可能です。          自由に変更してください。 ***************************************** また、均一不純物濃度の場合もあります。 この場合は空乏層近位の2次式で かなり精度良く近似できます。 ***************************************** *****************************************************/ /*****************************************************      Case (1) 均一不純物濃度の場合です。      この場合は空乏層近位の2次式で   かなり精度良く近似できます。 *****************************************************/ /************************************************* void Dope(void)の定義 *************************************************/ /************************************************** Case (1) **************************************************/ void Dope(void) { double s ; if ( X < X1) { D = Ns ; return ; } if ( X < X5 ) { D = Na ; return ; } D = - Nd ; } /**************************************************/ /***********************************************************/ void Find_XX5(void) { double dx = 0.000001; X = 0; NEXTX: Dope( ); if( D < 0 ) goto FINISH; X=X+dx; goto NEXTX; FINISH: XX5 = X ; D5 = D; printf("\n\n Find_XX5( ) : XX5 = % f D(XX5) = %f", XX5,D5 ); X=XX5-dx; Dope( ); printf("\n\n Find_XX5( ) : XX5 - dx = % f D(XX5-dx) = %f", XX5 - dx , D); } /**********************************************************/ /*****************************************************    空乏層近似と 表面近傍ではバリア電界近似で     反復計算の初期値 WW( ) 関数を使って求めます ******************************************************/ /**********************************************************/ void WW(void) { /*************************************************** ( X < Xo ) では、バリア電界近似で求めます。 ****************************************************/ if ( X < XX1 ) { Dope( ); W = kT*log(Doo/D) ; return ; } if ( X < XX4 ) { W = VB; return; } /************************************************** ( XX1<=X < XX4 ) では、V(XX4) = V4 を起点として、       空乏層近似で求めます **************************************************/ if ( X < XX5 ) { W = (X-XX4)*(X-XX4)*NAA/2/Esi + V4 ; return; } /************************************************** ( XX1 <= X<= Xm ) では、 (Xm -X) に注目し、 V(Xm) = VMM を起点として、空乏層近似で求めます **************************************************/ W = VMM - NDD*(Xm - X)*(Xm - X)/2/Esi; } /**************************************************/ /***************************************************/ void ErrorV(void) { int i; ErrMax=0; V[N+1]=V[N-1]; for (i=1;i 0 at X = 0 , and D(X) = - Ndd < 0 at X = Xm. D(X) = 0  となる X=XX5 の値を求めます。 *********************************************************/ Find_XX5( ); X=XX5; Dope( ); D5=D; X=XX5-DX; Dope( ); fprintf(fpAA,"\n\n (016) XX5 = %f XX5-DX = %f ",XX5, XX5-DX ); fprintf(fpAA,"\n\n (017) D5 =D(XX5) = %f D(XX5-DX) = %f ", D5, D ); printf( "\n\n (016) XX5 = %f XX5-DX = %f ",XX5, XX5-DX ); printf( "\n\n (017) D5 =D(XX5) = %f D(XX5-DX) = %f ", D5, D ); XX7=2*Xm -XX5; fprintf(fpAA,"\n\n (018) The PN junction edge XX5 = %f ", XX5 ); fprintf(fpAA,"\n\n (019) The PN junction edge XX7 = 2*Xm - XX5 = %f ", XX7 ); printf("\n\n (018) The PN junction edge XX5 = %f ", XX5 ); printf("\n\n (019) The PN junction edge XX7 = 2*Xm - XX5 = %f ", XX7 ); /******************************************************* P+PNPP+接合 幅 XX12 = 2*Xm の中で       埋め込み N 層の 幅 WW1の値を求めます。 ********************************************************/ WW1 = 2* ( Xm - XX5) ; fprintf(fpAA,"\n\n (020) The width of the N region ") ; printf( "\n\n (020) The width of the N region ") ; fprintf(fpAA," WW1 = XX7 - XX5 = 2* ( Xm - XX5) = %f ", WW1 ); printf( " WW1 = XX7 - XX5 = 2* ( Xm - XX5) = %f ", WW1 ); /******************************************************/ /*******************************************************    P+PNPP+接合 幅 XX12 = 2*Xm の中で  埋め込み N 層の 不純物DOSE量 QDDの値を求めます。 ********************************************************/ DXX = ( Xm - XX5)/1000000; QDD=0; for (i=1;i<1000001;i++) { X = XX5 + ( i - 0.5 )*DXX; Dope( ); QDD= QDD+ D*DXX; } QDD = - QDD; printf( "\n\n (021) In N region [ XX5 , Xm ] = [ %f , %f ]", XX5,Xm ) ; printf( "\n\n the tolal charge QDD = %f ", QDD) ; fprintf(fpAA,"\n\n (021) In N region [ XX5 , Xm ] = [ %f , %f ]", XX5,Xm ) ; fprintf(fpAA,"\n\n the tolal charge QDD = %f ", QDD) ; /************************************************************   表面のP+P 層側の空乏層の右側の境界位置 XX4 を求めます。 Left方向 <--- Xm < XX5 < XX4 < XX1 < 0 ---> Right方向      QDD = 区間 [ XX5, Xm ] の 不純物DOSE量 平均不純物濃度 NDD = QDD/ ( Xm - XX5 ) の値を求めます。 *************************************************************/ NDD=QDD/( Xm - XX5 ); printf( "\n\n (022) In N region [ XX5 , Xm ] = [ %f , %f ]", XX5,Xm); fprintf(fpAA,"\n\n (022) In N region [ XX5 , Xm ] = [ %f , %f ]", XX5,Xm ); printf( "\n\n NDD = QDD/( Xm - XX5 )= %f with Nd = %f ", NDD,Nd); fprintf(fpAA,"\n\n NDD = QDD/( Xm - XX5 )= %f with Nd = %f ", NDD,Nd); /************************************************************   表面のP+P 層側の空乏層の右側の境界位置 XX4 を求めます。 Left方向 <--- Xm < XX5 < XX4 < XX1 < 0 ---> Right方向      QDD = 区間 [ XX5, Xm ] の 不純物DOSE量      QAA = 区間 [ XX4, XX5] の 不純物DOSE量 不純物DOSE量 QAA = QDD となる点が XX4の値です。 *************************************************************/ QAA=0; i=0; X=0; NEXT_i : X=XX5 - ( i - 0.5 )*DXX; Dope( ); QAA = QAA + D*DXX; i=i+1; if(QAA Right方向      QDD = 区間 [ XX5, Xm ] の 不純物DOSE量      QAA = 区間 [ XX4, XX5] の 不純物DOSE量 不純物DOSE量 QAA = QDD となる点が XX4の値です。 平均不純物濃度 NAA = QAA / ( XX5 - XX4 ) を求めます。 **************************************************************/ NAA = QDD/ ( XX5 - XX4 ) ; printf( "\n\n (030)  P 領域側の空乏層の平均不純物濃度"); printf( "\n\n NAA= QDD/ ( XX5 - XX4 ) = %f with Na = %f ", NAA,Na) ; fprintf( fpAA,"\n\n (030) P 領域側の空乏層の平均不純物濃度"); fprintf( fpAA,"\n\n NAA= QDD/ ( XX5 - XX4 ) = %f with Na =%f ", NAA,Na) ; /************************************************************************/ /*****************************************************       空乏層近似での N層の中の       Empty Potential Well の minimum 電位    最低電圧 VMMの値を求めます. ******************************************************       同じ空乏層近似での式が      関数 WW( )の定義でも使用しています。 Empty Well Potentialの概算値の計算 ******************************************************/ VMM = NAA* ( XX5 - XX4 )* ( XX5 - XX4 )/2/Esi + NDD* ( Xm - XX5 )* ( Xm - XX5 )/2/Esi + V4; printf( "\n\n (032) Empty Well Potential = VMM = %f \n\n", VMM); fprintf(fpAA,"\n\n (032) Empty Well Potential = VMM = %f \n\n", VMM); /*****************************************************    空乏層近似と 表面近傍ではバリア電界近似で      V(X)に関する反復計算の初期を求めます。     WW( ) 関数を使って V(X) の初期値を求めます。 ******************************************************/ DX=Xm/N ; ErrMax=0; /*********************************************/ for (i=1;i"); c=getchar( ); if(c =='c') printf("\n\n Good Bye ! \n\n") ; fprintf( fpAA,"\n\n"); /***********************************************   P+PNPP+ double junction type Photodiode for Solar Cell Application ( Line 1210〜 ) ************************************************/ /************************************************ ここから 反復計算を hhhhh 回 実行します。 ************************************************/ /******************* Loop 001 **********************/ for (h=0;h 0 ) { h = 0 ; k=k+1; fprintf(fpAA, "\n\n i= %d XX%d = %f \n\n" , i, k, X) ; goto HHH; } if( h == 0 ) if ( D < 0 ) { h = 1 ; k=k+1; fprintf(fpAA, "\n\n i= %d XX%d = %f \n\n" , i, k, X) ; } HHH: /***********************************************/ X=i*DX; Dope( ) ; Hole = Doo*exp( - V[i]/kT) ; /***********************************************************           Graphの座標DATAを計算します。 Graph を NP 個 描きます。 ************************************************************/ NP = 4 ; /***************** Graph (1) ********************************** k = 1 電位 V(X)  の グラフを 描画します。 ************************************************************/ k=1; xxmin[k] = 0 ; xxmax[k] = 10 ; yymin[k]= 0.9 ; yymax[k] = - 0.1 ; /************************************************************/ XX = X ; if ( XX < xxmin[k] ) XX = xxmin[k]; if ( XX > xxmax[k] ) XX = xxmax[k]; XP[k][i] = xmin+ xmax*( XX - xxmin[k] ) /( xxmax[k] -xxmin[k] ) ; YY = V[i]; if ( YY > yymin[k] ) YY = yymin[k] ; if ( YY < yymax[k] ) YY = yymax[k]; YP[k][i] = ymin + ymax* ( YY - yymin[k] ) /( yymax[k] -yymin[k] ) ; /*************************************************************/ /***************** Graph (2) **************************** k = 2 電位 V(X)  の グラフを 描画します。 ********************************************************/ k=2; xxmin[k] = 3.9 ; xxmax[k] = 4.3 ; yymin[k]= 0.2 ; yymax[k] = -0.1 ; /************************************************************/ XX = X ; if ( XX < xxmin[k] ) XX = xxmin[k]; if ( XX > xxmax[k] ) XX = xxmax[k]; XP[k][i] = xmin+ xmax*( XX - xxmin[k] ) /( xxmax[k] -xxmin[k] ) ; YY = V[i]; if ( YY > yymin[k] ) YY = yymin[k] ; if ( YY < yymax[k] ) YY = yymax[k]; YP[k][i] = ymin + ymax* ( YY - yymin[k] ) /( yymax[k] -yymin[k] ) ; /*************************************************************/ /***************** Graph (3) **************************** k = 3 電位 ρ(x) = D(x) - P(V(x))  の グラフを 描画します。 ********************************************************/ k=3; xxmin[k] = 3.9 ; xxmax[k] = 4.3 ; yymin[k] = - Ns ; yymax[k] = Ns ; /************************************************************/ XX = X ; if ( XX < xxmin[k] ) XX = xxmin[k]; if ( XX > xxmax[k] ) XX = xxmax[k]; XP[k][i] = xmin+ xmax*( XX - xxmin[k] ) /( xxmax[k] -xxmin[k] ) ; Dope( ) ; YY = D - Ns*exp ( - V[i] / kT ) ; if ( YY < yymin[k] ) YY = yymin[k] ; if ( YY > yymax[k] ) YY = yymax[k]; YP[k][i] = ymin + ymax* ( YY - yymin[k] ) /( yymax[k] -yymin[k] ) ; /*************************************************************/ /***************** Graph (4) **************************** k = 4 電位 ρ(x) = D(x)   の グラフを 描画します。 ********************************************************/ k=4; xxmin[k] = 0 ; xxmax[k] = 10 ; yymin[k] = - 50*Nd ; yymax[k] = 50*Nd ; /************************************************************/ XX = X ; if ( XX < xxmin[k] ) XX = xxmin[k]; if ( XX > xxmax[k] ) XX = xxmax[k]; XP[k][i] = xmin+ xmax*( XX - xxmin[k] ) /( xxmax[k] -xxmin[k] ) ; Dope( ) ; YY = D - Ns *exp( - V[i]/kT ) ; if ( YY < yymin[k] ) YY = yymin[k] ; if ( YY > yymax[k] ) YY = yymax[k]; YP[k][i] = ymin + ymax* ( YY - yymin[k] ) /( yymax[k] -yymin[k] ) ; /*************************************************************/ Dope( ); Hole = Ns*exp(-V[i]/kT); Err = ( V[i] - V[i-1] )/DX ; fprintf(fpAA,"\n i=%d X=%f D =%f V= %f dV/dX = %f Hole = %f ( Hole - D ) = %f " , i, X, D, V[i], Err, Hole, Hole - D ) ; } /************* End Loop 009 **********************/ /******************************************* この後は Graph を描いて a.html に出力します  ********************************************/ fclose(fpAA); } /****************************************** End of Function void PXPY ( void ) *********************************************/ /****************************************** void Graph_Plot(void)   グラフ描画出力用の定義です。 *********************************************/ void Graph_Plot(void) { printf("\n\n Graph_PLot(%d) ......... Output = A&d.html ..... ",k,k); if ( k == 1 ) fpC=fopen("A1.html","w"); if ( k == 2 ) fpC=fopen("A2.html","w"); if ( k == 3 ) fpC=fopen("A3.html","w"); if ( k == 4 ) fpC=fopen("A4.html","w"); if ( k == 5 ) fpC=fopen("A5.html","w"); if ( k == 6 ) fpC=fopen("A6.html","w"); if ( k == 7 ) fpC=fopen("A7.html","w"); if ( k == 8 ) fpC=fopen("A8.html","w"); if ( k == 9 ) fpC=fopen("A9.html","w"); fprintf(fpC,"\n"); fprintf(fpC,"\n\n\n"); fprintf(fpC,"\n"); fprintf(fpC,"\n\n\n
\n"); fprintf(fpC,"
\n\n\n"); fprintf(fpC,"Frame < xmin = 0 , xmax = 20 , ymin = 0 , ymax = 10 >
\n") ; fprintf(fpC," Graph %d < xxmin = %f , xxmax =%f , yymin =%f , yymax = %f > \n", k, xxmin[k],xxmax[k],yymin[k],yymax[k]) ; fprintf(fpC,"

\n"); fprintf(fpC," Graph (%d) ........ V(x),D(x) and ρ(x) = D(x) - P(V) .......\n", k ) ; fprintf(fpC,"
\n

\n

\n"); /******************************************************* グラフの枠 ( k = 0 ) を描きます  *******************************************************/ for (i =0 ; i< 2500 ; i++) { XP[0][i] = xmin ; YP[0][i] = ymin + ( 2500 - i )*( ymax -ymin)/2500; } for (i =2500; i< 5000 ; i++) { XP[0][i] = xmax ; YP[0][i] = ymin + ( 5000 - i )*( ymax -ymin)/2500; } for (i =5000; i< 7500 ; i++) { YP[0][i] = ymin ; XP[0][i] = xmin + ( 7500 - i )*( xmax- xmin)/2500; } for (i =7500; i<=10000 ; i++) { YP[0][i] = ymax ; XP[0][i] = xmin + (10000 - i )*( xmax-xmin)/2500; } /********************************************************/ for ( i =0; i<=N ; i++) { xx= XP[0][i] ; yy= YP[0][i] ; /**************************************************************  描画したい点 (xx,yy) のGraph 上での絶対座標 (nxx,nyy) の計算 **************************************************************/ nyy = ny1 + (xx-xmin)*(ny2-ny1)/(xmax-xmin) ; nxx = nx2 + (yy-ymin)*(nx1-nx2)/(ymax-ymin) ; /**************************************************************/ fprintf(fpC,"

"); fprintf(fpC,"."); fprintf(fpC,"

\n" ); } /**************************************************************/ /******************************************************* k 番目の グラフ ( k > 0 ) を描きます  *******************************************************/ for ( i =0; i<=N ;i++) { xx= XP[k][i]; yy= YP[k][i]; /**************************************************************  描画したい点 (xx,yy) のGraph 上での絶対座標 (nxx,nyy) の計算 **************************************************************/ nyy = ny1 + (xx-xmin)*(ny2-ny1)/(xmax-xmin) ; nxx = nx2 + (yy-ymin)*(nx1-nx2)/(ymax-ymin) ; /**************************************************************/ fprintf(fpC,"

"); fprintf(fpC,"."); fprintf(fpC,"

\n" ); } /**************************************************************/ fprintf(fpC,"\n\n"); fclose(fpC); printf("\n\n ******* See a%d.html *******\n\n",k); }/********* End of PXPY ( ) *****************/ /***********************************************   P+PNPP+ double junction type Photodiode for Solar Cell Application ( Line 1839〜 ) ************************************************/ /***********************************************   P+PNPP+ double junction type Photodiode for Solar Cell Application ************************************************/ /*********************************************************** Main Program の名称は void main( void ) です。  NP 個の graph を描いて a.html に出力します。 関数 PXPY( ) を定義し、Graphの各点の座標値を決定します。             for k=1 to NP and for i = 0 to N,   各点の座標値は XP[k][i]、YP[k][i]  に入ります。   ***********************************************************/ void main( void ) { char c ; PXPY( ); for ( k=1; k" ); c=getchar( ); if(c =='c') printf("\n\n Good Bye ! \n\n"); c=getchar( ); if(c =='c') printf("\n\n Good Bye ! \n\n"); } /**END of Source Program Code ****************/