零. 写在前面
又到了半年一度的假期复盘。
本实验为CAU EXP192结课大作业(其实成绩占比还是以考试为主,本人只取得了A),但为了能顺利结课,有必要完成本次实验。该实验要求尽可能一人完成,若需要,也可以三人组队完成。
以下内容为笔者完成的实验报告,对于证明过程与证明结论,可能存在错误,其原因在于笔者发现使用Python求得的精确解与Multisim中模拟得到的实际情况存在误差(随着时间的推移有点大),但也可能是由于Multisim的精度问题(笔者尚未解决该问题,但因已结课便不再多想)。不过,该实验报告仍有借鉴意义,尤其是想拿A+的同学。
亲爱的读者,如果您能发现笔者证明过程的纰漏,望能通过评论或者邮箱的方式告知笔者(笔者的邮箱是:2506250214@qq.com),不胜感激。
一. 实验内容及要求(题目)
将0-5V 1KHz的方波变换为0-5V 1KHz线性度较好的三角波。
要求:
- 可使用的仿真元件有:信号发生器,示波器,直流电源,R,C
- 只能用积分、比例、求和电路组合设计
- 不能用滞回比…
- 参考电路图:
同时附上课堂抓拍内容[doge]:
二. 实验步骤及结果(使用Multisim仿真)
以下为电路图及示波器显示情况。具体元件参数均在电路图中体现,其中信号发生器设置频率1KHz,占空比50%,幅值2.5V,偏置2.5V,即与0~5V的1KHz方波等价。
三. 实验分析及源代码(理论推导过程)
import math
import matplotlib.pyplot as plt
def VO_VI1_END(Rf,V0,Rx): # 此半个周期输入电压为5V,初始电压为V0,返回值为半个周期结束时的电压
A1 = V0 + Rf/Rx*5
return A1*math.exp(-1/2)-Rf/Rx*5 # 指数函数的指数固定为-1/2,是由于已假定Rf*C为恒定值0.001
def VO_VI0_END(V0): # 此半个周期输入电压为0V,初始电压为V0,返回值为半个周期结束时的电压
return V0*math.exp(-1/2)
def Amplitude(Rf,R): # 迭代五次,得到的波形幅值近似于最终幅值
Vt1_0 = VO_VI1_END(Rf, 0, R) # 第一个半周期的初始电压为0
Vt1_1 = VO_VI0_END(Vt1_0) # 第二个半周期的初始电压为第一半周期结束时的电压
Vt2_0 = VO_VI1_END(Rf, Vt1_1, R) # 第三个半周期的初始电压为第二个半周期结束时的电压,以下同理
Vt2_1 = VO_VI0_END(Vt2_0)
Vt3_0 = VO_VI1_END(Rf, Vt2_1, R)
Vt3_1 = VO_VI0_END(Vt3_0)
Vt4_0 = VO_VI1_END(Rf, Vt3_1, R)
Vt4_1 = VO_VI0_END(Vt4_0)
Vt5_0 = VO_VI1_END(Rf, Vt4_1, R)
Vt5_1 = VO_VI0_END(Vt5_0)
return Vt5_1-Vt5_0 # 计算至第五个周期,该周期的波峰减去波谷即为近似的最终幅值
def Wave(Rf,R): # 根据Rf和R绘制示波器大致的波形图
time = [0,0.5,1,1.5,2,2.5,3,3.5,4,4.5,5]
voltage = []
Vt1_0 = VO_VI1_END(Rf, 0, R) # 第一个半周期的初始电压为0
Vt1_1 = VO_VI0_END(Vt1_0) # 第二个半周期的初始电压为第一半周期结束时的电压
Vt2_0 = VO_VI1_END(Rf, Vt1_1, R) # 第三个半周期的初始电压为第二个半周期结束时的电压,以下同理
Vt2_1 = VO_VI0_END(Vt2_0)
Vt3_0 = VO_VI1_END(Rf, Vt2_1, R)
Vt3_1 = VO_VI0_END(Vt3_0)
Vt4_0 = VO_VI1_END(Rf, Vt3_1, R)
Vt4_1 = VO_VI0_END(Vt4_0)
Vt5_0 = VO_VI1_END(Rf, Vt4_1, R)
Vt5_1 = VO_VI0_END(Vt5_0)
print("为使得最低电压为0,应将电压抬升 "+str(-Vt5_0)+"V")
voltage.append(0)
voltage.append(Vt1_0)
voltage.append(Vt1_1)
voltage.append(Vt2_0)
voltage.append(Vt2_1)
voltage.append(Vt3_0)
voltage.append(Vt3_1)
voltage.append(Vt4_0)
voltage.append(Vt4_1)
voltage.append(Vt5_0)
voltage.append(Vt5_1)
plt.plot(time,voltage)
plt.xlabel("time/ms")
plt.ylabel("voltage")
plt.title("Rough Waveform")
plt.grid()
plt.show()
Rf = float(1000000) # 首先假设Rf的初始值为1000k欧姆
C = 0.001/Rf # 使Rf*C满足特定关系
R_array = []
Amp_array = []
for i in range(100000,500000): # 对于1000k的Rf,R的值在100k至500k之间寻找
R_array.append(i)
Amp_array.append(Amplitude(Rf,i))
# plt.plot(R_array,Amp_array)
# plt.xlabel("R")
# plt.ylabel("Amplitude")
# plt.show() # 发现随着R的阻值上升,最终幅值呈单调递减
# 以下通过二分查找求解当Rf为1000k欧姆时最能符合题目要求的电阻R的值
# 注:此前已对R值遍历后并可视化,发现最终幅值随着R值的上升呈现单调递减形式,且大致值在0.25Rf附近,故为了降低时间复杂度,此处用二分查找寻求精确解
min = 1000000
flag = 0
a = 100000
b = 500000
while(math.fabs(Amplitude(Rf,a)-5)>0.001):
if(Amplitude(Rf,(a+b)/2)-5>0):
a = (a+b)/2
else:
b = (a+b)/2
print("在Rf=1000K欧姆时合适的R值为:"+str(a))
Wave(Rf,a)
运行结果如下:
所以可以得到,当Rf=1000k欧姆时,R=243k欧姆左右将得到接近于最好的结果,且为了使得电压幅值处在0~5V,此时需要抬升电压12.7V左右。而且可以得到更为一般的结论,即当满足Rf*C=0.001的条件时,由于迭代公式受到变量的影响只取决于R/Rf,故R的值可以根据Rf的值等比例放大,且该比值R/Rf =0.243左右拟合的情况最佳。