OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 14955|回复: 30

分享一个STM32F103+DAC+ADC实现闭环PID调节的例子

[复制链接]

0

主题

89

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1286
金钱
1286
注册时间
2020-4-7
在线时间
309 小时
发表于 2020-4-12 19:14:24 | 显示全部楼层 |阅读模式
本帖最后由 lv浅陌 于 2020-4-12 19:20 编辑

        最近看到了PID相关的知识,想来试着调一下,学习学习,PID在工业控制,日常生活中有许许多多的用途。为了调节起来更加的方便,就想着先在没有其他外设的情况下,利用STM32F103ZET6芯片自带的DAC用作输出,ADC用来采集检测DAC的输出,为了模拟真正的使用过程,还使用定时器3做了一个中断,是输出减小,模拟现实的情况。做一个闭环的PID调节实验。
一. PID的简单介绍:
        PID调节是一种调节算法,至今已经有70多年的历史,其中P是Proportional(比例)的简称,I是Integral(积分)的简称,D是Derivative(微分)的简称。其调节过程原理是将系统的输出进行一定的运算处理之后作用于输入,起到影响到输入,从而改变输出的作用。调节过程如下:
原理.png


       基本调节公式为:
公式.jpg
       在很多情况下,仅仅需要离散化PID调节时,可以将PID调节公式离散化为:
1586687621(1).jpg
      这么看是不是清晰了很多。
二. PID各个参数的作用
       PID中的P是比例运算,可以将系统的误差快速的缩小,向着目标值靠近。但是只有P调节的时候系统可能会存在静差,因为多数情况下,系统是存在能量损耗的,例如骑车的前进,需要克服摩擦力;一个水箱,如果往里面加水,如果这个水箱还在漏水等。这个时候,就可能存在P调节的情况下,系统到达不了目标值。在我的实验中,我使用定时器中断,减小输出来模拟现实情况。这个就是静差(下面会具体说明为什么达到不了)。
      I是积分运算,主要是用来消除系统存在的静差。
      D是微分运算,主要是起到一个阻尼作用,减小系统的震荡。使得系统的输出更加的线性。
三. PID参数的调节。
      看的很多资料,上面都把PID参数的调节叫做PID参数的整定。(别问为什么,问就是为了显得专业)。
      P的整定:先设定一个很小的P值,然后慢慢的增大,观察系统的输出。随着P的增加,在有负功的系统中,系统输出会渐渐到达一个稳定的值,波动较小。但是这个值还没有到达目标值。也就是出现了静差。系统输出过程如下:
P.jpg

我设置的目标值为3000,系统输出达到2964时到达了稳定状态。为什么会出现这样,是因为这时我的P值为1.4,系统当前的误差为36,36×1.4=50.4  ,我设置的定时器中断为400ms,PID调节时间为500ms调节一次,定时器3中断时,输出会减小50.如果考虑到这个减小。系统当前的误差0.4.我选取的是整形调节,那么误差会变成0.这时P调节不起作用,也就出现了静差。怎么消除这个静差。需要进行I的整定。
      I的整定。
      I整定时,会消除系统的误差,I是积分作用,积分是求和。当比例输出在没有误差的情况下输出为0时,就得利用I来产生一个稳定的误差,消除系统的静差,让系统达到目标值。I参数加加大,系统会减小静差。I值为0.1时。慢慢达到目标值(I值不可设置的过大,否则会使系统失控)。I作用下系统的输出过程如下:
PI.jpg
       D的整定:
       I整定后,我们可以看到,系统消除了静差,输出慢慢达到了目标值,但是在刚到达目标值附近时会出现一个较大的震荡,为了消除这个震荡就需要使用D参数的阻尼作用,是系统输出更加的稳定顺滑。D值为0.01时。系统达到最好的状态。D值加入时,系统的输出过程如下:
PID.jpg
       可以看到基本达到实验需求,系统的输出顺滑稳定。PID的整定过程也基本完成。

       目前为止,本人对PID 的调节还了解甚少,特附上源码,希望能与大家一起交流学习。









STM32F103ZET6+DAC+ADV PID实验.zip

312.09 KB, 下载次数: 1469

正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

31

主题

156

帖子

0

精华

高级会员

Rank: 4

积分
723
金钱
723
注册时间
2020-4-30
在线时间
109 小时
发表于 2020-9-12 09:06:29 | 显示全部楼层
爱写bug的小航 发表于 2020-8-11 15:03
同问,层主有头绪了还请告知

关于你这个问题 我觉得我应该是看明白了 前面一个判断是否大于600和小于-600  以及后面的判断是否大于200其实都是为了避免PID输出变化过快  但是楼主的代码里有一个很明显的错误是  他用的是增量式PID算法  但是他却用到了sumERROR  这个应该是用在位置式PID算法里的  还有一个问题就是  在楼主的工程里  PID的输出只会越来越大  因为他的一句else if (mid_pid_val<0)   mid_pid_val=0    这完全就断了PID输出往变小方向变化的后路  
回复 支持 2 反对 0

