使用PID算法实现DAC模拟量输出的快速调节

目录

概述

1 系统框架和算法

1.1 框架结构介绍

1.2 PID算法实现

1.2.1 理论介绍

1.2.2  离散化位置式PID

1.2.3 位置式PID算法

2 STM32Cube 配置项目

2.1 配置参数

2.2 GENERATE项目

3 功能实现

3.1 ADC采样数据功能

3.2 DAC数据转换

3.3  PID相关的调制函数

4 测试

4.1 编写测试代码

4.2 运行结果


源代码下载地址:

使用PID算法实现DAC模拟量输出的快速调节资源-CSDN文库

概述

本文主要介绍一个PID在实际项目应用的案例,通过ADC采样DAC的输出结果,调整使其快速到达期望的结果,系统基于STM32F103RC,使用DAC输出模拟量,ADC采集该模拟量作为反馈信号,以实现系统的闭环控制。

1 系统框架和算法

1.1 框架结构介绍

MCU内核处理数据: 设置DAC的初始值,读取ADC模块反馈回来的数值,内部进行PID运算,并将运算结果发送给DAC模块,重新输出数据。

DAC输出模拟量: 经过MCU计算后,将运行结果通道DAC模块输出

ADC采集输出数据:ADC模块采集DAC输出的模拟量,将其转换为数据值,MCU应用该值和输出量进行比较,以确定是否还需要继续调节输出数值

1.2 PID算法实现

1.2.1 理论介绍

PID 算法是闭环控制系统中常用的算法, PID 分别是 Proportion(比例)、 Integral(积分)、
Differential(微分)的首字母缩写。它是一种结合比例、积分和微分三个环节于一体的闭环控制算法。具体的控制流程如下图所示:


通过将输入目标值和实际输出值进行偏差的计算,然后把计算结果输入到 PID控制算法中,经过比例、积分和微分三个环节的运算,运算后的输出作用于执行器,从而让系统的实际值逐渐靠近目标值。连续控制的理想 PID 控制规律:

• Kp      —— 比例增益, Kp 与比例度成倒数关系
• Tt       —— 积分时间常数
• TD     —— 微分时间常数
• u(t)—— PID 控制器的输出信号
• e(t)—— 给定值 r(t)与测量值误差

1.2.2  离散化位置式PID

对离散式的PID公式进行运算,则 u(k) 可表示为:

进一步进行简化,则得出PID的标准公式:

参数介绍

• k                        采样的序号
• err(k)                 第 k 次的误差
• u(k)                    输出量
• Kp                      比例参数
• Ki=Kp*T/Ti         积分参数
• Kd=Kp*Td/T       微分参数

1.2.3 位置式PID算法

typedef struct
{float target_val;       //目标值float actual_val;       //实际值float err;              //定义偏差值float err_last;         //定义上一个偏差值float Kp,Ki,Kd;         //定义比例、积分、微分系数float integral;         //定义积分值
}_pid;_pid pid_location;void pid_param_init(void)
{/* 位置相关初始化参数 */pid_location.target_val = 20;pid_location.actual_val=0.0;pid_location.err=0.0;pid_location.err_last=0.0;pid_location.integral=0.0;pid_location.Kp = 0.045;pid_location.Ki = 0.0;pid_location.Kd = 0.0;} float pid_location_realize(_pid *pid, float actual_val)
{/*计算目标值与实际值的误差*/pid->err=pid->target_val-actual_val;/* 设定闭环死区 */if((pid->err >= -20) && (pid->err <= 20)){pid->err = 0;pid->integral = 0;}pid->integral += pid->err;    // 误差累积/*PID算法实现*/pid->actual_val = pid->Kp*pid->err+pid->Ki*pid->integral+pid->Kd*(pid->err-pid->err_last);/*误差传递*/pid->err_last=pid->err;/*返回当前实际值*/return pid->actual_val;
}

2 STM32Cube 配置项目

2.1 配置参数

1)配置DAC参数,使用DAC2模块,选择PA5作为输出IO

DAC相关参数配置

2)配置ADC参数,选择ADC1,通道号为IN2

 ADC1参数配置

