李 奇, 马晓波, 曹志杰, 马 玲, 杜全忠, 撒 强
(宁夏大学 物理学院, 宁夏 银川 750021)
学习半导体PN结的物理特性是《半导体物理学》相关知识的重要内容.准确、直观地表征半导体PN结的电流-电压关系及实现玻尔兹曼常数的测定,是半导体器件研究和教学的重要内容[1].实验中,测量流过PN结的正向电流I和PN结两端的电压U,通过描点法绘制I-U特性曲线.然后,基于最小二乘法原理,对实验数据进行数学拟合,得到I与U的非线性关系表达式,并由此计算出玻尔兹曼常数.该实验具有操作简单、测量精确度高、反映物理现象显著及表达物理思维逻辑清晰的特点,是对本科生进行实验技能训练的必修基础课程.为了保证实验的精确度,通常每隔0.01 V读取1个数据点.由于实际测量数据点为20~30个,且实验数据普遍使用计算器处理,易引入误差.针对这一问题,苏萍等基于MATLAB对PN结特性实验数据进行处理[2],得到较好的实验结果.但MATLAB对主机性能的要求相对较高,且无可视化界面客户端.虽然VB可实现可视化界面客户端,但其编程语言不具普适性,应用范围较窄[3].吴世宝等基于Python编译PN结特性实验数据处理器[4],通过调用封装好的函数,可方便、快捷地根据实验数据进行绘图、曲线拟合等.然而,该程序仅可用于一阶多项式拟合,无法拟合出更高阶次的多项式.基于此,笔者使用Python编程,通过Numpy模块实现多项式拟合,再通过Matplotlib模块完成可视化绘图.
针对PN结物理特性探究实验的目的是,当PN结处于正向偏置时,研究通过PN结的正向电流I与PN结两端电压U的关系[5].由《半导体物理学》可知,I,U满足克莱默方程,即:
I=I0[exp(eU/KT)-1],
(1)
式中:I0为PN结正向偏置时的反向饱和电流,且在温度恒定时为常数[6];T为实验时热力学温度;e为电子电荷量.当在常温(即300K)条件下,KT/e=0.026V,即eeU/KT≥1,则(1)式可简化为
I=I0[exp(eU/KT)].
(2)
由(2)式可知,I与U呈指数关系[7].由于指数函数的计算较复杂,计算量较大且易引入误差,降低了拟合结果的准确性.对(2)式等号两边作简单调整并同时取对数,(2)式可简化为
lnI-lnI0=eU/KT.
(3)
由(3)式可知,lnI与U呈一阶线性关系.基于此,可先将实验中测得通过PN结的正向电流进行运算,得到输入值x,其中
x=lnI.
(4)
将PN结两端电压U记录为输入值y.通过构造样本值x对应的样本输入矩阵X,根据最小二乘法公式计算出对应的系数矩阵B,随后将系数矩阵代入Y=XB计算得到输入值y对应的拟合值,并得到拟合直线的斜率a.根据a,可得到玻尔兹曼常数的测定值k′,其中k′与a的关系:
k′=ea/T.
(5)
比较玻尔兹曼常数测定值与标准值,即可得到实验误差.
为避免因使用普通计算器而引入的误差,并减少运算量,笔者采用Python编程[8],实现了I-U数据的拟合和曲线绘制.代码由多项式拟合部分和可视化绘图部分组成.第一部分程序实现数据的拟合,通过Numpy模块实现多项式拟合.在终端输入x和y,并选择多项式阶数,基于最小二乘法原理,通过Numpy模块中封装的函数值计算得到x和y各自对应的拟合值x_fit和y_fit(图1).
图1 终端输入
通过Matplotlib模块实现可视化绘图.在终端输入I和U(表1),修改相关参数并运行程序,可见I与U呈指数关系(图2).通过Mypolyfit函数拟合实验数据I与U.此外,Mypolyfit函数提供多项式拟合的阶数选择,当多项式阶数为1时,可在绘图界面拟合出直线的表达式,由此可求得直线的斜率.图中将输入值和拟合曲线同时呈现,以便对照是否符合最小二乘法的拟合特征(图3).
图2 I-U散点图
图3 绘图界面
由图3可知,拟合所得的数据点均匀分布于直线上及其两侧,可见该程序的数据拟合结果符合最小二乘法基本原理.根据数据拟合结果和(5)式,计算出玻尔兹曼常数k′的测定值为1.433×1023,与玻尔兹曼标准值1.381×1023对比,得到实验误差为3.77%,可见数据拟合结果较精确.
import numpy as np
import matplotlib.pyplot as plt
def mypolyfit(x, y, order=2):
"""这是一个最小二乘多项式拟合"""
# x,y是需要拟合的数据点, order是多项式的阶次
n = len(x)
X = np.zeros([order+1, n])
# 构造矩阵X0
for i in range(n):
for j in range(order+1):
X[j, i] = x[i]**(order - j)
X = X.T
A = np.linalg.inv(np.dot
(X.T, X)).dot(X.T).dot(y.T) # 系数矩阵A
num = 100 # 返回插值后的100个数据点
x_fit = np.linspace(x[0], x[-1], num)
y_fit = np.zeros([num, 1])
for i in range(num): # 拟合后的y_fit
for j in range(order+1):
y_fit[i] += A[j]*x_fit[i]**(order-j)
print(A)
return (x_fit, y_fit, A)
if __name__ == "__main__":
x, y = [], []
print("请按行输入数据点:(x,y),以end结束.")
while (True):
point = input()
if (point == ′end′):
break
(x0, y0) = eval(point)
x.append(x0)
y.append(y0)
x = np.array(x)
y = np.array(y)
order = int(input("请输入要拟合的阶次:"))
(x_fit, y_fit, weights) = mypolyfit(x, y, order)
fig = plt.figure()
ax = fig.add_subplot(111)
plt.rcParams[′font.sans-serif′] = [′MicrosoftYaHei′]
plt.plot(x, y, ′+′, x_fit, y_fit)
plt.title("最小二乘法——%s阶多项式拟合"% str(order))
plt.legend(["实际值","拟合值"])
plt.xlabel(′X′)
plt.ylabel(′Y′)
plt.grid()
plt.text(0.5, 0.5,"Y="+str(weights[0])[:4]+"X+"+str(weights[1])[:4], transform=ax.transAxes)#计算直线斜率并显示
plt.show()
针对PN结物理特性实验中数据处理繁琐费时、易引入误差的问题,基于Python语言,设计数据拟合方案,通过Numpy模块实现多项式拟合,通过Matplotlib模块实现可视化绘图.实验结果表明,该方法可快速便捷地拟合出相对精确的结果,避免较大的计算量和潜在的误差.Python语言具有功能强大、学习门槛较低及应用范围较广等特点.使用Python语言,既可锻炼本科生的编程能力,也能拓宽学生解决问题的思维,在对本科生进行科学实验方法和实验技能训练的过程中具有一定的应用和推广价值.