使用 PWM 控制的电压变化控制
一、简介
PWM就是Pulse Width Modulation,脉冲宽度调制。
假设一个PWM信号,V = +5V,CLK = 13KHz,Duty = 50%,那么它输出的信号就可以看成是一个+2.5V的直流信号。
二、PWM的分辨率
假设(1)芯片自带的PWM模块分辨率为10bit
(2)PWM信号参数为:Voltage = +5V,CLK = 13KHz,Duty = 50%
分析:
(1)PWM模块的分辨率为10bit,那么它的可以分为1024个等级,所以一个周期可以分为1024个刻度。所以说,每一个刻度对应的电压可以是5V的1/1024,即4.88mV左右。所以可以在0-5V区间内,实现4.88mV的步进。
(2)若PWM的时钟为25MHz的话,其输出的PWM信号最高频率可达24.4KHz左右。
计算过程:分辨率为10bit,那么PWM内部的计数cnt最高就从0-1023,而每次计数的间隔周期是1/25MHz,所以得出PWM信号频率为24.4KHz左右。
(3)也就说,在同一个输入时钟情况下,若要到达同一个电压,分辨率越高,所需要的计数cnt就越多,波形就越精细
三、PWM信号转换成直流信号
PWM信号可以使用RC低通滤波器(如下图所示)来实现将PWM信号转换成等效的直流信号。
RC滤波器的截止频率计算公式为f = 1/(2π×RC),也就是-3dB,换算过来为0.707倍,即输入1V,输出0.707V。 衰减增益的计算公式为 X dB = 20×lg(Au)。其中Au为增益。若增益Au为10^(-3/20),换算过来分别就是0.707倍,-3dB。
原理:PWM信号的正周期会对RC滤波电路中的电容充电,而负周期则是电容对外放电。这样,电容随着PWM信号而充电、放电,从而使电容的电压在PWM信号等效的直流信号附近波动。
由于电容C需要充电,而且充电的时间常数为RC,存在充电电阻R,所以电容C无法跟随输入电压的高频部分变换而变换,从而将高频部分滤除掉。
具体来说,就是PWM信号经过傅立叶变换后,2.5V是直流分量,高频分量就被滤除掉了。或者这样理解,就是一个周期内积分的平均值。如下图所示,经过滤波后,直流部分的增益为4dB左右,也就是说,直信号的振幅为10^(4/10)=2.5V。
接下来,我们使用FilterLab软件来模拟一个特定滤波器的增益曲线:
该低通滤波器的截止频率为48.3Hz,对应的增益曲线如上图所示。当频率为13KHz时候,对应的增益为-46dB左右,也就是10^(-46/20) = 0.005倍左右。
也就是说,我们对一个13KHz的PWM信号滤波,使其成为直流信号,使用该参数的低通滤波器是可以的,其纹波信号会衰减到0.005倍。
四、电路模拟
我们用Multisim软件来进行仿真。需要注意的是时间常数τ=RC会影响电容的充电时间,也就是会影响到达稳点电压的时间。
那么,用LTspice软件进行模拟来得到更精细的波形,对滤波后的波形放大来看,可以发现其纹波是比较小的。之所以有纹波,是因为RC滤波器的截止频率不够低,滤不掉所有的噪声。
推荐阅读
-
使用 PWM 控制的电压变化控制
-
基于 simulink 的电压型 PWM 整流器双闭环矢量控制仿真
-
使用 SAP C4C 规则编辑器动态控制用户界面上是否显示按钮 - 使用 SAP 客户云用户界面规则编辑器的示例
-
一种结构设计模式,允许在对象中动态添加新行为。它通过创建一个封装器来实现这一目的,即把对象放入一个装饰器类中,然后把这个装饰器类放入另一个装饰器类中,以此类推,形成一个封装器链。这样,我们就可以在不改变原始对象的情况下动态添加新行为或修改原始行为。 在 Java 中,实现装饰器设计模式的步骤如下: 定义一个接口或抽象类作为被装饰对象的基类。 公共接口 Component { void operation; } } 在本例中,我们定义了一个名为 Component 的接口,该接口包含一个名为 operation 的抽象方法,该方法定义了被装饰对象的基本行为。 定义一个实现基类方法的具体装饰对象。 公共类 ConcreteComponent 实现 Component { public class ConcreteComponent implements Component { @Override public void operation { System.out.println("ConcreteComponent is doing something...") ; } } 定义一个抽象装饰器类,该类继承于基类,并将装饰对象作为一个属性。 公共抽象类装饰器实现组件 { protected Component 组件 public Decorator(Component component) { this.component = component; } } @Override public void operation { component.operation; } } } 在这个示例中,我们定义了一个名为 Decorator 的抽象类,它继承了 Component 接口,并将被装饰对象作为一个属性。在操作方法中,我们调用了被装饰对象上的同名方法。 定义一个具体的装饰器类,继承自抽象装饰器类并实现增强逻辑。 公共类 ConcreteDecoratorA extends Decorator { public ConcreteDecoratorA(Component 组件) { super(component); } } public void operation { super.operation System.out.println("ConcreteDecoratorA 正在添加新行为......") ; } } 在本例中,我们定义了一个名为 ConcreteDecoratorA 的具体装饰器类,它继承自装饰器抽象类,并实现了操作方法的增强逻辑。在操作方法中,我们首先调用被装饰对象上的同名方法,然后添加新行为。 使用装饰器增强被装饰对象。 公共类 Main { public static void main(String args) { Component 组件 = new ConcreteComponent; component = new ConcreteDecoratorA(component); 组件操作 } } 在这个示例中,我们首先创建了一个被装饰对象 ConcreteComponent,然后通过 ConcreteDecoratorA 类创建了一个装饰器,并将被装饰对象作为参数传递。最后,调用装饰器的操作方法,实现对被装饰对象的增强。 使用场景 在 Java 中,装饰器模式被广泛使用,尤其是在 I/O 中。Java 中的 I/O 库使用装饰器模式实现了不同数据流之间的转换和增强。 让我们打开文件 a.txt,从中读取数据。InputStream 是一个抽象类,FileInputStream 是专门用于读取文件流的子类。BufferedInputStream 是一个支持缓存的数据读取类,可以提高数据读取的效率,具体代码如下: @Test public void testIO throws Exception { InputStream inputStream = new FileInputStream("C:/bbb/a.txt"); // 实现包装 inputStream = new BufferedInputStream(inputStream); byte bytes = new byte[1024]; int len; while((len = inputStream.read(bytes)) != -1){ System.out.println(new String(bytes, 0, len)); } } } } 其中 BufferedInputStream 对读取数据进行了增强。 这样看来,装饰器设计模式和代理模式似乎有点相似,接下来让我们讨论一下它们之间的区别。 第三,与代理模式的区别: 代理模式的目的是控制对对象的访问,它在对象外部提供一个代理对象来控制对原对象的访问。代理对象和原始对象通常实现相同的接口或继承相同的类,以确保两者可以相互替换。 装饰器模式的目的是动态增强对象的功能,而这是通过对象内部的包装器来实现的。在装饰器模式中,装饰器类和被装饰对象通常实现相同的接口或继承自相同的类,以确保两者可以相互替代。装饰器模式也被称为封装器模式。 在代理模式中,代理类附加了与原类无关的功能。
-
正负偏差变量 即 d2+、d2- 分别表示决策值中超出和未达到目标值的部分。而 di+、di- 均大于 0 刚性约束和目标约束(柔性目标约束有偏差) 在多目标规划中,>=/<= 在刚性约束中保持不变。当需要将约束条件转换为柔性约束条件时,需要将 >=/<= 更改为 =(因为已经有 d2+、d2- 用来表示正负偏差),并附加上 (+dii-di+) 注意这里是 +di、-di+!之所以是 +di,-di+,是因为需要将目标还原为最接近的原始刚性约束条件 优先级因素和权重因素 对多个目标进行优先排序和优先排序 目标规划的目标函数 是所有偏差变量的加权和。值得注意的是,这个加权和都取最小值。而 di+ 和 dii- 并不一定要出现在每个不同的需求层次中。具体分析需要具体问题具体分析 下面是一个例子: 题目中说设备 B 既要求充分利用,又要求尽可能不加班,那么列出的时间计量表达式即为:min z = P3 (d3- + d3 +) 使用 + 而不是 -d3 + 的原因是:正负偏差不可能同时存在,必须有 di+di=0 (因为判定值不可能同时大于目标值和小于目标值),而前面是 min,所以只要取 + 并让 di+ 和 dii- 都为正值即可。因此,得出以下规则: 最后,给出示例和相应的解法: 问题:某企业生产 A 和 B 两种产品,需要使用 A、B、C 三种设备。下表显示了与工时和设备使用限制有关的产品利润率。问该企业应如何组织生产以实现下列目标? (1) 力争利润目标不低于 1 500 美元; (2) 考虑到市场需求,A、B 两种产品的生产比例应尽量保持在 1:2; (3)设备 A 是贵重设备,严禁超时使用; (4)设备 C 可以适当加班,但要控制;设备 B 要求充分利用,但尽量不加班。 从重要性来看,设备 B 的重要性是设备 C 的三倍。 建立相应的目标规划模型并求解。 解:设企业生产 A、B 两种产品的件数分别为 x1、x2,并建立相应的目标计划模型: 以下为顺序求解法,利用 LINGO 求解: 1 级目标: 模型。 设置。 variable/1..2/:x;! s_con_num/1...4/:g,dplus,dminus;!所需软约束数量(g=dplus=dminus 数量)及相关参数; s_con(s_con_num);! s_con(s_con_num,variable):c;!软约束系数; 结束集 数据。 g=1500 0 16 15. c=200 300 2 -1 4 0 0 5; 结束数据 min=dminus(1);!第一个目标函数;!对应于 min=z 的第一小部分;! 2*x(1)+2*x(2)<12;!硬约束 @for(s_con_num(i):@sum(variable(j):c(i,j)*x(j))+dminus(i)-dplus(i)=g(i)); !使用设置完成的数据构建软约束表达式; ! !软约束表达式 @for(variable:@gin(x)); !将变量约束为整数; ! 结束 此时,第一级目标的最优值为 0,第一级偏差为 0: 第二级目标: !求 dminus(1)=0,然后求解第二级目标。 模型。 设置。 变量/1..2/:x;!设置:变量/1..2/:x; ! s_con_num/1...4/:g,dplus,dminus;!软约束数量及相关参数; s_con(s_con_num(s_con_num));! s_con(s_con_num,variable):c;! 软约束系数; s_con(s_con_num,variable):c;! 结束集 数据。 g=1500 0 16 15; c=200 300 2 -1 4 0 0 5; 结束数据 min=dminus(2)+dplus(2);!第二个目标函数 2*x(1)+2*x(2)<12;!硬约束 @for(s_con_num(i):@sum(variable(j):c(i,j)*x(j))+dminus(i)-dplus(i)=g(i)); ! 软约束表达式;! dminus(1)=0; !第一个目标结果 @for(variable:@gin(x)); ! 结束 此时,第二个目标的最优值为 0,偏差为 0: 第三目标 !求 dminus(2)=0,然后求解第三个目标。 模型。 设置。 变量/1..2/:x;!设置:变量/1..2/:x; ! s_con_num/1...4/:g,dplus,dminus;!软约束数量及相关参数; s_con(s_con_num(s_con_num));! s_con(s_con_num,variable):c;! 软约束系数; s_con(s_con_num,variable):c;! 结束集 数据。 g=1500 0 16 15; c=200 300 2 -1 4 0 0 5; 结束数据 min=3*dminus(3)+3*dplus(3)+dminus(4);!第三个目标函数。 2*x(1)+2*x(2)<12;!硬约束 @for(s_con_num(i):@sum(variable(j):c(i,j)*x(j))+dminus(i)-dplus(i)=g(i)); ! 软约束表达式;! dminus(1)=0; !第一个目标约束条件; ! dminus(2)+dplus(2)=0; !第二个目标约束条件 @for(variable:@gin(x));! 结束 最终结果为 x1=2,x2=4,dplus(1)=100,最优利润为
-
微控制器实验说明<4> 矩阵键盘和 LCD 的基本使用
-
矩阵控制键盘的使用
-
使用嵌入式 Linux tinyplay 控制音频的 tinymix
-
Nodejs]使用机器人js控制鼠标和键盘,自动点击屏幕上的图标,实现连接wifi等操作。
-
使用 ????控制网中用于高速推理的扩散器