m24h作者
1年1个月前修改于 1年1个月前IP:上海
947175
2楼

用python做了个类似VDMOSTool的小工具 可以对转移特征曲线和电容做一些多点拟合 因为有程序且有规划求解 所以Cgd的a值也多点逼近出来(但如果只给两点 则还是用默认的1)

.... 现在的代码框怎么这样了 失望 如果有缩进问题 需要自己解决了

#!/usr/bin/python3

import math

import tkinter as tk

import tkinter.ttk as ttk

from tkinter import messagebox

from scipy.optimize import minimize

class Vdmos:

def init(self, master=None, data_pool=None):

# build ui

self.main = XXXXXXXXXXXX(master)

self.main.configure(cursor="arrow")

self.main.overrideredirect("false")

self.main.resizable(True, True)

self.main.title("VDMOS")

self.main.geometry('+%d+100'%((self.main.winfo_screenwidth()-600)/2))

validatefloat = (self.main.register(self.validate_float), "%P")

frame_1 = ttk.Frame(self.main)

frame_1.configure(height=200)

notebook_1 = ttk.Notebook(frame_1)

frame_2 = ttk.Frame(notebook_1)

label_1 = ttk.Label(frame_2)

label_1.configure(justify="right", text='Vto(V)')

label_1.grid(column=0, row=0, sticky="e")

self.vto = ttk.Entry(frame_2)

self.vto.configure(

justify="right",

validate="key",

validatecommand=_validate_float,

width=10)

self.vto.grid(column=1, columnspan=2, row=0, sticky="w")

label_4 = ttk.Label(frame_2)

label_4.configure(

anchor="ne",

justify="right",

text='Vgs(V)',

width=10)

label_4.grid(column=0, row=1, sticky="e")

label_5 = ttk.Label(frame_2)

label_5.configure(justify="right", text='Vds(V)')

label_5.grid(column=1, row=1, sticky="e")

label_6 = ttk.Label(frame_2)

label_6.configure(justify="right", text='Id(A)')

label_6.grid(column=2, row=1, sticky="e")

self.vgs_vds_id = []

for i in range(8):

self.vgs_vds_id.append((ttk.Entry(frame_2), ttk.Entry(frame_2), ttk.Entry(frame_2)))

for j in range(3):

self.vgs_vds_id[i][j].configure(

justify="right",

validate="key",

validatecommand=_validate_float,

width=10)

self.vgs_vds_id[i][j].grid(column=j, row=i+2)

notebook_1.add(frame_2, text='Basic')

frame_4 = ttk.Frame(notebook_1)

frame_4.configure(height=200, width=200)

label_2 = ttk.Label(frame_4)

label_2.configure(text='Vj(V)')

label_2.grid(column=0, row=0, sticky="e")

self.vj = ttk.Entry(frame_4)

self.vj.configure(

justify="right",

validate="key",

validatecommand=_validate_float,

width=10)

self.vj.grid(column=1, columnspan=3, row=0, sticky="w")

label_7 = ttk.Label(frame_4)

label_7.configure(text='Vds(V)')

label_7.grid(column=0, row=1, sticky="e")

label_8 = ttk.Label(frame_4)

label_8.configure(text='Ciss(pF)')

label_8.grid(column=1, row=1, sticky="e")

label_9 = ttk.Label(frame_4)

label_9.configure(text='Coss(pF)')

label_9.grid(column=2, row=1, sticky="e")

label_10 = ttk.Label(frame_4)

label_10.configure(text='Crss(pF)')

label_10.grid(column=3, row=1, sticky="e")

self.vds_ciss_coss_crss = []

for i in range(8):

self.vds_ciss_coss_crss.append((ttk.Entry(frame_4), ttk.Entry(frame_4), ttk.Entry(frame_4), ttk.Entry(frame_4)))

for j in range(4):

self.vds_ciss_coss_crss[i][j].configure(

justify="right",

validate="key",

validatecommand=_validate_float,

width=10)

