/* 1SS294/319 (from data sheet) 0.216 0.1m 0.240 0.3m 0.265 1m 0.305 4m 0.341 10m 0.412 30m 0.471 50m 0.584 100m */ array(d, 7, 1) $ d[0,0] : 0.216 $ d[0,1] : 1e-4 $ d[1,0] : 0.240 $ d[1,1] : 3e-4 $ d[2,0] : 0.265 $ d[2,1] : 1e-3 $ d[3,0] : 0.305 $ d[3,1] : 4e-3 $ d[4,0] : 0.341 $ d[4,1] : 10e-3 $ d[5,0] : 0.412 $ d[5,1] : 30e-3 $ d[6,0] : 0.471 $ d[6,1] : 50e-3 $ d[7,0] : 0.584 $ d[7,1] : 100e-3 $ /* あらかじめ 100uA, 4mA 時の Id を元に Is, N の概略値を求めておく */ fn(Vd) := Is*(exp(Vd/(N*VT)) - 1) $ VT : 0.026 $ Is : 1e-7 $ N : 1 $ low : 0 $ hi : 3 $ f : 0 $ for i : 0 while i < 30 do ( /* Is を漸近させる */ tId1 : fn(d[low, 0]), tId2 : fn(d[hi, 0]), u1 : tId1/d[low, 1], u2 : tId2/d[hi, 1], Is : Is / (u1*u2)**0.4, /* N を漸近させる */ tId1 : fn(d[low, 0]), tId2 : fn(d[hi, 0]), u1 : tId1/d[low, 1], u2 : tId2/d[hi, 1], N : N * (u2/u1)**0.2, /* 終了? */ if abs(1 - u1) < 1e-6 and abs(1 - u2) < 1e-6 then (f : 1, i : 50) /* else print(i, "Is=", Is, "N", N) */ ) $ if f # 1 then error("") $ fpprec : 6 $ print("Is=", Is, "N=", N, "Id1=", tId1, "Id2=", tId2) $ fpprec : 16 $ Rs : 2.1 $ /* 適当な初期値 */ /* 直列抵抗を考慮した Vd = f(Id) モデル式 */ fvd(Id, Is, N, Rs) := log(Id/Is + 1)*N*VT + Id*Rs $ /* 最小二乗誤差。 Id の変化範囲は大きいので、比を計算している。(ln(Id) と同等) */ mmse(Is, N, Rs) := ( sum : 0, for i : 0 while i < 7 do ( s : fvd(d[i,1], Is, N, Rs)/d[i,0] - 1, /* print(d[i,1], d[i,0], "s", s), */ sum : sum + s**2 ), sum ) $ /* Is, N, Rs のフィット */ fct : 1e-3 $ fcu : float(1 / 12) $ for i : 0 while i < 50 do ( /* print(i, "Is, N, Rs", Is, N, Rs), */ u0 : mmse(Is, N, Rs), u1 : mmse((1 + fct)*Is, N, Rs)/u0, u2 : mmse(Is, (1 + fct)*N, Rs)/u0, u3 : mmse(Is, N, (1 + fct)*Rs)/u0, /* print("u0=", u0), */ /* print("u1 .. u3", u1, u2, u3), */ Is : Is / u1**fcu, N : N / u2**fcu, Rs : Rs / u3**fcu, 0 ) $ fpprec : 5 $ print("u0=", u0, ": Is=", Is, "N=", N, "Rs=", Rs) $ fpprec : 16 $