基于FPGA的PID算法学习———实现PID比例控制算法

news2025/6/13 23:39:38

基于FPGA的PID算法学习

  • 前言
  • 一、PID算法分析
  • 二、PID仿真分析
    • 1. PID代码
    • 2.PI代码
    • 3.P代码
    • 4.顶层
    • 5.测试文件
    • 6.仿真波形
  • 总结


前言

学习内容:参考网站:
PID算法控制
PID即:Proportional(比例)、Integral(积分)、Differential(微分)的缩写。也就是说,PID算法是结合这三种环节在一起的。
闭环控制:输出会影响到输入,进而逐渐逼近目标。

在这里插入图片描述

一、PID算法分析

PID比例控制算法:
核心部分,大部分作用来自于P,I和D主要控制减小误差。
目标值:Target
实际值:Pid_out
误差值:e_t
上一时刻误差值:e_t_1
上两个时刻误差值:e_t_2
弥补值:u_t

相关公式:
误差值:e_t=Target - Pid_out
误差值:e_t_1=e_t
误差值:e_t_2=e_t_1
弥补值:u(t)= (Kp * (e(t)-e(t-1)) + Ki * e(t) + Kd * ( e(t)- 2*e(t-1)-e(t-2) ) )
输出值:Pid_out = Pid_out + u(t)

增量式PID:

在这里插入图片描述

二、PID仿真分析

1. PID代码

`timescale 1ns / 1ps
//
// Company: 
// Engineer: 
// 
// Create Date: 2025/06/10 17:09:23
// Design Name: 
// Module Name: PID
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//
module PID(
     input                     sys_clk  ,  
     input                     rst_n,   
     //signal  
	  input		 signed	[7:0]  target,
	  output reg signed	[7:0]  Pid_out
    );
	 
	 reg	signed	[15:0]		e_t;//目标值和现在值的差距
	 reg	signed	[15:0]		e_t_1;//上一时刻差距
	 reg	signed	[15:0]		e_t_2;//上一时刻差距
	 reg	signed	[32:0]		u_t;//补偿值
     
	 parameter signed K_p = 32'd100;
	 parameter signed div_p = 8'd3;
	 
	 parameter signed K_i = 32'd250;
	 parameter signed div_i = 8'd3;
	 
	 parameter signed K_d = 32'd50;
	 parameter signed div_d = 8'd3;
//	 assign e_t = target - Pid_out;
	 always @(posedge sys_clk or negedge rst_n)begin
		  if(!rst_n)begin
				e_t <= 16'd0;
		  end
		  else begin
				e_t <= target - Pid_out;
		  end
	 end
	 
	 always @(posedge sys_clk or negedge rst_n)begin
		  if(!rst_n)begin
				e_t_1 <= 16'd0;
		  end
		  else begin
				e_t_1 <= e_t;
		  end
	 end
	 
	 always @(posedge sys_clk or negedge rst_n)begin
		  if(!rst_n)begin
				e_t_2 <= 16'd0;
		  end
		  else begin
				e_t_2 <= e_t_1;
		  end
	 end
	 
	 always @(posedge sys_clk or negedge rst_n)begin
		  if(!rst_n)begin
				u_t <= 32'd0;
		  end
		  else begin
				u_t <= ((e_t - e_t_1) * K_p )/1000 + ( e_t * K_i)/1000 +  ( (e_t -(2* e_t_1) + e_t_2 ) * K_d)/1000 ;
		  end
	 end
	 
	 always @(posedge sys_clk or negedge rst_n)begin
		  if(!rst_n)begin
				Pid_out <= 8'd0;
		  end
		  else begin
		        Pid_out <= Pid_out + u_t;
		  end
	 end
	 
	 
	 
endmodule



2.PI代码

module PID_control(
     input                     sys_clk  ,  
     input                     rst_n,   
     //signal  
	  input		 signed	[7:0]  target,
	  output reg signed	[7:0]  Pid_out
    );
	 
	 reg	signed	[15:0]		e_t;//目标值和现在值的差距
	 reg	signed	[15:0]		e_t_1;//上一时刻差距
	 reg	signed	[32:0]		u_t;//补偿值
     
	 parameter signed K_p = 32'd200;
	 parameter signed div_p = 8'd3;
	 
	 parameter signed K_i = 32'd310;
	 parameter signed div_i = 8'd3;
//	 assign e_t = target - Pid_out;
	 always @(posedge sys_clk or negedge rst_n)begin
		  if(!rst_n)begin
				e_t <= 16'd0;
		  end
		  else begin
				e_t <= target - Pid_out;
		  end
	 end
	 
	 always @(posedge sys_clk or negedge rst_n)begin
		  if(!rst_n)begin
				e_t_1 <= 16'd0;
		  end
		  else begin
				e_t_1 <= e_t;
		  end
	 end
	 
	 always @(posedge sys_clk or negedge rst_n)begin
		  if(!rst_n)begin
				u_t <= 32'd0;
		  end
		  else begin
				u_t <= ((e_t - e_t_1) * K_p )/1000 + ( e_t * K_i)/1000 ;
		  end
	 end
	 
	 always @(posedge sys_clk or negedge rst_n)begin
		  if(!rst_n)begin
				Pid_out <= 8'd0;
		  end
		  else begin
		        Pid_out <= Pid_out + u_t;
		  end
	 end
	 
	 
	 
endmodule


3.P代码

module PID_trol(
     input                     sys_clk  ,  
     input                     rst_n,   
     //signal  
	  input		 signed	[7:0]  target,
	  output reg signed	[7:0]  Pid_out
    );
	 
	 reg	signed	[15:0]		e_t;//目标值和现在值的差距
	 reg	signed	[32:0]		u_t;//补偿值
     
	 parameter signed K_p = 32'd300;
	 parameter signed div = 8'd3;
//	 assign e_t = target - Pid_out;
	 always @(posedge sys_clk or negedge rst_n)begin
		  if(!rst_n)begin
				e_t <= 16'd0;
		  end
		  else begin
				e_t <= target - Pid_out;
		  end
	 end
	 
	 always @(posedge sys_clk or negedge rst_n)begin
		  if(!rst_n)begin
				u_t <= 32'd0;
		  end
		  else begin
				u_t <= (e_t * K_p )/1000;
		  end
	 end
	 
	 always @(posedge sys_clk or negedge rst_n)begin
		  if(!rst_n)begin
				Pid_out <= 8'd0;
		  end
		  else begin
		        Pid_out <= Pid_out + u_t;
		  end
	 end
	 
	 
	 
endmodule


4.顶层

`timescale 1ns / 1ps
//
// Company: 
// Engineer: 
// 
// Create Date: 2025/06/10 13:45:03
// Design Name: 
// Module Name: top
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//


