PI闭环的FPGA实现

2023-10-30

PID闭环的FPGA实现

1 原理分析

最近小张同学在做项目的时候发现PI闭环的FPGA学习资料很少,秉持着“既然没有轮子,那么自己就造一个的原则”,于是乎自己写了个PI的Verilog程序。
FPGA中实现PI闭环与DSP、STM32、arm中都不一样,由于FPGA中没有数学库,需要从底层开始解决运算中产生的小数、除法等问题。因此FPGA中实现PI闭环相比来说有一点点难度。

​ 首先,位置式PI和增量式PI的选择问题,由于位置式PI的实现原理包含历史误差的累计,并且启动瞬间或状态突然切换瞬间会有突变现象,突变现象会影响电机的动态性能,同时启动电流会很大,而这会对电机工作状态产生影响,因此采用增量式PI控制更优。当然,我觉得用位置式pi也能适用于电机的pi闭环。因为本质上来说,这两种pi实现机理并无差异,最终的控制效果也应该差异不大。

而增量式PI控制通常包括并联式PI控制和串联式PI控制,并联式PI控制可以实现 K p K_p Kp K i K_i Ki 的解耦,方便参数调试,所以采用并联式增量PI控制器。

上图是增量并联并联式PI框图,含义为参考值与实际值比较得到的差值分为两部分,一部分通过P的直接增益,另一部分通过积分的积分增益,合并输出。

下图是传递函数,只调节Kp相,可以调节幅值,对应的Ki值需要与之对应,可以调节控制系统的零点,Kp幅值增加对应的零点频率会下降,零点频率实际上是Kp和Ki的函数

典型pid系统的输出信号表达式如(1)所示
u k = K p ( ( e t ) + 1 T i ∫ 0 t e ( t ) d ( t ) + T d d e ( k ) e ( k ) ) u_k = K_p((e_t)+\frac{1}{T_i}\int ^t_0 e(t){\rm d}(t)+T_d\frac{de(k)}{e(k)}) uk=Kp((et)+Ti10te(t)d(t)+Tde(k)de(k))

采用PI控制,即无微分项,则
u k = K p ( ( e t ) + 1 T i ∫ 0 t e ( t ) d ( t ) ) u_k = K_p((e_t)+\frac{1}{T_i}\int ^t_0 e(t){\rm d}(t)) uk=Kp((et)+Ti10te(t)d(t))

2 PI的硬件实现

在数字电路中,并无法实现连续时间的积分和微分,因此数字pid中,只能以固定采样周期来进行离散化,从而实现近似的连续时间的积分和微分,利用这个思想,将式(2)进行离散化,

  1. 用一系列采样时间kT来代替时间t
  2. 以和式来代替积分: ∫ 0 t e ( t ) d ( t ) ) = ∑ e ( j T ) T = T ∑ e ( k ) \int ^t_0 e(t){\rm d}(t)) = \sum e(jT)T = T\sum e(k) 0te(t)d(t))=e(jT)T=Te(k)
  3. 向后差分 来代替 微分 d e ( t ) d t = e ( k ) − e ( k − 1 ) Δ t = e ( k ) − e ( k − 1 ) T s \frac{de(t)}{dt}=\frac{e(k)-e(k-1)}{\Delta t}=\frac{e(k)-e(k-1)}{T_s} dtde(t)=Δte(k)e(k1)=Tse(k)e(k1)

可得位置式PID的离散化如下式
u k = K p ( e k ) + K i ∑ ( e k ) + K d ( e ( k ) − e ( k − 1 ) ) u_k = K_p(e_k)+K_i\sum(e_k)+K_d(e(k)-e(k-1)) uk=Kp(ek)+Ki(ek)+Kd(e(k)e(k1))
PI中令位置式 K d K_d Kd = 0 即可得 位置式PI表达式
u k = K p ( e k ) + K i ∑ ( e k ) u_k = K_p(e_k)+K_i\sum(e_k) uk=Kp(ek)+Ki(ek)
硬件中可以对误差的累计 S u m ( k ) = S u m ( k − 1 ) + ( k ) 。 Sum(k)=Sum(k-1)+(k)。 Sum(k)=Sum(k1)+(k)

增量式PID