self.vds_ciss_coss_crss[i][j].grid(column=j, row=i+2)

self.vds_ciss_coss_crss[0][0].insert(0, "0")

self.vds_ciss_coss_crss[0][0].configure(state='disabled')

notebook_1.add(frame_4, text='Cap')

notebook_1.pack(expand=True, fill="x", side="top")

frame_1.pack(side="top")

frame_5 = ttk.Frame(self.main)

self.result = tk.Text(frame_5, name="result")

self.result.configure(

borderwidth=1,

height=9,

relief="flat",

setgrid=False,

state="disabled",

undo=False,

width=30)

self.result.pack(

anchor="w",

expand=True,

fill="x",

ipadx=2,

padx=5,

side="left")

button_1 = ttk.Button(frame_5)

button_1.configure(text='Resolve')

button_1.pack(side="top")

button_1.configure(command=self.resolve)

button_2 = ttk.Button(frame_5, name="button_exit")

button_2.configure(text='Exit')

button_2.pack(side="top")

button_2.configure(command=exit)

frame_5.pack(anchor="w", side="top")

# Main widget

self.mainwindow = self.main

def run(self):

self.mainwindow.mainloop()

def validate_float(self, p_entry_value):

p_entry_value = p_entry_value.replace('.','',1)

return p_entry_value=='' or p_entry_value.isdigit()

@staticmethod

def calc_id(vgs, vds, vto, kp, lamb):

return 0 if vgs<vto else \

kp*(1+lamb*vds)*(vgs-vto-vds/2)*vds if vds<vgs-vto else \

kp*(1+lamb*vds)*(vgs-vto)*(vgs-vto)/2

@staticmethod

def calc_cgd(vds, a, cgdmin, cgdmax):

return (cgdmax*math.pi/2+cgdmin-(cgdmax-cgdmin)*math.atan(a*vds))/(1+math.pi/2)

@staticmethod

def calc_cds(vds, vj, cjo, m):

return cjo/math.pow(1+vds/vj, m)

def resolve(self):

self.result.configure(state='normal')

self.result.delete("1.0", tk.END)

self.result.insert(tk.END, ".model <name> VDMOS\n")

try:

# get vto, kp, lambda

vgs_vds_id = tuple(map(lambda x:tuple(map(lambda y:float(y.get()), x)),

filter(lambda z:all(map(lambda t:t.get()!='', z)),

self.vgs_vds_id)))

if self.vto.get()=='' and len(vgs_vds_id)>=3:

vto_kp_lambda=[0., 0., 0.]

solution = minimize(lambda x:sum(map(lambda y:(Vdmos.calc_id(y[0], y[1], x[0], x[1], x[2])-y[2])**2, vgs_vds_id)),

vto_kp_lambda, bounds=((0, None),(0,None),(0,None)))

if solution.success:

self.result.insert(tk.END, f'+ vto={solution.x[0]:10.4e} kp={solution.x[1]:10.4e} lambda={solution.x[2]:10.4e}\n')

elif self.vto.get()!='' and len(vgs_vds_id)>=2:

vto=float(self.vto.get())

solution = minimize(lambda x:sum(map(lambda y:(Vdmos.calc_id(y[0], y[1], vto, x[0], x[1])-y[2])**2, vgs_vds_id)),

(0., 0.), bounds=((0, None),(0,None)))

if solution.success:

self.result.insert(tk.END, f'+ vto={vto:10.4e} kp={solution.x[0]:10.4e} lambda={solution.x[1]:10.4e}\n')

# get cgd

vds_crss = tuple(map(lambda x: (float(x[0].get()), float(x[3].get())),

filter(lambda z:z[0].get()!="" and z[3].get()!="", self.vds_ciss_coss_crss)))

a_cgdmin_cgdmax = None

if len(vds_crss)>=3:

solution = minimize(lambda x:sum(map(lambda y:(Vdmos.calc_cgd(y[0], x[0], x[1], x[2])-y[1])**2, vds_crss)),

(1., 0., 0.), bounds=((0, None),(0, None),(0,None)))