module top(
     input                     sys_clk  ,  
     input                     rst_n,   
     //signal  
	  input		  signed	[7:0]  target,
	  output wire signed	[7:0]  P_out,
	  output wire signed	[7:0]  Pi_out,
	  output wire signed	[7:0]  Pid_out
    );
    
    PID u_PID (
        .sys_clk   (sys_clk),
        .rst_n     (rst_n),
        .target    (target),
        .Pid_out   (Pid_out) 
    );
    
   PID_control u_PI (
        .sys_clk   (sys_clk),
        .rst_n     (rst_n),
        .target    (target),
        .Pid_out   (Pi_out) 
    );
    
    PID_trol u_P(
    .sys_clk   (sys_clk),
    .rst_n     (rst_n),
    .target    (target),
    .Pid_out   (P_out)
);
endmodule

5.测试文件

`timescale 1ns / 1ps
//
// Company: 
// Engineer: 
// 
// Create Date: 2025/06/10 13:48:03
// Design Name: 
// Module Name: tb_top
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//

`timescale 1ns / 1ps

module tb_top();
    // 输入信号
    reg         sys_clk;
    reg         rst_n;
    reg signed [7:0] target;
    
    // 输出信号
    wire signed [7:0] P_out;
    wire signed [7:0] Pi_out;
    wire signed [7:0] Pid_out;
    // 实例化顶层模块
    top u_top (
        .sys_clk (sys_clk),
        .rst_n   (rst_n),
        .target  (target),
        .P_out   (P_out),
        .Pi_out  (Pi_out),
        .Pid_out (Pid_out)
    );
    
    // 时钟生成(100MHz)
    initial begin
        sys_clk = 0;
        forever #10 sys_clk = ~sys_clk;  // 10ns周期 = 100MHz
    end
    
    // 测试激励
    initial begin
        // 初始化并复位
        rst_n = 0;
        target = 0;
        #20;  // 等待两个时钟周期
        
        // 释放复位
        rst_n = 1;
        #10;
        
        // 测试场景 1:正目标值
        target = 8'd100;   // +50


    end
    