使用道具 举报

4

主题

177

帖子

0

精华

高级会员

Rank: 4

积分
656
金钱
656
注册时间
2019-7-28
在线时间
60 小时
发表于 2020-4-14 09:37:43 | 显示全部楼层
PID参数调不好的可以找我,告诉我系统情况,基本一次搞定参数
回复 支持 1 反对 1

使用道具 举报

0

主题

8

帖子

0

精华

初级会员

Rank: 2

积分
172
金钱
172
注册时间
2013-5-18
在线时间
52 小时
发表于 2020-4-13 10:59:21 | 显示全部楼层
谢谢分享!1
回复 支持 反对

使用道具 举报

31

主题

2183

帖子

0

精华

资深版主

Rank: 8Rank: 8

积分
14363
金钱
14363
注册时间
2018-8-3
在线时间
1155 小时
发表于 2020-4-13 11:30:55 | 显示全部楼层
赞  谢谢分享
回复 支持 反对

使用道具 举报

0

主题

50

帖子

0

精华

高级会员

Rank: 4

积分
710
金钱
710
注册时间
2019-3-5
在线时间
168 小时
发表于 2020-4-15 13:47:40 | 显示全部楼层
谢谢分享
回复 支持 反对

使用道具 举报

28

主题

92

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
462
金钱
462
注册时间
2019-3-30
在线时间
86 小时
发表于 2020-4-16 13:58:10 | 显示全部楼层
谢谢,谢谢分享,最近学东西,刚好想用一下,,,牛牛
回复 支持 反对

使用道具 举报

0

主题

14

帖子

0

精华

初级会员

Rank: 2

积分
63
金钱
63
注册时间
2018-4-11
在线时间
12 小时
发表于 2020-4-23 09:04:48 | 显示全部楼层
谢谢分享,!!!
回复 支持 反对

使用道具 举报

0

主题

1

帖子

0

精华

新手入门

积分
2
金钱
2
注册时间
2020-5-5
在线时间
0 小时
发表于 2020-5-5 18:27:04 | 显示全部楼层
有PID的程序源码吗
回复 支持 反对

使用道具 举报

0

主题

4

帖子

0

精华

新手上路

积分
42
金钱
42
注册时间
2019-5-2
在线时间
12 小时
发表于 2020-5-6 21:37:15 | 显示全部楼层
while(1)里面的:

adc1_next_val=PID_Cal(&pp,adc1_now_val);
adc1_next_val=adc1_next_val+adc1_now_val;

这两行代码我可以理解为是增量式PID吗?
回复 支持 反对

使用道具 举报

0

主题

1

帖子

0

精华

新手入门

积分
2
金钱
2
注册时间
2020-5-12
在线时间
0 小时
发表于 2020-5-12 11:31:20 | 显示全部楼层
有PID的源码吗?
回复 支持 反对

使用道具 举报

0

主题

8

帖子

0

精华

初级会员

Rank: 2

积分
129
金钱
129
注册时间
2016-4-9
在线时间
14 小时
发表于 2020-5-14 22:00:42 | 显示全部楼层
谢谢大神分享,最近在学DAC,刚好借用一下
回复 支持 反对

使用道具 举报

0

主题

1

帖子

0

精华

新手入门

积分
15
金钱
15
注册时间
2020-3-26
在线时间
5 小时
发表于 2020-5-26 23:45:59 | 显示全部楼层
谢谢嘻嘻嘻嘻嘻嘻嘻
回复 支持 反对

使用道具 举报

0

主题

11

帖子

0

精华

新手上路

积分
33
金钱
33
注册时间
2020-5-11
在线时间
8 小时
发表于 2020-6-22 14:22:16 | 显示全部楼层
谢谢,谢谢分享,最近学东西,刚好想用一下,,,牛牛
回复 支持 反对

使用道具 举报

0

主题

3

帖子

0

精华

新手上路

积分
32
金钱
32
注册时间
2020-7-17
在线时间
7 小时
发表于 2020-7-23 10:18:04 | 显示全部楼层
你好,可以说一下整个工作流程嘛,怎么做的。
回复 支持 反对

使用道具 举报

0

主题

3

帖子

0

精华

新手上路

积分
32
金钱
32
注册时间
2020-7-17
在线时间
7 小时
发表于 2020-7-23 17:38:20 | 显示全部楼层
if(pp->sumERROR>600)
                         pp->sumERROR=600;
                 if(pp->sumERROR<-600)
                         pp->sumERROR=-600;
                 。。。。。。。。。。。
                if(mid_pid_val>200)
                      mid_pid_val=200;这里为什么要判断600和-600,pid算出来的为什么是选择大于200。

回复 支持 反对

使用道具 举报

1

主题

2

帖子

0

精华

新手入门

积分
12
金钱
12
注册时间
2020-7-27
在线时间
2 小时
发表于 2020-7-27 15:23:18 | 显示全部楼层
谢谢分享@
回复 支持 反对

