本文芯片采用STM32G474CBT6,采用STM32cubeMX进行程序生成。
BUCK电路拓扑结构:

如图所示,BUCK变换器主要由电源VDC、场效应管MOSFET、续流二极管VD、电感L以及滤波电容C和负载RES组成。当MOSFET开通时,电流通过MOSFET给电感L储能,同时给负载供电;当MOSFET关闭时,电感L释放能量,电流从电感L经过负载再通过续流二极管VD流回电感L。通过改变MOSFET的开关时间,即改变MOSFET的占空比D可以控制输出电压的大小,其中D=Vo/Vi,该公式只适用于BUCK变换器中的CCM模式。
控制方式:
模拟控制:
传统的模拟控制方式通常采用电源控制芯片控制电路,如常用的UC3842。该控制方式通常将输出电压通过反馈电路产生一个电压与电源芯片内部的基准进行比较,再将比较的得到的值与芯片的锯齿波进行比较产生PWM波,通过这样的一个控制回路调节占空比,最终与芯片内部基准相等,从而进行稳压的目的。
数字控制:
图1为数字控制的流程图,输出电压通过电压采样电路进入MCU的AD模块,AD模块在一定的周期内对AD的值进行采样与MCU设置的基准进行比较产生误差,(图1中VDC2可看为MCU设置的基准)产生的误差进入PID算法中进行一个误差运算,再将运算出来的值进行一个限幅,防止PWM过大或者过小对电路造成不稳定。控制量再经过MCU内部定时器的预分频器的值进行除运算得出相对应的占空比值赋给定时器更新占空比对MOSFET进行控制。其中PID需要每个周期进行一次运算。

图1
程序编写:
得知数字控制的流程之后我们就可以将其转换为程序放入MCU中,其中最重要的是AD采样的位置和PID算法。
如图2所示,在一个周期的中点对ADC进行采样是最好的,这样可以避免开关噪声所带来的误差。程序中采用HRTIM1的TimerA的寄存器1产生PWM波,寄存器3进行触发AD采用。