endmodule

6.仿真波形

在这里插入图片描述

在这里插入图片描述

总结

简单测试,有问题欢迎交流

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2407950.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

大话软工笔记—需求分析概述

需求分析&#xff0c;就是要对需求调研收集到的资料信息逐个地进行拆分、研究&#xff0c;从大量的不确定“需求”中确定出哪些需求最终要转换为确定的“功能需求”。 需求分析的作用非常重要&#xff0c;后续设计的依据主要来自于需求分析的成果&#xff0c;包括: 项目的目的…

51c自动驾驶~合集58

我自己的原文哦~ https://blog.51cto.com/whaosoft/13967107 #CCA-Attention 全局池化局部保留&#xff0c;CCA-Attention为LLM长文本建模带来突破性进展 琶洲实验室、华南理工大学联合推出关键上下文感知注意力机制&#xff08;CCA-Attention&#xff09;&#xff0c;…

Prompt Tuning、P-Tuning、Prefix Tuning的区别

一、Prompt Tuning、P-Tuning、Prefix Tuning的区别 1. Prompt Tuning(提示调优) 核心思想:固定预训练模型参数,仅学习额外的连续提示向量(通常是嵌入层的一部分)。实现方式:在输入文本前添加可训练的连续向量(软提示),模型只更新这些提示参数。优势:参数量少(仅提…

树莓派超全系列教程文档--(61)树莓派摄像头高级使用方法

树莓派摄像头高级使用方法 配置通过调谐文件来调整相机行为 使用多个摄像头安装 libcam 和 rpicam-apps依赖关系开发包 文章来源&#xff1a; http://raspberry.dns8844.cn/documentation 原文网址 配置 大多数用例自动工作&#xff0c;无需更改相机配置。但是&#xff0c;一…

Spark 之 入门讲解详细版(1)

1、简介 1.1 Spark简介 Spark是加州大学伯克利分校AMP实验室&#xff08;Algorithms, Machines, and People Lab&#xff09;开发通用内存并行计算框架。Spark在2013年6月进入Apache成为孵化项目&#xff0c;8个月后成为Apache顶级项目&#xff0c;速度之快足见过人之处&…

css实现圆环展示百分比,根据值动态展示所占比例

代码如下 <view class""><view class"circle-chart"><view v-if"!!num" class"pie-item" :style"{background: conic-gradient(var(--one-color) 0%,#E9E6F1 ${num}%),}"></view><view v-else …

(十)学生端搭建

本次旨在将之前的已完成的部分功能进行拼装到学生端&#xff0c;同时完善学生端的构建。本次工作主要包括&#xff1a; 1.学生端整体界面布局 2.模拟考场与部分个人画像流程的串联 3.整体学生端逻辑 一、学生端 在主界面可以选择自己的用户角色 选择学生则进入学生登录界面…

【OSG学习笔记】Day 18: 碰撞检测与物理交互

物理引擎&#xff08;Physics Engine&#xff09; 物理引擎 是一种通过计算机模拟物理规律&#xff08;如力学、碰撞、重力、流体动力学等&#xff09;的软件工具或库。 它的核心目标是在虚拟环境中逼真地模拟物体的运动和交互&#xff0c;广泛应用于 游戏开发、动画制作、虚…

突破不可导策略的训练难题:零阶优化与强化学习的深度嵌合

强化学习&#xff08;Reinforcement Learning, RL&#xff09;是工业领域智能控制的重要方法。它的基本原理是将最优控制问题建模为马尔可夫决策过程&#xff0c;然后使用强化学习的Actor-Critic机制&#xff08;中文译作“知行互动”机制&#xff09;&#xff0c;逐步迭代求解…

Qt/C++开发监控GB28181系统/取流协议/同时支持udp/tcp被动/tcp主动

一、前言说明 在2011版本的gb28181协议中&#xff0c;拉取视频流只要求udp方式&#xff0c;从2016开始要求新增支持tcp被动和tcp主动两种方式&#xff0c;udp理论上会丢包的&#xff0c;所以实际使用过程可能会出现画面花屏的情况&#xff0c;而tcp肯定不丢包&#xff0c;起码…

基于距离变化能量开销动态调整的WSN低功耗拓扑控制开销算法matlab仿真

目录 1.程序功能描述 2.测试软件版本以及运行结果展示 3.核心程序 4.算法仿真参数 5.算法理论概述 6.参考文献 7.完整程序 1.程序功能描述 通过动态调整节点通信的能量开销&#xff0c;平衡网络负载&#xff0c;延长WSN生命周期。具体通过建立基于距离的能量消耗模型&am…

简易版抽奖活动的设计技术方案

1.前言 本技术方案旨在设计一套完整且可靠的抽奖活动逻辑,确保抽奖活动能够公平、公正、公开地进行,同时满足高并发访问、数据安全存储与高效处理等需求,为用户提供流畅的抽奖体验,助力业务顺利开展。本方案将涵盖抽奖活动的整体架构设计、核心流程逻辑、关键功能实现以及…

K8S认证|CKS题库+答案| 11. AppArmor

目录 11. AppArmor 免费获取并激活 CKA_v1.31_模拟系统 题目 开始操作&#xff1a; 1&#xff09;、切换集群 2&#xff09;、切换节点 3&#xff09;、切换到 apparmor 的目录 4&#xff09;、执行 apparmor 策略模块 5&#xff09;、修改 pod 文件 6&#xff09;、…

【Oracle APEX开发小技巧12】

有如下需求&#xff1a; 有一个问题反馈页面&#xff0c;要实现在apex页面展示能直观看到反馈时间超过7天未处理的数据&#xff0c;方便管理员及时处理反馈。 我的方法&#xff1a;直接将逻辑写在SQL中&#xff0c;这样可以直接在页面展示 完整代码&#xff1a; SELECTSF.FE…

【JavaEE】-- HTTP

1. HTTP是什么&#xff1f; HTTP&#xff08;全称为"超文本传输协议"&#xff09;是一种应用非常广泛的应用层协议&#xff0c;HTTP是基于TCP协议的一种应用层协议。 应用层协议&#xff1a;是计算机网络协议栈中最高层的协议&#xff0c;它定义了运行在不同主机上…

VB.net复制Ntag213卡写入UID

本示例使用的发卡器&#xff1a;https://item.taobao.com/item.htm?ftt&id615391857885 一、读取旧Ntag卡的UID和数据 Private Sub Button15_Click(sender As Object, e As EventArgs) Handles Button15.Click轻松读卡技术支持:网站:Dim i, j As IntegerDim cardidhex, …

微软PowerBI考试 PL300-选择 Power BI 模型框架【附练习数据】

微软PowerBI考试 PL300-选择 Power BI 模型框架 20 多年来&#xff0c;Microsoft 持续对企业商业智能 (BI) 进行大量投资。 Azure Analysis Services (AAS) 和 SQL Server Analysis Services (SSAS) 基于无数企业使用的成熟的 BI 数据建模技术。 同样的技术也是 Power BI 数据…

【人工智能】神经网络的优化器optimizer(二):Adagrad自适应学习率优化器

一.自适应梯度算法Adagrad概述 Adagrad&#xff08;Adaptive Gradient Algorithm&#xff09;是一种自适应学习率的优化算法&#xff0c;由Duchi等人在2011年提出。其核心思想是针对不同参数自动调整学习率&#xff0c;适合处理稀疏数据和不同参数梯度差异较大的场景。Adagrad通…

Xshell远程连接Kali(默认 | 私钥)Note版

前言:xshell远程连接&#xff0c;私钥连接和常规默认连接 任务一 开启ssh服务 service ssh status //查看ssh服务状态 service ssh start //开启ssh服务 update-rc.d ssh enable //开启自启动ssh服务 任务二 修改配置文件 vi /etc/ssh/ssh_config //第一…

Zustand 状态管理库:极简而强大的解决方案

Zustand 是一个轻量级、快速和可扩展的状态管理库&#xff0c;特别适合 React 应用。它以简洁的 API 和高效的性能解决了 Redux 等状态管理方案中的繁琐问题。 核心优势对比 基本使用指南 1. 创建 Store // store.js import create from zustandconst useStore create((set)…