使用道具 举报

1

主题

16

帖子

0

精华

初级会员

Rank: 2

积分
51
金钱
51
注册时间
2020-7-28
在线时间
16 小时
发表于 2020-8-11 15:03:51 | 显示全部楼层
这么大辣条 发表于 2020-7-23 17:38
if(pp->sumERROR>600)
                         pp->sumERROR=600;
                 if(pp->sumERRORsumERROR=-600;

同问,层主有头绪了还请告知
回复 支持 反对

使用道具 举报

0

主题

1

帖子

0

精华

新手上路

积分
31
金钱
31
注册时间
2020-5-16
在线时间
9 小时
发表于 2020-8-17 20:37:30 | 显示全部楼层
爱写bug的小航 发表于 2020-8-11 15:03
同问,层主有头绪了还请告知

同问,是不是人为设定的阈值怕系统失控,层主有头绪了还请告知
回复 支持 反对

使用道具 举报

0

主题

12

帖子

0

精华

初级会员

Rank: 2

积分
148
金钱
148
注册时间
2018-11-26
在线时间
29 小时
发表于 2020-8-18 11:14:35 | 显示全部楼层
想问一下作者,您贴图上去的是运行代码之后从keil里面仿真出来的图片吗?
回复 支持 反对

使用道具 举报

0

主题

32

帖子

0

精华

初级会员

Rank: 2

积分
184
金钱
184
注册时间
2020-7-29
在线时间
40 小时
发表于 2020-8-24 19:33:38 | 显示全部楼层
谢谢分享
回复 支持 反对

使用道具 举报

1

主题

54

帖子

0

精华

初级会员

Rank: 2

积分
125
金钱
125
注册时间
2018-7-7
在线时间
20 小时
发表于 2020-9-12 17:22:34 | 显示全部楼层
学习学习
回复 支持 反对

使用道具 举报

0

主题

3

帖子

0

精华

新手入门

积分
16
金钱
16
注册时间
2020-9-11
在线时间
5 小时
发表于 2020-10-3 15:11:52 | 显示全部楼层
2721978231 发表于 2020-9-12 09:06
关于你这个问题 我觉得我应该是看明白了 前面一个判断是否大于600和小于-600  以及后面的判断是否大于200 ...

赞同此回答PID算法中对于增量式和位置式的理解。楼主在PID算法中用的是位置式的公式,但是在while(1)中却应用了增量式中的累加,楼主概念理解错误。
回复 支持 反对

使用道具 举报

0

主题

89

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1286
金钱
1286
注册时间
2020-4-7
在线时间
309 小时
 楼主| 发表于 2020-11-6 14:27:45 | 显示全部楼层
2721978231 发表于 2020-9-12 09:06
关于你这个问题 我觉得我应该是看明白了 前面一个判断是否大于600和小于-600  以及后面的判断是否大于200 ...

多谢指正。
回复 支持 反对

使用道具 举报

0

主题

1

帖子

0

精华

新手入门

积分
8
金钱
8
注册时间
2020-5-3
在线时间
2 小时
发表于 2021-1-3 18:26:30 | 显示全部楼层
感谢大佬分享
回复 支持 反对

使用道具 举报

1

主题

232

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
3328
金钱
3328
注册时间
2015-4-19
在线时间
366 小时
发表于 2021-4-27 13:56:29 | 显示全部楼层
谢谢分享!
回复 支持 反对

使用道具 举报

2

主题

14

帖子

0

精华

初级会员

Rank: 2

积分
72
金钱
72
注册时间
2021-4-20
在线时间
10 小时
发表于 2021-5-2 17:06:05 | 显示全部楼层
mark 标记标记
回复 支持 反对

使用道具 举报

0

主题

5

帖子

0

精华

新手上路

积分
40
金钱
40
注册时间
2014-10-14
在线时间
4 小时
发表于 2022-1-22 11:02:48 | 显示全部楼层
很好,灰常感谢!
回复 支持 反对

使用道具 举报

5

主题

312

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1817
金钱
1817
注册时间
2018-11-28
在线时间
226 小时
发表于 2023-6-12 20:25:28 | 显示全部楼层
谢谢分享
回复 支持 反对

使用道具 举报

2

主题

62

帖子

0

精华

高级会员

Rank: 4

积分
711
金钱
711
注册时间
2019-5-17
在线时间
273 小时
发表于 2023-6-24 13:50:26 | 显示全部楼层
glenxu 发表于 2020-4-14 09:37
PID参数调不好的可以找我,告诉我系统情况,基本一次搞定参数

可以帮我看看嘛  PID调参相关
回复 支持 反对

使用道具 举报

28

主题

360

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1028
金钱
1028
注册时间
2021-2-4
在线时间
146 小时
发表于 2023-12-7 14:38:42 | 显示全部楼层
这个图怎么做的
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-2-24 09:14

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表