1.参考资料和电压采样电路
1.1 参考资料
https://www.ti.com.cn/cn/lit/ds/symlink/amc1311-q1.pdf?ts=1712853544543
https://www.ti.com.cn/cn/lit/ug/slau745/slau745.pdf?ts=1712880885313
https://www.ti.com/lit/ds/symlink/tlv6001.pdf?ts=1713028954999
1.2 电压采样电路
摘自Ti文档《AMC1311EVM Users Guide》,1.1章节中含有这篇文档的链接,为了方便说明,文中做了一些补充说明和假定,蒙特卡洛分析借用的采样电路见下图。
2.蒙特卡洛分析实现的过程
使用matlab实现蒙特卡洛分析的过程,其实说白了就是数学建模,利用数学表达式准确的表达出输出电压和输入电压的关系,在输出电压和输入电压之间的所有变量都可以认为是误差的来源,每个变量通常都有一个典型值和极大极小值,此时,利用随机数产生的机理将每个变量都用一个极大的数组去体现,最后利用这些相同长度的数组进行运算,生成的结果会以高斯分布的形式展现。
以1.2章节显示的电压采样电路为例,可以简要说明下建立数学表达式,为了方便处理,这里面我简化了一些内容,感兴趣的可以自行更新模型,文章最后也会贴上matlab代码。
VoutputA = Vin*R4/(R1+R2+R3+R4),这里考虑了电阻的误差。
VoutputB = ( VoutputA + ISO_OPA_offset_volt + ISO_OPA_offset_current * Para_Rsense ) * ISO_OPA_gain,Para_Rsense = R4*(R1+R2+R3)/(R1+R2+R3+R4)。这里考虑了隔离运放的偏置电压和偏置电流误差,另外还有电阻的误差。
VoutputC_ref = VDD2*(R8/(R6+R8)) + OPA2_offset_volt,VoutputC = VoutputB*(R9/R5) + VoutputC_ref - OPA1_offset_volt*(R9+R5)/R5。这里考虑了运放的偏置电压误差,VDD2电源的误差,另外还有电阻的误差,能力有限,这里做了一些简化处理,默认R10=R5,R9=R7,此外,删除了运放的偏置电流误差的影响。
3.蒙特卡洛分析仿真的结果展示
下图是校核用的,目的是排除程序出错导致结果不对
下图是输出的结果
4、matlab 代码
clear all;
clc
%% 参考文档
% https://www.ti.com.cn/cn/lit/ds/symlink/amc1311-q1.pdf?ts=1712853544543
% https://www.ti.com.cn/cn/lit/ug/slau745/slau745.pdf?ts=1712880885313
% https://www.ti.com/lit/ds/symlink/tlv6001.pdf?ts=1713028954999
%% 输入电压&仿真点数
Vin_min = 100;
Vin_max = 550;
Vin_step = 10;
Vin = Vin_min:Vin_step:Vin_max;
size_Vin = size(Vin);
num_mrnd = 1e6;
%% Vin-VoutputA变量输入
RsenseA_tol_per = 0.01;
RsenseA_typ = 500e3;
RsenseB_tol_per = 0.01;
RsenseB_typ = 10e3;
R1_typ = RsenseA_typ;
R2_typ = RsenseA_typ;
R3_typ = RsenseA_typ;
R4_typ = RsenseB_typ;
R1 = normrnd(RsenseA_typ,RsenseA_typ*RsenseA_tol_per/3,[1,num_mrnd]);
R2 = normrnd(RsenseA_typ,RsenseA_typ*RsenseA_tol_per/3,[1,num_mrnd]);
R3 = normrnd(RsenseA_typ,RsenseA_typ*RsenseA_tol_per/3,[1,num_mrnd]);
R4 = normrnd(RsenseB_typ,RsenseB_typ*RsenseB_tol_per/3,[1,num_mrnd]);
%% VoutputA-VoutputB
ISO_OPA_offset_volt_tol_value = 9.9e-3;
ISO_OPA_offset_volt_typ = 0;
ISO_OPA_offset_current_tol_value = 15e-9;
ISO_OPA_offset_current_typ = 0;
ISO_OPA_gain_tol_per = 0.01;
ISO_OPA_gain_typ = 1;
ISO_OPA_offset_volt = normrnd(ISO_OPA_offset_volt_typ,ISO_OPA_offset_volt_tol_value/3,[1,num_mrnd]);
ISO_OPA_offset_current = normrnd(ISO_OPA_offset_current_typ,ISO_OPA_offset_current_tol_value/3,[1,num_mrnd]);
ISO_OPA_gain = normrnd(ISO_OPA_gain_typ,ISO_OPA_gain_typ*ISO_OPA_gain_tol_per/3,[1,num_mrnd]);
%% VoutputB-VoutputC
OPA_offset_volt_tol_value = 4.5e-3;
OPA_offset_volt_typ = 0;
VDD2_typ = 5;
VDD2_tol_per = 0.01;
RsenseC_tol_per = 0.01;
RsenseC_typ = 10e3;
RsenseD_tol_per = 0.01;
RsenseD_typ = 1.1e3;
OPA1_offset_volt_typ = OPA_offset_volt_typ;
OPA2_offset_volt_typ = OPA_offset_volt_typ;
OPA1_offset_volt = normrnd(OPA_offset_volt_typ,OPA_offset_volt_tol_value/3,[1,num_mrnd]);
OPA2_offset_volt = normrnd(OPA_offset_volt_typ,OPA_offset_volt_tol_value/3,[1,num_mrnd]);
VDD2 = normrnd(VDD2_typ,VDD2_typ*VDD2_tol_per/3,[1,num_mrnd]);
R5_typ = RsenseC_typ;
R6_typ = RsenseC_typ;
R8_typ = RsenseD_typ;
R9_typ = RsenseC_typ;
R5 = normrnd(RsenseC_typ,RsenseC_typ*RsenseC_tol_per/3,[1,num_mrnd]);
R6 = normrnd(RsenseC_typ,RsenseC_typ*RsenseD_tol_per/3,[1,num_mrnd]);
R8 = normrnd(RsenseD_typ,RsenseD_typ*RsenseC_tol_per/3,[1,num_mrnd]);
R9 = normrnd(RsenseC_typ,RsenseC_typ*RsenseC_tol_per/3,[1,num_mrnd]);
%% 主函数
Vsense_outputA_typ = zeros(size_Vin(2),size_Vin(1));
Vsense_outputB_typ = zeros(size_Vin(2),size_Vin(1));
Vsense_outputC_typ = zeros(size_Vin(2),size_Vin(1));
Para_Rsense_typ = zeros(size_Vin(2),size_Vin(1));
Vsense_outputA = zeros(size_Vin(2),num_mrnd);
Vsense_outputB = zeros(size_Vin(2),num_mrnd);
Vsense_outputC = zeros(size_Vin(2),num_mrnd);
Para_Rsense = zeros(size_Vin(2),num_mrnd);
for i = 1:1:size_Vin(2)
[Vsense_outputA_typ(i),Para_Rsense_typ(i)] = Vsense_ratioA(Vin(i),R1_typ,R2_typ,R3_typ,R4_typ);
[Vsense_outputB_typ(i)] = Vsense_ratioB(Vsense_outputA_typ(i),Para_Rsense_typ(i),ISO_OPA_offset_volt_typ,ISO_OPA_offset_current_typ,ISO_OPA_gain_typ);
[Vsense_outputC_typ(i)] = Vsense_ratioC(Vsense_outputB_typ(i),OPA1_offset_volt_typ,R5_typ,R9_typ,VDD2_typ,R6_typ,R8_typ,OPA2_offset_volt_typ);
end
for i = 1:1:size_Vin(2)
for ii = 1:1:num_mrnd
[Vsense_outputA(i,ii),Para_Rsense(i,ii)] = Vsense_ratioA(Vin(i),R1(ii),R2(ii),R3(ii),R4(ii));
[Vsense_outputB(i,ii)] = Vsense_ratioB(Vsense_outputA(i,ii),Para_Rsense(i,ii),ISO_OPA_offset_volt(ii),ISO_OPA_offset_current(ii),ISO_OPA_gain(ii));
[Vsense_outputC(i,ii)] = Vsense_ratioC(Vsense_outputB(i,ii),OPA1_offset_volt(ii),R5(ii),R9(ii),VDD2(ii),R6(ii),R8(ii),OPA2_offset_volt(ii));
end
end
mu_outputC = zeros(size_Vin(2),size_Vin(1));
sigma_outputC = zeros(size_Vin(2),size_Vin(1));
min_outputC_3sigma = zeros(size_Vin(2),size_Vin(1));
max_outputC_3sigma = zeros(size_Vin(2),size_Vin(1));
delta_3sigma_percent = zeros(size_Vin(2),size_Vin(1));
for i = 1:1:size_Vin(2)
[mu_outputC(i),sigma_outputC(i)] = normfit(Vsense_outputC(i,:));
min_outputC_3sigma(i) = mu_outputC(i) - 3*sigma_outputC(i);
max_outputC_3sigma(i) = mu_outputC(i) + 3*sigma_outputC(i);
delta_3sigma_percent(i) = 3*sigma_outputC(i)/mu_outputC(i);
end
%% 数据校核&结果展示
figure;
plot(Vsense_outputC_typ,mu_outputC);
title('输出电压典型值VS均值')
xlabel('典型值');
ylabel('均值');
figure;
[f_inital,Vsense_outputC_inital] = ksdensity(Vsense_outputC(1,:));
plot(Vsense_outputC_inital,f_inital);
title('最低输入电压情况下输出电压分布情况');
str1 = '输出电压均值';
num1 = mu_outputC(1);
str2 = 'sigma';
num2 = sigma_outputC(1);
str_sum = sprintf('%s%d',str1,num1,str2,num2);
xlabel(str_sum);
ylabel('输出电压统计点数');
hold on
sigma1 = num1 + num2;
sigma1_nan = num1 - num2;
sigma2 = num1 + 2*num2;
sigma2_nan = num1 - 2*num2;
sigma3 = num1 + 3*num2;
sigma3_nan = num1 - 3*num2;
plot(sigma1,0,'o',sigma2,0,'o',sigma3,0,'o',sigma1_nan,0,'o',sigma2_nan,0,'o',sigma3_nan,0,'o');
figure;
[f_end,Vsense_outputC_end] = ksdensity(Vsense_outputC(size_Vin(2),:));
plot(Vsense_outputC_end,f_end);
title('最高输入电压情况下输出电压分布情况');
str1 = '输出电压均值';
num1 = mu_outputC(size_Vin(2));
str2 = 'sigma';
num2 = sigma_outputC(size_Vin(2));
str_sum = sprintf('%s%d',str1,num1,str2,num2);
xlabel(str_sum);
ylabel('输出电压统计点数');
hold on
sigma1 = num1 + num2;
sigma1_nan = num1 - num2;
sigma2 = num1 + 2*num2;
sigma2_nan = num1 - 2*num2;
sigma3 = num1 + 3*num2;
sigma3_nan = num1 - 3*num2;
plot(sigma1,0,'o',sigma2,0,'o',sigma3,0,'o',sigma1_nan,0,'o',sigma2_nan,0,'o',sigma3_nan,0,'o');
figure;
plot(Vin,delta_3sigma_percent*100);
title('输入电压 VS 3sigma误差')
xlabel('输入电压 V');
ylabel('3sigma误差 %');
%% 子函数
function [Vsense_outputA,Para_Rsense] = Vsense_ratioA(Vin,R1,R2,R3,R4)
Vsense_outputA = Vin*R4/(R1+R2+R3+R4);
Para_Rsense = R4*(R1+R2+R3)/(R1+R2+R3+R4);
end
function [Vsense_outputB] = Vsense_ratioB(Vsense_outputA,Para_Rsense,ISO_OPA_offset_volt,ISO_OPA_offset_current,ISO_OPA_gain)
Vsense_outputB = (Vsense_outputA+ISO_OPA_offset_volt+ISO_OPA_offset_current*Para_Rsense)*ISO_OPA_gain;
end
function [Vsense_outputC] = Vsense_ratioC(Vsense_outputB,OPA1_offset_volt,R5,R9,VDD2,R6,R8,OPA2_offset_volt)
Vsense_outputC_ref = VDD2*(R8/(R6+R8)) + OPA2_offset_volt;
Vsense_outputC = Vsense_outputB*(R9/R5) + Vsense_outputC_ref - OPA1_offset_volt*(R9+R5)/R5;
end