if solution.success:

a_cgdmin_cgdmax = solution.x

elif len(vds_crss)>=2:

solution = minimize(lambda x:sum(map(lambda y:(Vdmos.calc_cgd(y[0], 1.0, x[0], x[1])-y[1])**2, vds_crss)),

(0., 0.), bounds=((0, None),(0, None)))

if solution.success:

a_cgdmin_cgdmax = (1.0, *solution.x)

elif len(vds_crss)>=1:

a_cgdmin_cgdmax = (1.0, vds_crss[0][1], vds_crss[0][1])

if a_cgdmin_cgdmax is not None:

self.result.insert(tk.END, f'+ a={a_cgdmin_cgdmax[0]:10.4e} cgdmin={a_cgdmin_cgdmax[1]/1e12:10.4e} cgdmax={a_cgdmin_cgdmax[2]/1e12:10.4e}\n')

# get cgs

vds_ciss = tuple(map(lambda x: (float(x[0].get()), float(x[1].get())),

filter(lambda z:z[0].get()!="" and z[1].get()!="", self.vds_ciss_coss_crss)))

if len(vds_ciss)>=1:

if a_cgdmin_cgdmax is not None:

cgs = max(map(lambda x:x[1]-Vdmos.calc_cgd(x[0], *a_cgdmin_cgdmax), vds_ciss))

else:

cgs = max(map(lambda x:x[1], vds_ciss))

self.result.insert(tk.END, f'+ cgs={cgs/1e12:10.4e}\n')

# get cds

vds_cds = tuple(map(lambda x: (float(x[0].get()), float(x[2].get())),

filter(lambda z:z[0].get()!="" and z[2].get()!="", self.vds_ciss_coss_crss)))

if a_cgdmin_cgdmax is not None:

vds_cds = tuple(map(lambda x: (x[0], x[1]-Vdmos.calc_cgd(x[0], *a_cgdmin_cgdmax)), vds_cds))

if self.vj.get()=='' and len(vds_cds)>=3:

solution = minimize(lambda x:sum(map(lambda y:(Vdmos.calc_cds(y[0], x[0], x[1], x[2])-y[1])**2, vds_cds)),

(0., 0., 0.), bounds=((0.2, 2),(0, None),(0, None)))

if solution.success:

self.result.insert(tk.END, f'+ vj={solution.x[0]:10.4e} cjo={solution.x[1]/1e12:10.4e} m={solution.x[2]:10.4e}\n')

elif self.vj.get()!='' and len(vds_cds)>=2:

vj = float(self.vj.get())

solution = minimize(lambda x:sum(map(lambda y:(Vdmos.calc_cds(y[0], vj, x[0], x[1])-y[1])**2, vds_cds)),

(0., 0.), bounds=((0, None),(0, None)))

if solution.success:

self.result.insert(tk.END, f'+ vj={vj:10.4e} cjo={solution.x[0]/1e12:10.4e} m={solution.x[1]:10.4e}\n')

except Exception as e:

messagebox.showinfo("Exception", e)

self.result.configure(state='disabled')

if name == "__main__":

app = Vdmos()

XXXXXXXXXXXXXX()


评论
文号 / 947175

千古风流
名片专栏发私信
学术分 1
总主题 68 帖总回复 1007 楼拥有证书:进士 学者 机友
注册于 2020/01/22 18:44:43最后登录 2026/10/31 00:16:32
主体类型:个人
所属领域:无
认证方式:手机号
IP归属地:上海

个人简介

个人开源项目: m24h.github.io

笔记
{{note.content}}
{{n.user.username}}
{{fromNow(n.toc)}} {{n.status === noteStatus.disabled ? "已屏蔽" : ""}} {{n.status === noteStatus.unknown ? "正在审核" : ""}} {{n.status === noteStatus.deleted ? '已删除' : ''}}
  • 编辑
  • 删除
  • {{n.status === 'disabled' ? "解除屏蔽" : "屏蔽" }}
我也是有底线的