增量为:
Δ u ( k ) = u ( k ) − u ( k − 1 ) = k p [ e ( k ) − e ( k − 1 ) ] + k i    e ( k ) + k d   [ e ( k ) − 2 e ( k − 1 ) + e ( k − 2 ) ] \Delta u(k) = u(k)-u(k-1) =k_p[e(k)-e(k-1)]+k_i\,\,e(k)+k_d\,[e(k)-2e(k-1)+e(k-2)] Δu(k)=u(k)u(k1)=kp[e(k)e(k1)]+kie(k)+kd[e(k)2e(k1)+e(k2)]
令位置式 K d K_d Kd = 0 即可得
Δ u ( k ) = u ( k ) − u ( k − 1 ) = k p [ e ( k ) − e ( k − 1 ) ] + k i    e ( k ) \Delta u(k) = u(k)-u(k-1) =k_p[e(k)-e(k-1)]+k_i\,\,e(k) Δu(k)=u(k)u(k1)=kp[e(k)e(k1)]+kie(k)
增量式PID的输出为
u ( k ) = u ( k − 1 ) + Δ u ( k ) u(k)=u(k-1)+\Delta u(k) u(k)=u(k1)+Δu(k)

然而很多场合下需要的往往不只增量,还有上一拍的输出值,于是可知增量式PI调节器算法为
u ( k ) = u ( k − 1 ) + Δ u ( k ) = u ( k − 2 ) + Δ u ( k − 1 ) + Δ u ( k ) = u ( 0 ) + u ( 1 ) + . . . . . + u ( k − 1 ) u(k)=u(k-1)+\Delta u(k)=u(k-2)+\Delta u(k-1)+\Delta u(k)=u(0)+u(1)+.....+u(k-1) u(k)=u(k1)+Δu(k)=u(k2)+Δu(k1)+Δu(k)=u(0)+u(1)+.....+u(k1)
由于 u ( 0 ) = 0 u(0)=0 u(0)=0在具体编程操作中,对每一拍的 Δ u ( k ) \Delta u(k) Δu(k)进行累积,即为PI调节器的输出;同样地,为了避免超过允许值,仅需对输出限幅即可

事实上,由增量式PI
u ( k ) = u ( k − 1 ) + Δ u ( k ) = u ( k − 1 ) + K P ∗ ( e ( k ) − e ( k − 1 ) ) + K i T s e ( k ) u(k)=u(k-1)+\Delta u(k)=u(k-1)+K_P*(e(k)-e(k-1))+K_iT_se(k) u(k)=u(k1)+Δu(k)=u(k1)+KP(e(k)e(k1))+KiTse(k)
可得
u ( k − 1 ) = u ( k − 2 ) + Δ u ( k − 1 ) = u ( k − 2 ) + K P ∗ ( e ( k − 1 ) − e ( k − 2 ) ) + K i T s e ( k − 1 ) u(k-1)=u(k-2)+\Delta u(k-1)=u(k-2)+K_P*(e(k-1)-e(k-2))+K_iT_se(k-1) u(k1)=u(k2)+Δu(k1)=u(k2)+KP(e(k1)e(k2))+KiTse(k1)
代入上式即可约去 e ( k − 1 ) e(k-1) e(k1)项,不断迭代,由于 e ( 0 ) = 0 e(0)=0 e(0)=0,可发现其最终结果与位置式PI的表达式一致,也即两种PI算法完全相同(未超出限幅值的前提下)
因此,可以理解为无论用增量叠加的方式来计算位置式PI,还是直接计算,结果都是相同的。两者唯一的区别就是位置式PI需要同时设置积分限幅和输出限幅,而增量式PI只需输出限幅。 增量式的好处就是启动时和状态突然发生变化时不会产生突变,其控制效果与位置式PI基本相同。

3 如何在硬件中实现积分器

如何实现一个积分器(I)?

​ 创建一个加法器是最简单的形式,PI环节如上述框图描述所示。Z-1代表延迟块,T代表采样周期。
O u t ( x ) = O u t ( x − 1 ) + I n ( x ) ∗ T Out(x) = Out(x-1) + In(x)*T Outx=Out(x1)+In(x)T
​ 新输出值 = 旧输出值 + 输入*采样周期

//C语言实现
Out += In*T;

4、FPGA的硬件实现

话不多说,直接贴代码

