- 使用 Spring Initializr 创建 Spring Boot 应用程序
- 在Spring Boot中配置Cassandra
- 在 Spring Boot 上配置 Tomcat 连接池
- 将Camel消息路由到嵌入WildFly的Artemis上
在使用PSIM软件仿真开关电源时,大多数都是模拟电路,纯数字电路的仿真很少。无意间发现了在PSIM 2021版本中有官方的数字控制BUCK电路仿真。电路使用简单C模块编写的代码来控制电路。
由于下载的2021版是演示版,不能直接仿真,为了能够彻底的学习,于是将电路图和程序移植到了9.1版本中。现在将电路和代码分享出来。
2021版官方例程
由于软件是演示版,有限制,所以不能仿真。
于是将电路图和代码移植到 PSIM 9.1 版本上
硬件电路如下:
首先使用电路传感器读取电流值。
将采样到的模拟电流值缩小0.2倍然后加上1.5送入到ADC模块中。
ADC模块有三路输入信号,两路输出信号。ADC模块是用简化C模块编写代码实现。t它的主要作用是将模拟信号转换为数字信号输出。
/
ADC Basic function /
/
// Power Smart Control S.L. //
/ https://powersmartcontrol.com/ ///
/ May 2020 ///
///
//Variables declaration
float data_in, Gadc;
static int sampled_data, counter;
static bool Flag =1, Fsamp_instant, ap_start_compensator;
int Bits;
//Input assignation
Fsamp_instant = x1;
Bits = x2;
data_in = x3;
//ADC Gain///
/* ADC gain is given by:
Gadc = ((2^Bits)-1)/(Vmax-Vmin)
Where
Vmax = maximun input voltage of the ADC.
Vmin = minimum input voltage of the ADC.
Bits = number of bits of the ADC*/
Gadc = (pow(2,Bits) -1)/3.3;
/Sample and hold, saturation and truncation///
/*As sample_data is an integer therefore
a truncation of the decimal part occurs.*/
if (Fsamp_instant == 1 && Flag ==1){
if (data_in > 3.3){
sampled_data = (3.3*Gadc); //Saturation to Vmax
}
if (data_in < 0){
sampled_data = (0*Gadc); //Saturation to Vmin
}
if (data_in <= 3.3 && data_in>=0){ //Store the data until the next sampling
sampled_data = (data_in*Gadc);
}
Flag = 0;
}
if (Fsamp_instant == 0){
Flag = 1;
ap_start_compensator = 0;
counter = 0;
}
/*A small delay of 2 time steps is considered in order to
guarantee that the data that the compensator will use to
calculate the error is the sample [k]*/
if (Flag == 0){
counter = counter +1;
}
if (counter > 2){
ap_start_compensator = 1;
}
//Output assignation
y1 = sampled_data;
y2 = ap_start_compensator;
ADC模块输出电流的数字量之后,然后在送入PI模块中通过PI公式计算输出占空比的值。
PI模块有8路输入,2路输出。PI计算时需要的一些常量通过常量模块输入。
/
// PI compensator implementation
/
// Power Smart Control S.L. //
/ https://powersmartcontrol.com/ ///
/ May 2020 ///
///
//Variables of the top function
int IL_ref, IL_sense;
float Kp, Ti, Fsamp;
float upper_limit_compensator, lower_limit_compensator;
static int output;
//Variable Definition
float A1, A0;
float e_k, proportional_k, integral_k;
static float e_k_1, integral_k_1, y_k;
//Variables only for psim simulation
static bool Flag;
bool ap_start;
//Input assignation
Kp = x3;
Ti = x4;
Fsamp = x5;
upper_limit_compensator = x6;
lower_limit_compensator = x7;
ap_start = x8;
//Calculate the compensator coefficients of the difference equation
A0 = Kp; // 137.38m
A1 = Kp/(Ti*2*Fsamp); // 137.38m / ( 43.95u * 2 * 200k) = 7.814562m
//Detect rising edge of the ap_start signal and starts the calculation of the difference equation
if (ap_start == 1 && Flag == 0){
Flag =1;
IL_ref = x1;
IL_sense = x2;
//Calculate the value of the error in the instant [k]
e_k = IL_ref - IL_sense; //计算参考值和采样值误差
//Difference equation of the compensator // PI 计算
proportional_k = A0*e_k; // 误差*Kp
integral_k = A1*e_k + A1*e_k_1 + integral_k_1; // Ki * e_k + Ki * e_k-1 + integral_k_1;
y_k = proportional_k + integral_k;
//Stores sample [K] in variables [K-1] in order to be used in the next sampling instant
e_k_1 = e_k;
integral_k_1 = integral_k;
//Limiter at the output of the compensator
if (y_k >= upper_limit_compensator) {
y_k = upper_limit_compensator;
}
if (y_k <= lower_limit_compensator) {
y_k = lower_limit_compensator;
}
output =y_k;
}
//Detect falling edge of the ap_start signal
if (ap_start == 0) {
Flag =0;
}
//Output signal
y1 = output;
y2 = integral_k;
最后将PI模块输出的占空比控制量送入到DPWM模块中,DPWM模块根据占空比的值输出两路互补的PWM波。
// DPWM with Triangular carrier ///
//
/
// Power Smart Control S.L. //
/ https://powersmartcontrol.com/ ///
/ May 2020 ///
///
//Variables declarations
float Fclk_psim, time_step, deadtime;
int Nr, Fsw, digital_deadtime, duty_1, duty_2;
bool samp_inst;
static int counter_trig=0, duty_cycle;
static bool Up=1, Down=0, HB, LB;
//Input assignation
Fsw = x1;
time_step = x2;
deadtime = x4;
//Calculation of the amplitude of the triangular
/* the maximum value of the counter is given by:
Nr = 0.5*Fclk/Fsw
Since the psim block is executed every time step
therefore the frequency of the master clock is:
Fclk = 1/time_step */
Fclk_psim = 1/time_step; // 1 / 5ns 200Mhz
Nr = 0.5*Fclk_psim/Fsw; // 0.5 * 200M / 100K = 100M / 100K = 1000
//Updating the duty cycle at the lower vertex of the triangular //三角波最小值 向上计数
if (counter_trig ==0) {
Up =1;
Down =0;
duty_cycle = x3;
}
//Updating the duty cycle at the upper vertex of the triangular //三角波最大值 向下计数
if (counter_trig == Nr) { // 判断计数器是否等于1000
Up = 0;
Down =1;
duty_cycle = x3;
}
//It generates the sampling instant signal // 输出采样信号 在计数器为 0--4 或者 996-1000时采样
if ((counter_trig >=0 && counter_trig <= 4 && Up ==1) || (counter_trig <= Nr && counter_trig >= Nr-4 && Down ==1 )){
samp_inst = 1;
} else {
samp_inst = 0;
}
//Triangular Carrier //生成三角波
if (Up ==1) {
counter_trig = counter_trig +1;
}
if (Down ==1) {
counter_trig = counter_trig -1;
}
//Calculations to generate the deadtime
digital_deadtime = deadtime/(2*time_step); // 200n / ( 2 * 5ns) = 20ns
duty_1 = duty_cycle - digital_deadtime;
duty_2 = duty_cycle + digital_deadtime;
//PWM generation
if (counter_trig >= duty_1){
HB =0;
} else {
HB =1;
}
if (duty_2 <= counter_trig){
LB =1;
} else {
LB =0;
}
//Output assignation
y1 = HB;
y2 = LB;
y3 = samp_inst;
y4 = counter_trig;
y5 = duty_cycle;
为了便于验证ADC模块转换的正确性,官方线路中还提供了一个硬件将模拟信号转换为数字信号的电路。
同时为了便于监控信号,将变量的标签和电压表连接起来,这样就可以直接在波形中观察变量的值。
电路中用到了一些参考值是通过电压源直接输入到模块中的。
移植到PSIM 9.1 版本中的完整电路如下。
仿真结果如下
如果想看其他变量的结果,可以直接在波形中添加。
这里观察输出电流的模拟值,经过ADC模块转换后的数字值,PI模块计算后的占空比值
官方的代码写的很详细,里面也有很多注释。通过官方的这个例程去理解学习数字电源的仿真,相信大家会有很多收获的。
仿真文件下载链接:https://download.csdn.net/download/qq_20222919/82906330
巴克有一些 useful macros ,例如 $(location :rule)。它是否也有获取平台名称的宏? 我需要根据构建目标的平台执行一些自定义逻辑。 最佳答案 它支持,但它只支持 nativ
我正在尝试使用 buck build leveldb . LevelDB 有一个 script that generates some platform-specific flags .我可以使用 g
尝试按照这些说明 (https://buckbuild.com/setup/getting_started.html) 构建 buck 示例项目时,我收到以下错误。 BUILD FAILED: No
我正在尝试使用 buck 构建 Eigen .不幸的是,Eigen 有一个不寻常的标题结构: Eigen/src/Cholesky/LLT.h Eigen/src/Cholesky/LDLT.h Ei
关闭。这个问题是opinion-based .它目前不接受答案。 想改善这个问题吗?更新问题,以便可以通过 editing this post 用事实和引文回答问题. 3年前关闭。 Improve t
如标题所述 - 我想使用带有 Buck 的自定义 Java 注释处理器(例如 Dagger 1/2)。查看文档没有发现任何与 Java(或 Android)相关的构建规则的明显注释处理相关属性,而且我
我正在尝试使用 Buck 添加一个预构建的静态库作为我的 iOS 项目的依赖项。使用 prebuilt_cxx_library,我可以通过 CLI 让它正常工作,但是当它生成 .xcodeproj 文
与此票相关Parameters for annotation processors are disabled and undocumented 我们如何使用 annotation_processors
我正在为我的个人项目尝试降压,但查看文档时,我无法找到构建阶段实际发生的情况。当我使用 cxx_ 选项设置项目时,buck 会为我生成一个 makefile 还是会生成 CMakeLists.txt?
我正在尝试将项目从 Buck 迁移到 bazel,并寻找可用于 genrules 的 $(classpath) 宏的等效项。 bazel 中是否有类似的东西可以获取给定 java_library 的类
我一直在研究将 Buck 用于一个大型项目,但我想知道是否有与 gradle 的构建变体和产品风格等价的非常有用的东西。 最佳答案 对于调试与发布版本(即 BuildConfig.java 中的常量)
我正在玩本地 react 。我读了很多关于buckbuild系统。现在我正在尝试将这两者联系起来(以充分发挥核素编辑器的潜力)。 有没有人告诉我如何生成 buckconfig现有 React Nati
我正在尝试写一个 homebrew我的 Java 项目的公式。我正在使用buck构建项目,需要从 Maven 下载一些 jar 文件。 例如,我的 BUCK 文件具有: remote_file(
关闭。此题需要details or clarity 。目前不接受答案。 想要改进这个问题吗?通过 editing this post 添加详细信息并澄清问题. 已关闭 6 年前。 Improve th
根据 this thread , Buck 目前没有完整的多 dexing 支持——至少在“官方”解决方案如何解决多 dexing 的意义上是这样。 我感到困惑的是:如果我只去 Exopackage
我正在尝试根据最大小时数将一个事件放入多个存储桶中。在我的示例中,Pin 这里的最大小时数为 1938。因此,仅通过我的查询将其存储到 2000 范围。但理想情况下,由于大头针的使用时间已达到 193
大家好我的开发人员, 我正在尝试从 Gradle 切换到 Buck,但在使用 Dagger 和 Butterknife 进行设置时遇到问题,因为它们需要注释处理。 我找到了一些链接和教程,但它们已经有
如果我有如下测试 TEST(One, A) { ... } TEST(Two, B) { ... } 如何使用buck test 只运行One.A?我希望能够做到 buck test somethin
我正在尝试使用 Buck 构建测试在 Travis CI 服务器上使用 buck test C++ 目标(通过 GitHub),但有两件事我无法弄清楚。 我必须在 Travis 服务器上安装 Buck
我在自己的 C++ 项目中使用 Buck,但我依赖于使用 CMake 构建的第三方库。 CMake 文件很复杂,所以我认为在 Buck 中重新创建他们的 CMake 文件不切实际。相反,我想从 Buc
我是一名优秀的程序员,十分优秀!