图2
接下来开始编写程序。
以下程序为定时器寄存器3的中断回调函数,用同一个定时器的好处就是可以方便确定AD采样的点,该程序主要进行ADC的采样和PID的计算,其中将采样回来的值进行换算成实际电压后放入PID程序中进行计算。电压是否要放大根据自己的实际采样电路进行取舍,也可自行加入滤波程序。
void HAL_HRTIM_Compare3EventCallback(HRTIM_HandleTypeDef * hhrtim, uint32_t timerA)
{
uint32_t sum = 0; //循环总和
uint32_t value_sum = 0; //滤波后电压
Vout = ADC_Value[1]*3.3f/4095; //计算采样出来的实际电压
Value = Vout * 1000; //电压放大一千倍
PID_Incremental(Value,251); //PID计算
}
以下程序为PID程序,首先定义需要用到的变量,再将这些变量进行初始化赋值,其次就进入PID的主要程序。该程序有两个变量,一个是AD采样得到的值,一个是自己设置的一个值,(设置值主要根据自己想要的输出电压进行设置)首先计算出设置值和当前采样值的误差(若采样电压有放大则需要除一个放大倍数,若采样时没有放大,则不需要),求得多几次的误差,得到误差后就可以放入PID的程序中进行计算出ERROR_Increase_V。(PID的公式为∆uk = Kp * [ek - ek-1 + Ki * ek + Kd * [ek - 2ek-1 + e(k-2)])计算完PID后将误差进行移位,留给下一次计算做准备。将计算得到的ERROR_Increase_V进行占空比的限幅,防止没有设置合适的PID参数时得到的结果过大对电路造成损坏。用得到的ERROR_Increase_V计算出实际电压计算出占空比赋值给定时器的寄存器1更新占空比,将计算出的占空比的一半的值赋值给寄存器3进行更新ADC的采样点。其中PID的参数对电路的稳定性有决定性的影响,调试PID参数时可采用串口的方式进行调试,但是调整好参数之后要将串口程序进行屏蔽,否则输出电压会跳动。
float Kp_V; //比例系数
float Ki_V; //积分系数
float Kd_V; //微分系数
float error1_V; //当前输出和设定值误差
float error2_V; //当前输出和设定值误差
float e1_V; //上次输出和设定值误差
float e2_V; //上上次输出和设定值误差
float Duty; //占空比
float ERROR_Increase_V; //占空比增加量
uint32_t Pulse_width = 0; //占空比宽度
void PID_init(void) //PID初始化
{
Kp_V = 0.3f; //比例系数
Ki_V = 0.001f; //积分系数
Kd_V = 0.8; //微分系数
error1_V = 0.0; //当前输出和设定值误差
error2_V = 0.0; //当前输出和设定值误差
e1_V = 0.0; //上次输出和设定值误差
e2_V = 0.0; //上上次输出和设定值误差
ERROR_Increase_V = 0.0; //占空比增加量
Duty = 0.0;
}
void PID_Incremental(uint16_t Vout_actual,uint16_t Vset_target) //当前电压和设置电压
{
error1_V = (Vset_target - Vout_actual) * 0.001f; //当前误差
e1_V = error1_V - error2_V; //上上次误差
ERROR_Increase_V += Kp_V * e1_V + Ki_V * error1_V + Kd_V * (e1_V - e2_V); //PID算法
error2_V = error1_V; //移位
e2_V = e1_V; //移位
if(ERROR_Increase_V >= 2.706f) //限制最大占空比82%
{
ERROR_Increase_V = 2.706f;
}
if(ERROR_Increase_V <= 0.33f) //限制最小占空比10%
{
ERROR_Increase_V = 0.33f;
}
Duty = ERROR_Increase_V * 0.303030303f; //计算电压
Pulse_width = Duty * 27200; //计算占空比
hhrtim1.Instance->sTimerxRegs[0].CMP1xR = Pulse_width; //修改占空比
hhrtim1.Instance->sTimerxRegs[0].CMP3xR = Pulse_width >> 1; //修改AD的采样点
}
BUCK电路改为同步整流只需要将续流二极管改为MOSFET即可,程序只需要将PWM波改为互补的PWM即可。
我想用ruby编写一个小的命令行实用程序并将其作为gem分发。我知道安装后,Guard、Sass和Thor等某些gem可以从命令行自行运行。为了让gem像二进制文件一样可用,我需要在我的gemspec中指定什么。 最佳答案 Gem::Specification.newdo|s|...s.executable='name_of_executable'...endhttp://docs.rubygems.org/read/chapter/20 关于ruby-在Ruby中编写命令行实用程序
当我在Rails控制台中按向上或向左箭头时,出现此错误:irb(main):001:0>/Users/me/.rvm/gems/ruby-2.0.0-p247/gems/rb-readline-0.4.2/lib/rbreadline.rb:4269:in`blockin_rl_dispatch_subseq':invalidbytesequenceinUTF-8(ArgumentError)我使用rvm来管理我的ruby安装。我正在使用=>ruby-2.0.0-p247[x86_64]我使用bundle来管理我的gem,并且我有rb-readline(0.4.2)(人们推荐的最少
我正在使用Ruby2.1.1和Rails4.1.0.rc1。当执行railsc时,它被锁定了。使用Ctrl-C停止,我得到以下错误日志:~/.rvm/gems/ruby-2.1.1/gems/spring-1.1.2/lib/spring/client/run.rb:47:in`gets':Interruptfrom~/.rvm/gems/ruby-2.1.1/gems/spring-1.1.2/lib/spring/client/run.rb:47:in`verify_server_version'from~/.rvm/gems/ruby-2.1.1/gems/spring-1.1.
我将我的Rails应用程序部署到OpenShift,它运行良好,但我无法在生产服务器上运行“Rails控制台”。它给了我这个错误。我该如何解决这个问题?我尝试更新rubygems,但它也给出了权限被拒绝的错误,我也无法做到。railsc错误:Warning:You'reusingRubygems1.8.24withSpring.UpgradetoatleastRubygems2.1.0andrun`gempristine--all`forbetterstartupperformance./opt/rh/ruby193/root/usr/share/rubygems/rubygems
我正在尝试解析一个CSV文件并使用SQL命令自动为其创建一个表。CSV中的第一行给出了列标题。但我需要推断每个列的类型。Ruby中是否有任何函数可以找到每个字段中内容的类型。例如,CSV行:"12012","Test","1233.22","12:21:22","10/10/2009"应该产生像这样的类型['integer','string','float','time','date']谢谢! 最佳答案 require'time'defto_something(str)if(num=Integer(str)rescueFloat(s
我想在Ruby中创建一个用于开发目的的极其简单的Web服务器(不,不想使用现成的解决方案)。代码如下:#!/usr/bin/rubyrequire'socket'server=TCPServer.new('127.0.0.1',8080)whileconnection=server.acceptheaders=[]length=0whileline=connection.getsheaders想法是从命令行运行这个脚本,提供另一个脚本,它将在其标准输入上获取请求,并在其标准输出上返回完整的响应。到目前为止一切顺利,但事实证明这真的很脆弱,因为它在第二个请求上中断并出现错误:/usr/b
导读:随着叮咚买菜业务的发展,不同的业务场景对数据分析提出了不同的需求,他们希望引入一款实时OLAP数据库,构建一个灵活的多维实时查询和分析的平台,统一数据的接入和查询方案,解决各业务线对数据高效实时查询和精细化运营的需求。经过调研选型,最终引入ApacheDoris作为最终的OLAP分析引擎,Doris作为核心的OLAP引擎支持复杂地分析操作、提供多维的数据视图,在叮咚买菜数十个业务场景中广泛应用。作者|叮咚买菜资深数据工程师韩青叮咚买菜创立于2017年5月,是一家专注美好食物的创业公司。叮咚买菜专注吃的事业,为满足更多人“想吃什么”而努力,通过美好食材的供应、美好滋味的开发以及美食品牌的孵
目录一.加解密算法数字签名对称加密DES(DataEncryptionStandard)3DES(TripleDES)AES(AdvancedEncryptionStandard)RSA加密法DSA(DigitalSignatureAlgorithm)ECC(EllipticCurvesCryptography)非对称加密签名与加密过程非对称加密的应用对称加密与非对称加密的结合二.数字证书图解一.加解密算法加密简单而言就是通过一种算法将明文信息转换成密文信息,信息的的接收方能够通过密钥对密文信息进行解密获得明文信息的过程。根据加解密的密钥是否相同,算法可以分为对称加密、非对称加密、对称加密和非
C#实现简易绘图工具一.引言实验目的:通过制作窗体应用程序(C#画图软件),熟悉基本的窗体设计过程以及控件设计,事件处理等,熟悉使用C#的winform窗体进行绘图的基本步骤,对于面向对象编程有更加深刻的体会.Tutorial任务设计一个具有基本功能的画图软件**·包括简单的新建文件,保存,重新绘图等功能**·实现一些基本图形的绘制,包括铅笔和基本形状等,学习橡皮工具的创建**·设计一个合理舒适的UI界面**注明:你可能需要先了解一些关于winform窗体应用程序绘图的基本知识,以及关于GDI+类和结构的知识二.实验环境Windows系统下的visualstudio2017C#窗体应用程序三.
文章目录1.开发板选择*用到的资源2.串口通信(个人理解)3.代码分析(注释比较详细)1.主函数2.串口1配置3.串口2配置以及中断函数4.注意问题5.源码链接1.开发板选择我用的是STM32F103RCT6的板子,不过代码大概在F103系列的板子上都可以运行,我试过在野火103的霸道板上也可以,主要看一下串口对应的引脚一不一样就行了,不一样的就更改一下。*用到的资源keil5软件这里用到了两个串口资源,采集数据一个,串口通信一个,板子对应引脚如下:串口1,TX:PA9,RX:PA10串口2,TX:PA2,RX:PA32.串口通信(个人理解)我就从串口采集传感器数据这个过程说一下我自己的理解,