代码简单易懂 相信各位聪明的小伙伴一看就能看懂

`timescale 1 ns/1 ns

//增量式 PI	
//仿真验证通过版本
// 至于k_p k_i 
module pid_controller_delta #(
	parameter   logic  [23:0] k_p=24'd30,   //kP
	parameter   logic  [23:0] k_i=24'd2 		 //Ki	
)(
	input  wire signed [15:0] i_real,//实际电流值
	input  wire signed [15:0] i_aim, //输入给定电流值
	input  wire 				  clk,
	input  wire					  rstn,
	input  wire					  pi_en,  //park变换是否完成的信号,高定平即完成park变换
	output wire  signed [15:0] u_out, //输出电压值 u_alpha U_beta
	output reg	 	  			  o_en    //PI 结束信号
 );
	reg signed [31:0] error_1,error_2,delta_error;//误差值 error_1为上一时刻的误差值,error_2为当前的误差值
	reg signed [31:0] multipy_p,multipy_i,multipy_i1,multipy_i2;  		 //分别代表delta_u两部分的乘积
	reg signed [31:0] u_out_temp,delta_u; 	 		 //寄存上一时刻的输出值,delta_u代表输出的增量
	reg 					en_s1,en_s2,en_s3,en_s4,en_s5; 
	
	assign 	u_out = u_out_temp[15:0];  
	function automatic logic signed [31:0] protect_add(input logic signed [31:0] a, input logic signed [31:0] b);
		automatic logic signed [32:0] y;
		y = $signed({a[31],a})+$signed({b[31],b});  //积分限幅
		//积分限幅
		if(       y  >  $signed(33'h7fffffff)  )//
			return 		 $signed(32'h7fffffff);
		else if(  y  < -$signed(32'h7fffffff)	)
			return 		-$signed(32'h7fffffff);
		else
			return		 $signed(y[31:0]);
	endfunction 
	
	function automatic logic signed [31:0] protect_mul(input logic signed [31:0] a, input logic signed [24:0] b);
	
		automatic logic signed [57:0] y;
		y = a * b;  //积分限幅
		//积分限幅
		if(       y  >  $signed(57'h7fffffff)  )//
			return 		 $signed(32'h7fffffff);
		else if(  y  < -$signed(57'h7fffffff)	)
			return 		-$signed(32'h7fffffff);
		else
			return		 $signed(y[31:0]);
	endfunction 
	
	function automatic logic signed [31:0] protect_subtract(input logic signed [31:0] a, input logic signed [31:0] b);
		automatic logic signed [32:0] y;
		y = $signed({a[31],a}) - $signed({b[31],b});
		//
		if(  			y  >  $signed(33'h7fffffff)  )
			return 	   	$signed(32'h7fffffff);
		else if (   y  < -$signed(32'h7fffffff)	)
		return 			  -$signed(32'h7fffffff);
		else 
		return 				$signed(y[31:0]);
	endfunction
	// plpeline 1  计算e(k)
	always@(posedge clk or negedge rstn)
		if(~rstn) begin
			en_s1   <= 1'b0;
			error_1 <= 0;
		end 
		else begin
			en_s1 <= pi_en;
			if(pi_en) begin
				error_1 <=  $signed({{16{i_aim[15]}},i_aim}) - $signed({{16{i_real[15]}},i_real}) ;
			end
		end
	//pipeline 2 计算e(k-1)
	always@(posedge clk or negedge rstn)
		if(~rstn) begin
			en_s2   <= 1'b0;
			error_2 <= 0;
		end
		else begin
			en_s2 <= en_s1;
			if(en_s1) begin
				error_2 <= error_1;  //e(k-1)
				multipy_i <= protect_mul(error_1,k_i);
			end 
		end
	
	always@(posedge clk or negedge rstn)
		if(~rstn) begin
			en_s3 <= 1'b0;
			multipy_i1 <= 0;
			delta_error <= 0;
		end
		else begin
			en_s3 <= en_s2;
			if(en_s2) begin
				multipy_i1 <= multipy_i;
				delta_error <= protect_subtract(error_1,error_2);
			end			
		end 	
		
	always@(posedge clk or negedge rstn)
		if(~rstn) begin
			en_s4 <= 1'b0;
			multipy_i2 <= 0;
			multipy_p <=0;
		end
		else begin
		 en_s4 <= en_s3;
		 if(en_s3) begin
			multipy_i2 <= multipy_i1;
			multipy_p  <= protect_mul(delta_error,k_p);
		 end
		end
		
	always@(posedge clk or negedge rstn)
		if(~rstn) begin
			en_s5 <= 1'b0;
			delta_u <= 0;
		end
		else begin
			en_s5 <= en_s4;
			if(en_s4) begin
			delta_u <= protect_add(multipy_i2,multipy_p);
			end
		end
		
	always@(posedge clk or	negedge rstn)
		if(~rstn) begin
			o_en <= 1'b0;
			u_out_temp <= 0;
		end 
		else begin
			o_en <= en_s5;
			if(en_s5) begin
				u_out_temp = protect_add(u_out_temp,delta_u);
			 end
		end  
endmodule  

5、仿真波形

i_aim 给定值是350 实际值是调节后的曲线,从图中可以看出,PI调节可以快速达到闭环,并进入稳态。

如果感觉博主的博客写的还可以的话,欢迎一键三连,点个关注不迷路哦~

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

PI闭环的FPGA实现 的相关文章

  • 修改后的 baugh-wooley 算法乘法 verilog 代码不能正确乘法

    以下 verilog 源代码和 或测试平台可以很好地工作商业模拟器 iverilog https www edaplayground com x 3TuQ也形式化验证工具 yosys smtbmc https gist github com
  • Linux驱动程序DMA传输到PC作为主机的PCIe卡

    我正在开发一个 DMA 例程 将数据从 PC 传输到 PCIe 卡上的 FPGA 我阅读了 DMA API txt 和 LDD3 ch 15 详细信息 但是 我不知道如何从 PC 到 PCIe 卡上的一致 iomem 块进行 DMA 传输
  • 模拟器和合成器之间初始化状态机的差异

    我的问题是关于合成状态机中使用的第一个状态 我正在使用莱迪思 iCE40 FPGA 用于仿真的 EDA Playground 和用于综合的莱迪思 Diamond Programmer 在下面的示例中 我生成一系列信号 该示例仅显示引用状态机
  • Verilog 错误:必须连接到结构网络表达式

    我收到错误 output or inout port Qout must be connected to a structural net expression 我评论了下面代码中发生错误的行 代码被修剪 压缩 我搜索了答案 似乎我无法将输
  • 您可以使用类 C 语言对 FPGA 进行编程吗? [关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 在大学里 我用类似 C 的语言编写了 FPGA 不过 我也知道人们通常使用 Verilog 或 VHD
  • 从测试台访问 uvm_config_db 的最佳方式?

    我想在我的顶级测试平台中创建一个时钟 其周期可以通过测试进行控制 我所做的是将周期设置到 uvm config db 中并将其返回到测试台中 我必须输入 1 以确保构建阶段已完成 否则 get 返回错误值 module testbench
  • 在verilog中将wire值转换为整数

    我想将电线中的数据转换为整数 例如 wire 2 0 w 3 b101 我想要一个将其转换为 5 并将其存储在整数中的方法 我怎样才能以比这更好的方式做到这一点 j 1 for i 0 i lt 2 i i 1 begin a a w i
  • 如何在 Verilog 中综合 While 循环?

    我尝试设计一个 Booth 乘法器 它在所有编译器中运行良好 包括 Modelsim Verilogger Extreme Aldec Active Hdl 和 Xilinx Isim 我知道模拟和综合是两个不同的过程 而且只有少数Veri
  • 具有 +1 逻辑的 4 位计数器 D 触发器

    我正在尝试通过 Verilog 实现带有 1 逻辑的 D 触发器计数器 但是我收到了很多有关网络多个常量驱动程序的错误代码 有人可以帮我吗 这是到目前为止的代码 module LAB clk clear Enable Q input clk
  • AppleScript:从应用程序隐藏/获取进程名称

    我想隐藏最前面的应用程序 我知道您可以使用以下语法隐藏进程 tell application System Events set visible of process to false end tell 我知道如何获取最前面的应用程序 pa
  • 如何从 Spartan 6 写入 Nexys 3 FPGA 板上的 Micron 外部蜂窝 RAM?

    我到处都查过了 数据表 Xilinx 网站 digilent 等等 但什么也没找到 我能够使用 Adept 工具来验证我的蜂窝 RAM 是否正常运行 但我找不到任何库存 VHDL 代码作为控制器来写入数据和从中读取数据 帮助 找到了此链接
  • Verilog 中的 If 语句和分配连线

    我试图弄清楚基于组合逻辑分配电线的基础知识 I have wire val wire x wire a wire b always begin if val 00 I want to assign x a if val 01 I want
  • 在测试台中显示信号名称/文字

    是否可以在 Verilog 中引用 显示信号的名称 文字 对于在 Verilog 测试台中创建通用信号检查功能来说 这将是一个有用的功能 我知道使用 display 时 m 将打印信号的范围 是否有显示信号名称的等效项 在 Verilog
  • 如何在 Verilog 中推断 Block RAM

    我在一个项目中遇到了一个非常具体的问题 这个问题已经困扰我好几天了 我有以下 RAM 模块的 Verilog 代码 module RAM param clk addr read write clear data in data out pa
  • reg 声明中的位顺序

    如果我需要使用 4 个 8 位数字 我会声明以下 reg reg 7 0 numbers 3 0 我对第一个和第二个声明 7 0 和 3 0 之间的区别感到很困惑 他们应该按什么顺序来 第一个是保留数字的大小 而第二个是保留数字的数量 还是
  • 使用正则表达式进行 Verilog 端口映射

    我有一个很长的端口映射 我想在其中替换一堆 SignalName i with SignalName SignalName i 我想我可以用正则表达式轻松地做到这一点 但我无法弄清楚如何做到这一点 有任何想法吗 假设 SignalData
  • 具有内部赋值延迟的阻塞和非阻塞语句之间的区别

    以下 2 个 verilog 代码片段有什么区别 1 always in out 5 in AND 2 always in out lt 5 in 考虑到always块中不存在其他行 输出会有什么不同吗 问题参考幻灯片 16 参见 o5 和
  • 学习 Verilog 的资源 [关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 我是 Verilog 新手 有人可以推荐学习资源 书籍 视频 博客或任何他们有良好个人经验并帮助他们更
  • 无符号和 std_logic_vector 之间的区别

    谁能告诉我以下书面陈述之间的区别 signal A unsigned 3 downto 0 signal B std logic vector 3 downto 0 Both std logic vector and unsigned ar
  • docker 容器无法启动,因为现有的 pid 文件

    当我启动 docker 容器时 它会失败 因为现有的 pid 文件 root newhope sergio docker logs sharp shockley httpd pid 1 already running httpd pid 1

随机推荐

  • C/C++语言 从日期格式字符串中提取年月日时分秒

    系列文章目录 文章目录 系列文章目录 前言 一 日期格式字符串 二 strftime函数 1 描述 2 声明 3 形参 4 返回值 三 strptime函数 1 形参 2 示例 3 函数封装 总结 前言 上一篇文章 C C 语言 获取系统时
  • MES管理系统如何帮助制造企业打造透明化工厂

    在制造型企业的运营中 车间现场管理至关重要 然而 面临着信息传递速度慢 跨部门协作困难 生产进度无法及时掌握 制造品质不良 设备故障不能及时处理等困境 企业需要寻求有效的解决方案 MES生产管理系统作为针对制造企业车间生产过程控制和管理的解
  • 如何在使用中文输入法的时候打出英文字符

    解决方法很简单 只需要按CTRL 就可以实现中英文字符切换 这样在按字母的时候还是会显示拼音 但输入字符时都是英文字符了 避免了频繁的shift切换
  • 【Qt学习】07:绘图与绘图设备

    OVERVIEW 绘图与绘图设备 一 QPainter 二 QPainterDevice 1 QPixmap 2 QBitmap 3 QImage 4 QPicture 绘图与绘图设备 一 QPainter Qt 的绘图系统允许使用API在
  • unsigned int用法

    注意使用unsigned int 无符号常数 正如我们所知道的 编程语句都有很多的基本数据类型 如char inf float等等 而在C和C 中还有一个特殊的类型就是无符号数 它由unsigned修饰 如unsigned int等 大家有
  • visible.sync 的作用

    我们在前端开发中经常看到 visible sync这种修饰符 很多人不知道这是干什么的 特别是在使用ElementUI的时候 里面有个弹窗el dialog组件的时候会有用到 visible sync
  • VUE项目中的全局格式化时间过滤器

    1 全局过滤器 https blog csdn net weixin 45054614 article details 105368776 全局时间格式化 对名称进行定义 提供一个function函数 originVal 为形参 Vue f
  • Chapter1 ROS概述与环境搭建

    一 序言 学习一个新的知识模块时 要先了解模块的相关概念 安装官方软件包 搭建其集成的开发环境 这些完成后 继续开始开创新领域的大门 二 ROS简介 2 1 ROS的概念 一个比喻 机器人的控制集成硬件设计 嵌入式软件设计 上层软件设计 l
  • Echart 之 timeline 时间组件 基本用法

    此处是基础版 大神请绕路 官方给的timeline组件太过于复杂 对于不熟悉的朋友 只是看逻辑就浪费很多时间 以下是基础版的示例 div style height 100 div
  • Altium AD20删除机械层MECH

    1 滥用MECH机械层导致的PCB过孔错误 前两天打样PCB时犯了个大毛病 导致送打样回来发现有多处网络对GND短路 更可气的是 这是在手贴了两块样板后才发现的 赔进去一下午时间和一堆元件 亏死 刚开始百思不得其解 因为在AD20中规则检查
  • 2021/9/29 TX POWER 蓝牙发射功率

    1 觉得挺奇葩 如果不是扩展包的话 就是TX power 设定 没法通过hci 下发 就是 在controller 设定好 也没法中途去变化 扩展包 有这个选项 能够改变 可以通过HCI 下发指令来更改 2 AD9361 设置发射功率 要注
  • (转)如何选择合适的射频模块

    要选择合适的射频模块 以下几个问题我们都需要搞搞清楚 无线设备该通多远 该用多大的功率 如何扩大通信距离 天线是否该重视 该选什么样的模块 初学者如何选择仪器 如何确定通信状况等等 无线设备该通多远 谈到这个话题 有必要想一想当年了 比如1
  • 一个panic bug的分析过程1

    一个panic bug的分析过程 一 2012 05 15 14 57 06 分类 LINUX 一个工作中遇到的bug的问题 分析一下流程 顺便把panic这种类似的bug流程做一些分析 环境 linux 3 0 arm 芯片平台 首先看出
  • 一台服务器部署多个tomcat

    参考文档 19条消息 一 linux部署多个tomcat 做测试的喵酱的博客 CSDN博客
  • 【算法】经典的八大排序算法

    点击链接 可视化排序 动态演示各个排序算法来加深理解 大致如下 一 冒泡排序 Bubble Sort 原理 冒泡排序 Bubble Sort 是一种简单的排序算法 它通过多次比较和交换相邻元素的方式 将最大 或最小 的元素逐步冒泡到数组的一
  • gradle更新snapshot的jar

    通常 gradle下载引用的jar文件的话 会缓存到本地 不会重复去下载 但是 我们引用的是snapshot的jar 这种jar文件一般是其他项目组的代码 这种jar一般都进行迭代开发 会重复更新上传到nexus代码仓库中 我们必须在每次启
  • linux-vmware workstation安装

    环境介绍 闲着没事测试下linux vmware workstation linux vmware workstation安装 1 搭建软件仓库 root gby mount dev sr0 mnt mount mnt WARNING de
  • TRON节点验证交易的时间容忍度

    这篇文章主要介绍深入分析TRON的节点配置文件中vm minTimeRatio和vm maxTimeRatio这两个标志的意义 这两个标志的表示的是节点 包括sr和fullnode 验证区块中智能合约交易的时间比例 时间容忍度 注 sr节点
  • 【java】swagger中api接口传多个参数 @ApiImplicitParam和@ApiImplicitParams

    目录 1 ApiImplicitParam 2 ApiImplicitParams 3 Spring Boot项目中集成Swagger knife4j并自定义访问路径 swagger常用注解使用说明 1 ApiImplicitParam 作
  • PI闭环的FPGA实现

    PID闭环的FPGA实现 1 原理分析 最近小张同学在做项目的时候发现PI闭环的FPGA学习资料很少 秉持着 既然没有轮子 那么自己就造一个的原则 于是乎自己写了个PI的Verilog程序 FPGA中实现PI闭环与DSP STM32 arm