ADC1对应的DMA配置

 使能DMA1中断

 2.2 GENERATE项目

配置完成参数后,点击GENERATE生成项目,具体目录结构如下:

3 功能实现

端口介绍:

PA2: 模拟量ADC的输入端口

PA5: 模拟量DAC的输出端口

 3.1 ADC采样数据功能

实现功能: 

1)使能ADC模块

2)数据处理

3)DMA调用ADC相关的回调函数

typedef struct
{uint8_t sta         : 2;      //00: IELD, 01: Ready   02: Fail   11: unuseuint8_t res         : 6;
} Status_bit;typedef struct
{uint16_t adcRaw;union{uint8_t status;Status_bit  status_bit;};}Stru_GetAdc;static uint32_t adcDMAValue[2];
Stru_GetAdc struc_GetAdc;void ADC_ConvInit( ADC_HandleTypeDef* hadc )
{HAL_ADC_Start_DMA(hadc, adcDMAValue, 4);
}void ADC_HandleDataPackets( void )
{uint16_t adcvalueList[4];uint32_t value=0;adcvalueList[0] = adcDMAValue[0]&0x0000ffff;adcvalueList[1] = (adcDMAValue[0]>>16)&0x0000ffff;adcvalueList[2] = adcDMAValue[1]&0x0000ffff;adcvalueList[3] = (adcDMAValue[1]>>16)&0x0000ffff;value = 0;for( int i =0;  i< 4; i++ ){value +=  adcvalueList[i]; }struc_GetAdc.adcRaw =  value>>2;struc_GetAdc.status_bit.sta = 1;
}void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc)
{if(hadc->Instance == ADC1){HAL_ADC_Stop_DMA(hadc);                     // stop to convert adc value ADC_HandleDataPackets();HAL_ADC_Start_DMA(hadc, adcDMAValue, 4);    // start to convert adc value}
}

3.2 DAC数据转换

功能介绍:

设置对应通道需要转换的数字量

void DAC_SetConvert(DAC_HandleTypeDef *hdac, uint32_t Channel, uint16_t value)
{HAL_DAC_SetValue( hdac, Channel, DAC_ALIGN_12B_R,value );
}

3.3  PID相关的调制函数

代码73行: 获取当前ADC的值

代码74行:获取PID的期望值

代码75行: 比较期望值和实际值的误差

代码78行:使用当前的ADC值进行PID运算

代码80行:设置DAC的输出值

详细源代码:

void ADC_DAC_MatchByPID( void )
{bool is_match;uint32_t current_val,cal_value;{current_val = struc_GetAdc.adcRaw;cal_value = pid_get_target(&pid_speed);is_match = abs((int)((current_val- cal_value))) > 5 ? false : true;if( !is_match ){cal_value = pid_speed_realize(&pid_speed, current_val);cal_value = cal_value > MAX_VALE ? MAX_VALE: cal_value;DAC_SetConvert( &hdac, DAC_CHANNEL_2, cal_value );}printf("ADC Raw Count: %04d , voltage: %0.2f V \r\n",current_val, (current_val*3.3)/4096  );}
}

4 测试

4.1 编写测试代码

代码96行:初始化PID数据结构

代码97行:设置期望值

代码97行:设置P,I,D三个参数的值

详细源码:

void voltage_InitPara( void )
{pid_param_init();pid_set_target( &pid_speed, 3400);pid_set_para(&pid_speed, 0.5, 0.1, 0.1);
}

4.2 运行结果

编译代码,下载到板卡中运行.

测试1: 期望值RAW = 3400,误差delta < 5对应实际电压值V = 2.74V

稳定前的值:

稳定后的值:

测试2: 期望值RAW = 1400,误差delta < 5,对应实际电压值V = 1.12V 

void voltage_InitPara( void )
{pid_param_init();pid_set_target( &pid_speed, 1400);pid_set_para(&pid_speed, 0.5, 0.1, 0.1);
}

稳定前的值:

稳定后的值:

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

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

相关文章

基于YOLOv10深度学习的CT扫描图像肾结石智能检测系统【python源码+Pyqt5界面+数据集+训练代码】深度学习实战、目标检测

《博主简介》 小伙伴们好&#xff0c;我是阿旭。专注于人工智能、AIGC、python、计算机视觉相关分享研究。 ✌更多学习资源&#xff0c;可关注公-仲-hao:【阿旭算法与机器学习】&#xff0c;共同学习交流~ &#x1f44d;感谢小伙伴们点赞、关注&#xff01; 《------往期经典推…

第10天:字典和集合任务

学习内容&#xff1a; 字典的创建和操作集合的创建和操作 字典&#xff08;Dictionary&#xff09; 字典的创建 # 创建一个空字典 my_dict {}# 创建一个带有初始值的字典 my_dict {"name": "Alice", "age": 25, "city": "N…

【Python】已解决:ModuleNotFoundError: No module named ‘pyhanlp’

文章目录 一、分析问题背景二、可能出错的原因三、错误代码示例五、注意事项 已解决&#xff1a;ModuleNotFoundError: No module named ‘pyhanlp’ 一、分析问题背景 在使用Python进行自然语言处理时&#xff0c;有时我们可能会用到pyhanlp这个库&#xff0c;它是一个基于J…

【JVM】Java虚拟机运行时数据分区介绍

JVM 分区&#xff08;运行时数据区域&#xff09; 文章目录 JVM 分区&#xff08;运行时数据区域&#xff09;前言1. 程序计数器2. Java 虚拟机栈3. 本地方法栈4. Java 堆5. 方法区6. 运行时常量池7. 直接内存 前言 之前在说多线程的时候&#xff0c;提到了JVM虚拟机的分区内存…

HarmonyOS APP应用开发项目- MCA助手(Day01持续更新中~)

简言&#xff1a; gitee地址&#xff1a;https://gitee.com/whltaoin_admin/money-controller-app.git端云一体化开发在线文档&#xff1a;https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V5/agc-harmonyos-clouddev-view-0000001700053733-V5 注&#xff1…

MySQL 9.0 悄悄上线,支持面向AI的向量数据库

MySQL狂热粉丝群已经发现MySQL官网上MySQL9.0这两天悄然上线&#xff0c;已经可以下载体验了&#xff0c;目前被定义为创新版本&#xff08;Innovation&#xff09;。 下载地址&#xff1a;https://dev.mysql.com/downloads/mysql/ 支持主流的操作系统&#xff0c;安装后可以直…

DDD学习笔记六

基类与继承 领域模型中何时发掘和应用基类与继承&#xff1a; 1&#xff09;基类概念必须是通用语言的一部分&#xff0c;并且对应领域中的一个抽象概念。 2&#xff09;这个概念必须被进一步细化&#xff0c;才能具备实际业务含义。 3&#xff09;基类概念被细化的子类存在着不…

QT 线程计时器

qt自带的计时器QTimer是与界面主线程绑定在一起的&#xff0c;如果操作界面有可能会影响计时器的执行&#xff0c;所以查找一些资料写了一个长期运行的线程计时器。 1.线程类的头文件 #ifndef WORKTH_H #define WORKTH_H#include <QDebug> #include <QThread> #i…

分布式服务——注册中心

介绍 想象一下&#xff0c;一个繁忙的周末&#xff0c;阳光明媚&#xff0c;公园里的孩子们在尽情玩耍&#xff0c;大人们则坐在长椅上享受着难得的闲暇时光。突然&#xff0c;一个小女孩跑到一位陌生的先生面前&#xff0c;甜甜地说&#xff1a;“叔叔&#xff0c;你能不能帮…

论坛入门与提升

前言 明确设计思路&#xff0c;精准定位问题&#xff0c;对于我们后期理解迭代工程有很大的帮助。 这就是我们常说的40%设计&#xff0c;20%编写和剩下的40%时间进行调试优化。 今天为大家带来的是通过对论坛的深入了解&#xff0c;来解决大家遇到问题时的迷茫&#xff0c;合…

基于字符和词特征融合的恶意域名检测

传统的恶意域名检测方法在检测由域名生成算法&#xff08;DGA&#xff09;随机生成的恶意域名方面性能不佳&#xff0c;尤其是对于那些由随机单词组成的域名。文章提出了一种新的检测算法&#xff0c;通过融合字符和词特征来提高对恶意域名的检测能力&#xff0c;特别是对于更具…

SpringCloud基础篇

文章目录 创建新模块拷贝yml配置文件修改配置文件的信息修改pom.xml文件启动入口拷贝相关文件接口文档配置配置启动项注册中心原理Nacos注册中心创建nacos数据库存储数据部署nacos在docker容器中 服务注册引入依赖配置Nacos地址启动 服务发现(调用)引入依赖配置nacos地址发现并…

文章解读与仿真程序复现思路——电力系统自动化EI\CSCD\北大核心《面向电网调峰的电动汽车聚合商多层级实时控制策略》

本专栏栏目提供文章与程序复现思路&#xff0c;具体已有的论文与论文源程序可翻阅本博主免费的专栏栏目《论文与完整程序》 论文与完整源程序_电网论文源程序的博客-CSDN博客https://blog.csdn.net/liang674027206/category_12531414.html 电网论文源程序-CSDN博客电网论文源…

通过docker overlay2 目录名查找占用磁盘空间最大的容器名和容器ID

有时候经常会有个别容器占用磁盘空间特别大&#xff0c; 这个时候就需要通过docker overlay2 目录名查找占用磁盘空间最大的容器名和容器ID&#xff1a; 1、 首先进入到 /var/lib/docker/overlay2 目录下,查看谁占用的较多 [rootPPS-97-8-ALI-HD1H overlay2]# cd /var/lib/doc…

Linux基础 - MariaDB 数据库管理系统

目录 零. 简介 一. 安装 二. 基本使用 1. 设置root密码 2. 创建库 3. 创建表 4.添加数据 5. 查看数据 三. 管理表单及数据 四. 数据库的备份及恢复 零. 简介 MariaDB 是一种流行的开源数据库管理系统&#xff0c;它是 MySQL 的一个分支。 MariaDB 保留了与 MySQL 的…

CesiumJS【Basic】- #045 绘制流动线(Entity方式)- 需要自定义着色器

flow 文章目录 绘制流动线(Entity方式)- 需要自定义着色器1 目标2 代码2.1 main.ts绘制流动线(Entity方式)- 需要自定义着色器 1 目标 使用Entity方式绘制流动线 2 代码 2.1 main.ts import * as Cesium from cesium;const viewer = new Cesium

独一无二的设计模式——单例模式(python实现)

1. 引言 大家好&#xff0c;今天我们来聊聊设计模式中的“独一无二”——单例模式。想象一下&#xff0c;我们在开发一个复杂的软件系统&#xff0c;需要一个全局唯一的配置管理器&#xff0c;或者一个统一的日志记录器&#xff1b;如果每次使用这些功能都要创建新的实例&…

IDEA中Maven的配置

目录 1. 安装maven 2. 配置环境变量 3. IDEA中配置Maven 4. 配置仓库目录 1. 安装maven 官网下载地址&#xff1a;Maven – Download Apache Maven 下载后&#xff0c;将zip压缩包解压到某个目录即可。 2. 配置环境变量 变量名称随意&#xff0c;通常为M2_HOME&#xff…

【INTEL(ALTERA)】nios调试器中的重新启动按钮不起作用

目录 说明 解决方法 说明 在 Nios II SBT 调试Eclipse时&#xff0c;如果单击 重新启动 图标&#xff0c; 执行被暂停&#xff0c; 以下错误消息&#xff1a; Dont know how to run. Try "help target." 解决方法 终止程序&#xff0c;再次下载&#xff0c;并启…

MySQL/SqlServer 跨服务器 增删改查(CRUD) 的一种方法

前言&#xff1a;主要是利用SqlServer 的链接服务器功能 1.准备一台 SqlServer Server&#xff0c;服务如下图&#xff1a; 这台服务器专门用于 链接服务器 IP&#xff1a;10.x.x.3 和数据源服务器&#xff08;10.x.x.5&#xff09; 在一个局域网 1.1 版本 是 2017 2.在 10.…