微带线计算工具

  #最新版的下载地址:MAC版本 http://files.cnblogs.com/files/hiramlee0534/ms_calc.zip
1
## -*- coding: utf-8 -* 2 #import logo_rc 3 import sys 4 import math 5 from PyQt4 import QtCore, QtGui, Qt, uic 6 from PyQt4.QtGui import * 7 from PyQt4.QtCore import * 8 import scipy.integrate as integrate 9 import scipy.special as special 10 qtCreatorFile = "E:emmicrostrip_calcaulator_leon.ui" # Enter file here. 11 Ui_MainWindow, QtBaseClass = uic.loadUiType(qtCreatorFile) 12 class MyApp(QtGui.QMainWindow, Ui_MainWindow): 13 def __init__(self): 14 QtGui.QMainWindow.__init__(self) 15 Ui_MainWindow.__init__(self) 16 QtGui.QWidget.__init__(self, parent=None) 17 #self.img_=QImage(self) 18 #self.img_.load('E:emmicrostrip_calc.png') 19 #图片显示 20 #self.label.setPixmap(QPixmap().fromImage(self.img_).scaled(QSize(240,120),Qt.KeepAspectRatio)) 21 #palette1 = QtGui.QPalette() 22 #palette1.setColor(self.backgroundRole(), QColor(192,253,123)) # 设置背景颜色 23 #palette1.setBrush(self.backgroundRole(), QtGui.QBrush(QtGui.QPixmap('E:emackground.png'))) # 设置背景图片 24 #self.setPalette(palette1) 25 #self.setAutoFillBackground(True) 26 self.setupUi(self) 27 self.pushButton_ms_analysis.setIcon(QIcon('E:\em\img\left.jpg')) 28 self.er = 0.0 29 self.h = 0.0 30 self.fc = 0.0 31 self.w = 0.0 32 self.l = 0.0 33 self.c = 2.99792458e8 34 self.fZ0 = 4.0*math.pi*1.0e-7*self.c 35 #self.test = 0.0 36 self.ms_dielectric_list = ['Air','Alumina','GaAs','Germanium','Indium phosphide','Silicon','RT/Duroid 5880','FR4'] 37 if len(self.ms_dielectric_list) > 0: 38 for dielectric in self.ms_dielectric_list: 39 #ser = serial.Serial(port[0]) 40 self.comboBox_ms_diel.addItem(dielectric) 41 self.comboBox_ms_diel.setCurrentIndex(6) 42 self.ms_dielconst_list = [1,9.8,12.9,16,12.4,11.9,2.16,4.6] 43 self.lineEdit_ms_er.setText('2.16') 44 self.ms_conductor_list = ['Silver','Copper','Gold','Aluminum'] 45 if len(self.ms_conductor_list) > 0: 46 for conductor in self.ms_conductor_list: 47 #ser = serial.Serial(port[0]) 48 self.comboBox_ms_conductor.addItem(conductor) 49 self.comboBox_ms_conductor.setCurrentIndex(1) 50 self.ms_conductivity_list =[6.14E+07,5.88E+07,4.1E+07,3.53E+07,1.47E+07] 51 self.ms_conductivity = self.ms_conductivity_list[1] 52 self.lineEdit_ms_conductivity.setText(str(self.ms_conductivity )) 53 self.ms_conductivity_unit_list = ['S/um','S/mm','S/cm','S/m'] 54 self.ms_conductivity_unit_scale_list = [1000000,1000,100,1] 55 if len(self.ms_conductivity_unit_list) > 0: 56 for unit in self.ms_conductivity_unit_list: 57 #ser = serial.Serial(port[0]) 58 self.comboBox_ms_cond_unit.addItem(unit) 59 self.comboBox_ms_cond_unit.setCurrentIndex(3) 60 self.unit_last = self.ms_conductivity_unit_scale_list[3] 61 self.ms_losstangent_list = [0,0.0005,0.0005,0.0005,0.0005,0.001,0.001,0.02] 62 self.lineEdit_ms_loss_tangent.setText(str(self.ms_losstangent_list[6])) 63 self.lineEdit_ms_H.setText(str(0.254)) 64 self.lineEdit_ms_T.setText(str(0.000)) 65 self.lineEdit_ms_Zc.setText(str(50)) 66 self.lineEdit_ms_fc.setText(str(5000.0)) 67 self.lineEdit_ms_el.setText(str(90.0)) 68 self.lineEdit_ms_L.setText(str(5.869)) 69 self.lineEdit_ms_W.setText(str(0.240)) 70 self.lineEdit_ms_mur.setText(str(1.000)) 71 self.lineEdit_ms_rough.setText(str(0.000)) 72 self.pushButton_calculate.clicked.connect(self.synthesis) 73 self.pushButton_ms_analysis.clicked.connect(self.ms_analysis) 74 self.pushButton_ms_synthesis.clicked.connect(self.ms_synthesis) 75 self.comboBox_ms_diel.currentIndexChanged.connect(self.dielectric_changed) 76 self.comboBox_ms_conductor.currentIndexChanged.connect(self.conductor_changed) 77 self.comboBox_ms_cond_unit.currentIndexChanged.connect(self.cond_unit_changed) 78 79 def dielectric_changed(self): 80 self.lineEdit_ms_er.setText(str(self.ms_dielconst_list[self.comboBox_ms_diel.currentIndex()])) 81 self.lineEdit_ms_loss_tangent.setText(str(self.ms_losstangent_list[self.comboBox_ms_diel.currentIndex()])) 82 def conductor_changed(self): 83 self.lineEdit_ms_conductivity.setText(str(self.ms_conductivity_list[self.comboBox_ms_conductor.currentIndex()] 84 /self.ms_conductivity_unit_scale_list[self.comboBox_ms_cond_unit.currentIndex()])) 85 self.ms_conductivity = self.ms_conductivity_list[self.comboBox_ms_conductor.currentIndex()] 86 def cond_unit_changed(self): 87 self.lineEdit_ms_conductivity.setText(str(float(self.lineEdit_ms_conductivity.text()) 88 *self.unit_last/self.ms_conductivity_unit_scale_list[self.comboBox_ms_cond_unit.currentIndex()])) 89 self.unit_last = self.ms_conductivity_unit_scale_list[self.comboBox_ms_cond_unit.currentIndex()] 90 def synthesis(self): 91 self.er = float(self.lineEdit_er.text()) 92 self.h = float(self.lineEdit_h.text()) 93 self.fc = float(self.lineEdit_fc.text()) 94 self.zin =float(self.lineEdit_Zin.text()) 95 self.w = self.c*1000.0/(2*self.fc*1e6)*math.pow(2.0/(self.er+1.0),0.5)#mm 96 self.ereff = (self.er+1.0)/2.0+(self.er-1.0)/2.0*math.pow(1+12*self.h/self.w,-0.5) 97 self.lambda_eff = self.c*1000/self.fc/1e6/math.sqrt(self.ereff)#mm 98 self.deltaL = self.h*0.412*(self.ereff+0.3)*(self.w/self.h+0.264)/(self.ereff-0.258)/(self.w/self.h+0.8)#mm 99 self.l = self.lambda_eff/2-2*self.deltaL #mm 100 #self.test = self.test + 1.0 101 self.lineEdit_w.setText(str(self.w)) 102 self.lineEdit_l.setText(str(self.l)) 103 k0 = 2.0*math.pi/(self.c/self.fc/1e6) 104 G1 = integrate.quad(lambda x: math.pow(math.sin(k0*self.w/2000*math.cos(x))/math.cos(x),2)*math.pow(math.sin(x),3), 0, math.pi) 105 G12 = integrate.quad(lambda x: math.pow(math.sin(k0*self.w/2000*math.cos(x))/math.cos(x),2)*special.j0(math.sin(x)*self.l/1000*k0)*math.pow(math.sin(x),3), 0, math.pi) 106 result = 1.0/(2.0*(G1[0]/(120*math.pow(math.pi,2))+G12[0]/(120*math.pow(math.pi,2)))) 107 self.y = math.acos(math.sqrt(self.zin/result))*self.l/math.pi 108 self.lineEdit_Rin.setText(str(result)) 109 self.lineEdit_y.setText(str(self.y)) 110 def ms_analysis(self): 111 self.ms_h = float(self.lineEdit_ms_H.text())/1.0e3 # substrate thickness 112 self.ms_w = float(self.lineEdit_ms_W.text())/1.0e3 # conductor width 113 self.ms_l = float(self.lineEdit_ms_L.text())/1.0e3 # conductor length 114 self.ms_er = float(self.lineEdit_ms_er.text()) # relative dielectric constant 115 self.ms_mur = float(self.lineEdit_ms_mur.text()) # relative permeability 116 self.ms_fc = float(self.lineEdit_ms_fc.text())*1e6 # frequency in Hz 117 rough = float(self.lineEdit_ms_rough.text())/1.0e3 118 tand = float(self.lineEdit_ms_loss_tangent.text()) # loss tangent of the dielectric 119 cond = float(self.lineEdit_ms_conductivity.text()) 120 mu = self.ms_mur*4*math.pi*1.0e-7 121 self.ms_t = float(self.lineEdit_ms_T.text())/1.0e3 122 U = self.ms_w/self.ms_h # ratio of trace width to substrate thickness 123 if self.ms_t > 0: 124 T = self.ms_t/self.ms_h #ratio of conductor thickness to substrate thickness 125 #(T/PI)*log(1.0 + 4.0*exp(1.0)/(T*pow(coth(sqrt(6.517*u)),2.0))) 126 U1 = U +(T*math.log(1.0+4.0*math.e/T/math.pow(1.0/math.tanh(math.sqrt(6.517*U)),2.0)))/math.pi # from Hammerstad and Jensen 127 # 0.5*(1.0 + 1.0/cosh(sqrt(er-1.0)))*deltau1 128 Ur = U +(U1-U)*(1.0+1.0/(math.cosh(math.sqrt(self.ms_er-1))))/2.0 # from Hammerstad and Jensen 129 else: 130 U1 = U 131 Ur = U 132 Y = self.ee_HandJ(Ur,self.ms_er) 133 Z0 =self.z0_HandJ(Ur)/math.sqrt(Y) 134 #ereff0 = Y*math.pow(Z01_U1/Z01_Ur,2) 135 ereff0 = Y*math.pow(self.z0_HandJ(U1)/self.z0_HandJ(Ur),2.0) 136 fn = self.ms_fc*self.ms_h/1e7 137 P1 = 0.27488 + (0.6315 + (0.525 / (math.pow((1 + 0.157*fn),20))) )*U - 0.065683*math.exp(-8.7513*U) 138 P2 = 0.33622*(1 - math.exp(-0.03442*self.ms_er)) 139 P3 = 0.0363*math.exp(-4.6*U)*(1 - math.exp(-math.pow((fn / 3.87),4.97))) 140 P4 = 1 + 2.751*( 1 - math.exp(-math.pow((self.ms_er/15.916),8))) 141 P = P1*P2*math.pow(((0.1844 + P3*P4)*10*fn),1.5763) 142 self.ms_ereff = (self.ms_er*P+ereff0)/(1+P) # equavlent ralative dielectric constant 143 self.ms_Zc = self.z_calc(self.ms_w,self.ms_h,self.ms_l,self.ms_t,self.ms_fc,self.ms_er) 144 z1 = 0.434907*((math.pow(self.ms_ereff,0.81) + 0.26)/(math.pow(self.ms_ereff,0.81) - 0.189))*(math.pow(U,0.8544) + 0.236)/(math.pow(U,0.8544) + 0.87); 145 z2 = 1 + (math.pow(U,0.371))/(2.358*self.ms_er + 1) 146 z3 = 1 + (0.5274*math.atan(0.084*(math.pow(U,(1.9413 / z2)))))/(math.pow(self.ms_ereff,0.9236)) 147 z4 = 1 + 0.0377*math.atan(0.067*(math.pow(U,1.456)))*(6 - 5*math.exp(0.036*(1-self.ms_er))) 148 z5 = 1 - 0.218*math.exp(-7.5*U) 149 deltal = self.ms_h * z1 * z3 * z5 / z4 150 v = self.c/math.sqrt(self.ms_ereff) 151 length = self.ms_l/(v/self.ms_fc) 152 # delay 153 delay = 1e9*self.ms_l/v 154 # dielectric losses 155 ld = math.pi*self.ms_fc/v*self.ms_er/self.ms_ereff*(self.ms_ereff-1)/(self.ms_er-1)*tand # unit in nepers/meter 156 ld = 20.0/math.log(10)*ld # unit in dB/meter 157 ld = ld * self.ms_l # unit in dB 158 # conduction losses 159 # skin depth in meters 160 skin_depth = math.sqrt(1/(math.pi*self.ms_fc*mu*cond)) 161 if skin_depth <= self.ms_t : 162 Z2 = self.z_calc(self.ms_w,self.ms_h,self.ms_l,self.ms_t,self.ms_fc,1) 163 Z1 = self.z_calc(self.ms_w-skin_depth,self.ms_h+skin_depth,self.ms_l,self.ms_t-skin_depth,self.ms_fc,1) 164 # conduction losser 165 lc = math.pi*self.ms_fc/self.c*(Z1-Z2)/self.ms_Zc 166 elif self.ms_t > 0 : 167 #resistance per meter = 1/(Area*conductivity) 168 res = 1/(self.ms_w*self.ms_t*cond) 169 #conduction losses, nepers per meter 170 lc = res/(2.0*self.ms_Zc) 171 skin_depth = self.ms_t 172 else: 173 lc = 0 174 lc = 20.0/math.log(10)*lc 175 lc = lc * self.ms_l 176 lc = lc * (1.0+2.0/math.pi*math.atan(1.4*math.pow(rough/skin_depth,2))) 177 loss = ld + lc 178 self.ms_k0 = 2*math.pi/self.c*self.ms_fc 179 self.ms_beta = self.ms_k0*math.sqrt(self.ms_ereff) 180 self.ms_el = math.sqrt(self.ms_ereff)*self.ms_k0*self.ms_l/1000/math.pi*180.0 181 self.ms_el = 360*length 182 self.lineEdit_ms_Zc.setText(str(self.ms_Zc)) 183 self.lineEdit_ms_ereff.setText(str(self.ms_ereff)) 184 self.lineEdit_ms_el.setText(str(self.ms_el)) 185 self.lineEdit_ms_beta.setText(str(self.ms_beta)) 186 self.lineEdit_ms_loss.setText(str(loss)) 187 self.label_delay.setText('delay = '+str(delay)+' ns') 188 self.label_skin_depth.setText('skin depth = '+str(skin_depth)+' m') 189 def z0_HandJ(self,u): 190 LIGHTSPEED = 2.99792458e8 191 FREESPACEZ0 = 4.0*math.pi*1.0e-7*LIGHTSPEED 192 # from Hammerstad and Jensen. 'u' is the normalized width 193 F = 6.0 + (2.0*math.pi - 6.0)*math.exp(-1*math.pow((30.666/u),0.7528)) 194 # from Hammerstad and Jensen 195 z01 = (FREESPACEZ0/(2*math.pi))*math.log(F/u + math.sqrt(1.0 + math.pow((2/u),2.0))) 196 return z01 197 def ee_HandJ(self,u,er): 198 #Au = 1.0 + (1.0/49.0)*math.log(math.pow(Ur,4.0) + math.pow(Ur/52.0,2.0)/(math.pow(Ur,4.0)+0.432))+ (1.0/18.7)*math.log(1.0+ math.pow(Ur/18.1,3.0)) 199 A = 1.0 + (1.0/49.0)*math.log((math.pow(u,4.0) + math.pow((u/52.0),2.0))/(math.pow(u,4.0) + 0.432)) 200 + (1.0/18.7)*math.log(1.0 + math.pow((u/18.1),3.0)) 201 #Ber = 0.564*math.pow((er-0.9)/(er+3),0.053) 202 B = 0.564*math.pow(((er-0.9)/(er+3.0)),0.053) 203 #Y = (er+1.0)/2.0+(er-1.0)/2.0*math.pow(1+10.0/Ur,-(A*B)) 204 Y= (er+1.0)/2.0 + ((er-1.0)/2.0)*math.pow((1.0 + 10.0/u),(-A*B)) 205 return Y 206 def z_calc(self,w,h,l,t,fc,er): 207 #fn = fc*h/1e6 208 U = w/h # ratio of trace width to substrate thickness 209 if t > 0: 210 T = t/h #ratio of conductor thickness to substrate thickness 211 #(T/PI)*log(1.0 + 4.0*exp(1.0)/(T*pow(coth(sqrt(6.517*u)),2.0))) 212 U1 = U +(T*math.log(1.0+4.0*math.e/T/math.pow(1.0/math.tanh(math.sqrt(6.517*U)),2.0)))/math.pi # from Hammerstad and Jensen 213 # 0.5*(1.0 + 1.0/cosh(sqrt(er-1.0)))*deltau1 214 Ur = U +(U1-U)*(1.0+1.0/(math.cosh(math.sqrt(er-1))))/2.0 # from Hammerstad and Jensen 215 else: 216 U1 = U 217 Ur = U 218 Y = self.ee_HandJ(Ur,er) 219 Z0 =self.z0_HandJ(Ur)/math.sqrt(Y) 220 #ereff0 = Y*math.pow(Z01_U1/Z01_Ur,2) 221 ereff0 = Y*math.pow(self.z0_HandJ(U1)/self.z0_HandJ(Ur),2.0) 222 fn = fc*h/1e7 223 P1 = 0.27488 + (0.6315 + (0.525 / (math.pow((1 + 0.157*fn),20))) )*U - 0.065683*math.exp(-8.7513*U) 224 P2 = 0.33622*(1 - math.exp(-0.03442*er)) 225 P3 = 0.0363*math.exp(-4.6*U)*(1 - math.exp(-math.pow((fn / 3.87),4.97))) 226 P4 = 1 + 2.751*( 1 - math.exp(-math.pow((er/15.916),8))) 227 P = P1*P2*math.pow(((0.1844 + P3*P4)*10*fn),1.5763) 228 ereff = (er*P+ereff0)/(1+P) # equavlent ralative dielectric constant 229 #self.ms_Zc = Z0*math.pow(ereff0/self.ms_ereff,0.5)*(self.ms_ereff-1)/(ereff0-1) 230 fn = fc*h/1e6 231 R1 = 0.03891*(math.pow(er,1.4)) 232 R2 = 0.267*(math.pow(U,7.0)) 233 R3 = 4.766*math.exp(-3.228*(math.pow(U,0.641))) 234 R4 = 0.016 + math.pow((0.0514*er),4.524) 235 R5 = math.pow((fn/28.843),12.0) 236 R6 = 22.20*(math.pow(U,1.92)) 237 R7 = 1.206 - 0.3144*math.exp(-R1)*(1 - math.exp(-R2)) 238 R8 = 1.0 + 1.275*(1.0 - math.exp(-0.004625*R3*math.pow(er,1.674)*math.pow(fn/18.365,2.745))) 239 R9 = (5.086*R4*R5/(0.3838 + 0.386*R4))*(math.exp(-R6)/(1 + 1.2992*R5)) 240 R9 = R9 * (math.pow((er-1),6))/(1 + 10*math.pow((er-1),6)) 241 R10 = 0.00044*(math.pow(er,2.136)) + 0.0184 242 R11 = (math.pow((fn/19.47),6))/(1 + 0.0962*(math.pow((fn/19.47),6))) 243 R12 = 1 / (1 + 0.00245*U*U) 244 R13 = 0.9408*(math.pow( ereff,R8)) - 0.9603 245 R14 = (0.9408 - R9)*(math.pow(ereff0,R8))-0.9603 246 R15 = 0.707*R10*(math.pow((fn/12.3),1.097)) 247 R16 = 1 + 0.0503*er*er*R11*(1 - math.exp(-(math.pow((U/15),6)))) 248 R17 = R7*(1 - 1.1241*(R12/R16)*math.exp(-0.026*(math.pow(fn,1.15656))-R15)) 249 Zc = Z0*(math.pow((R13/R14),R17))# characteristic impedance 250 return Zc 251 def er_eff_calc(self,w,h,t,fc,er): 252 #fn = fc*h/1e6 253 U = w/h # ratio of trace width to substrate thickness 254 if t > 0: 255 T = t/h #ratio of conductor thickness to substrate thickness 256 #(T/PI)*log(1.0 + 4.0*exp(1.0)/(T*pow(coth(sqrt(6.517*u)),2.0))) 257 U1 = U +(T*math.log(1.0+4.0*math.e/T/math.pow(1.0/math.tanh(math.sqrt(6.517*U)),2.0)))/math.pi # from Hammerstad and Jensen 258 # 0.5*(1.0 + 1.0/cosh(sqrt(er-1.0)))*deltau1 259 Ur = U +(U1-U)*(1.0+1.0/(math.cosh(math.sqrt(er-1))))/2.0 # from Hammerstad and Jensen 260 else: 261 U1 = U 262 Ur = U 263 Y = self.ee_HandJ(Ur,er) 264 Z0 =self.z0_HandJ(Ur)/math.sqrt(Y) 265 #ereff0 = Y*math.pow(Z01_U1/Z01_Ur,2) 266 ereff0 = Y*math.pow(self.z0_HandJ(U1)/self.z0_HandJ(Ur),2.0) 267 fn = fc*h/1e7 268 P1 = 0.27488 + (0.6315 + (0.525 / (math.pow((1 + 0.157*fn),20))) )*U - 0.065683*math.exp(-8.7513*U) 269 P2 = 0.33622*(1 - math.exp(-0.03442*er)) 270 P3 = 0.0363*math.exp(-4.6*U)*(1 - math.exp(-math.pow((fn / 3.87),4.97))) 271 P4 = 1 + 2.751*( 1 - math.exp(-math.pow((er/15.916),8))) 272 P = P1*P2*math.pow(((0.1844 + P3*P4)*10*fn),1.5763) 273 er_eff = (er*P+ereff0)/(1+P)# equavlent ralative dielectric constant 274 return er_eff 275 def ms_synthesis(self): 276 Zc = float(self.lineEdit_ms_Zc.text()) 277 fc = float(self.lineEdit_ms_fc.text())*1e6 278 er = float(self.lineEdit_ms_er.text()) 279 h = float(self.lineEdit_ms_H.text())/1e3 280 el = float(self.lineEdit_ms_el.text()) 281 t = float(self.lineEdit_ms_T.text())/1.0e3 282 # temp value for l used while finding w 283 lx = 1000*25.4e-6 284 wmin = 0.01*25.4e-6 285 wmax = 499.0*25.4e-6 286 #impedance convergence tolerance (ohms) 287 abstol = 1e-6 288 reltol = 0.1e-6 289 maxiters = 50 290 A = ((er - 1)/(er + 1)) * (0.226 + 0.121/er) + (math.pi/377.0)*math.sqrt(2*(er+1))*Zc; 291 w_h = 4/(0.5*math.exp(A) - math.exp(-A)) 292 if w_h > 2.0 : 293 B = math.pi*377.0/(2*Zc*math.sqrt(er)) 294 w_h = (2/math.pi)*(B - 1 - math.log(2*B - 1) + ((er-1)/(2*er))*(math.log(B-1) + 0.293 - 0.517/er)) 295 wx = h * w_h 296 if wx >= wmax: 297 wx = 0.95*wmax 298 if wx <= wmin: 299 wx = wmin 300 wold = 1.01*wx 301 Zold = self.z_calc(wold,h,lx,t,fc,er) 302 if Zold < Zc: 303 wmax = wold 304 else: 305 wmin = wold 306 iters = 0 307 done = 0 308 while done == 0: 309 iters = iters + 1 310 Z0 = self.z_calc(wx,h,lx,t,fc,er) 311 if Z0 < Zc: 312 wmax = wx 313 else: 314 wmin = wx 315 if abs(Z0-Zc) < abstol: 316 done = 1 317 elif abs(wx-wold) < reltol: 318 done = 1 319 elif iters >= maxiters : 320 done = 1 321 else: 322 dzdw = (Z0 -Zold)/(wx-wold) 323 wold = wx 324 Zold = Z0 325 wx = wx -(Z0-Zc)/dzdw 326 if (wx > wmax) |(wx < wmin): 327 wx = (wmin+ wmax)/2.0 328 er_eff = self.er_eff_calc(wx,h,t,fc,er) 329 v = self.c/math.sqrt(er_eff) 330 l = el/360.0*v/fc; 331 self.lineEdit_ms_W.setText(str(wx*1.0e3)) 332 self.lineEdit_ms_ereff.setText(str(er_eff)) 333 self.lineEdit_ms_L.setText(str(l*1.0e3)) 334 if __name__ == "__main__": 335 app = QtGui.QApplication(sys.argv) 336 window = MyApp() 337 window.setWindowOpacity(1) 338 #window.setWindowFlags(Qt.Qt.FramelessWindowHint) 339 #window.setWindowFlags(Qt.Qt.WindowTitleHint) 340 window.show() 341 sys.exit(app.exec_())

OPTIMISM, PASSION & HARDWORK
原文地址:https://www.cnblogs.com/hiramlee0534/p/6263104.html