panxiaoyi 发表于 2012-10-4 00:54:04

发一个简单的山寨版PID控制例子

本帖最后由 panxiaoyi 于 2012-10-4 00:51 编辑

/*****************************************************
CodeWizardAVR V1.25.6 Professional
Chip type         : ATmega48
Clock frequency   : 8 MHz
Memory model      : Small
External SRAM size: 0
Data Stack size   : 128
*****************************************************/

#include <mega48.h>
#include <delay.h>
#include <adc.h>
#include <nokia3310.h>

#define ADC   100                                       //ADC目标读数(相当于目标电压)
#define kp    9                                           //P系数/请小心全局数据溢出!
#define ki    1                                           //I系数/取消则I=0
#define kd    3                                           //D系数/取消则D=0

unsigned int adc_data;
int wc0, wc1,wc2, xz, pwm;                              //当前,上次,再上次的误差,修正,输出

void main(void)
{
TCCR1A=0b10000001;                                    //OCR1A正比例PWM/相位修正模式
TCCR1B=0b00000001;                                    //时钟1分频
OCR1AL=0;                                             //PWM占空比调整0-255   
DDRB.1=1;                                             //输出PWM
lcd_init(); lcd_cls();                                  //LCD初始化
while (1)
{
    delay_ms(98);                                       //简易的间隔检测时间设定
    adc_start(5);                                       //启动某通道ADC/参考电压5V/8bit
    adc_data=adc_read();                                  //等待和读结果/电压=ADC_DATA*98/5
   
    wc2=wc1;
    wc1=wc0;
    wc0=ADC-adc_data;                                     //误差值=目标值-当前值
    xz=wc0*kp+(wc0+wc1+wc2)*ki+((wc0-wc1)-(wc1-wc2))*kd;//修正值=比例放大+积分放大+微分放大
    pwm=pwm+xz;                                           //输出值=旧数值+修正值
    if(pwm>255) pwm=255; if(pwm<0) pwm=0;               //输出值限幅
    OCR1AL=pwm;
         
    lcd_gotoxy(0,1);                                    //LCD显示
    lcd_putsf("PWM:",4); lcd_putbyte(OCR1AL);
    lcd_gotoxy(0,3);
    lcd_putsf("ADC:",4); lcd_putbyte(adc_data);
};
}

如下图:
单片机通过PWM输出供电,驱动3个串联电阻,其中50K是一个电位器,人为不断的旋动电位器,来模拟负载无规律的变化。
目标要求:100uF电容两端的电压不受负载的影响,即ADC读数要求稳定在100左右。
大概的输出电压mV = 5000mV * ADC读数 / 255
调整 P、I、D 这三个系数,还有调整间隔检测时间,即可调整负载电压的稳定度和皱纹度。

本例比较简单,没有多少语句,且都是16位的整数运算,适合8位单片机运行,但是它并没有按照PID的公式来套(说实话我对那些公式也是一知半解),它只是按照PID的思路来工作而已,所以,这个程序只能说是山寨程序,适合要求不高的场所。还好,它的语句短、运行速度特快

shower.xu 发表于 2012-10-4 07:53:17

Mark一下,谢谢分享,有机会的话试一下

wcm_e 发表于 2012-10-4 07:57:45

有意思,学习了

stm8s 发表于 2012-10-4 09:09:28

这样的资料很好,很亲民!比那些砖家叫兽的论文强多了!

zigonghlt 发表于 2012-10-4 10:43:35

细读了下程序,感觉很实用,改天有空做个样品放到工业场所看下实际运行效果。

zgbkdlm 发表于 2012-10-4 10:49:45

确实挺不错的~

ydprtm 发表于 2012-10-4 11:02:50

嗯,Mark。
改天试试效果。

sandao 发表于 2012-10-5 17:27:47

简单明了,没有多余的语句····

vjcmain 发表于 2012-10-5 17:42:20

学习了,呵呵

f117_2r 发表于 2012-10-5 19:05:00

楼主你的网站怎么不搞了,现在还有没有串口的STK500

hpdell 发表于 2012-10-5 19:45:18

f117_2r 发表于 2012-10-5 19:05 static/image/common/back.gif
楼主你的网站怎么不搞了,现在还有没有串口的STK500

本论坛有大量STK500的制作资料

eddia2012 发表于 2012-10-5 20:03:41

楼主
电路有实际测试过吗?

senbaby2 发表于 2012-10-6 09:48:23

学习学习

yishengjun2012 发表于 2012-10-6 14:13:30

简单明了,学习一下,多谢楼主。

lcmdw 发表于 2012-10-6 17:12:54

amrk{:smile:}

panxiaoyi 发表于 2012-10-6 17:18:26

已经通过实际电路测试过的,还有LCD辅助显示观测,效果很好。
1:先测试逐步调整(检测电压不够,PWM+1,第二次检测不够,PWM再+1,反之,PWM-1,以此类推)
2:测试比例调整,就是调整P系数,I、D 两个系数设为0
3:测试PID调整
结果,PID最好,其次P调整,逐步调整最差。

maimaige 发表于 2012-10-6 17:20:42

这个是用ATmega48实现的?,它内部有ADC模块?

maimaige 发表于 2012-10-6 17:21:42

mark 学习一下

panxiaoyi 发表于 2012-10-6 17:26:10

f117_2r 发表于 2012-10-5 19:05 static/image/common/back.gif
楼主你的网站怎么不搞了,现在还有没有串口的STK500

你好,我转行好多年了,现在玩电子只是月余爱好而已

panxiaoyi 发表于 2012-10-6 17:36:39

本帖最后由 panxiaoyi 于 2012-10-6 17:49 编辑

小提示,假设P系数要设为0.85,而又不想使用浮点运算,可以这样 :
1:当前误差*85/100
2:如果 最大当前误差*85 有可能使变量溢出的话,可以:当前误差*17/20
这样做的好处是代码量小,运行速度快,缺点是 精确度、准确度 偏差一点。

panxiaoyi 发表于 2012-10-6 17:38:06

maimaige 发表于 2012-10-6 17:20 static/image/common/back.gif
这个是用ATmega48实现的?,它内部有ADC模块?

是M48,有ADC

52robot 发表于 2012-10-6 18:01:37

楼主亲测,哈哈

qd118118 发表于 2012-10-6 18:46:34

好例子,下来仔细看看

Bicycle 发表于 2012-10-6 18:49:40

偶路过友情顶下帖

szxszx 发表于 2012-10-6 19:19:08

支持一下

our2008 发表于 2012-10-6 19:44:00

好东西 !收藏

stely 发表于 2012-10-9 08:40:25

mark 学习

slayer_ni 发表于 2012-10-9 11:39:56

有意思,学习了

bai2011 发表于 2012-10-9 21:24:32

学习下谢谢分享!

kkkkyx 发表于 2012-10-10 15:01:57

不错,正需要

MINI2440 发表于 2012-10-10 15:21:43

mark                很好

summarize 发表于 2012-10-10 15:55:51

公式: xz=wc0*kp+(wc0+wc1+wc2)*ki+((wc0-wc1)-(wc1-wc2))*kd; 中的: ((wc0-wc1)   -    (wc1-wc2))*kd,为什么不是:((wc0-wc1)   +    (wc1-wc2))*kd,即两次微分求和?(wc0+wc1+wc2)*ki就比较好理解-积分即累加求和.

hbzxx 发表于 2012-10-11 10:26:29

好文,谢谢分享{:victory:}

panxiaoyi 发表于 2012-10-14 10:54:38

summarize 发表于 2012-10-10 15:55 static/image/common/back.gif
公式: xz=wc0*kp+(wc0+wc1+wc2)*ki+((wc0-wc1)-(wc1-wc2))*kd; 中的: ((wc0-wc1)   -    (wc1-wc2))*kd,为 ...

搞这个东西,我们不能只看文字,还要动手画图才会有比较好的理解,如下图。
图a的误差是一条直线,说明误差不断的在变大,但是,它每次变大的数值与之前一次比较都是一样的
就是 (wc0-wc1)-(wc1-wc2) = 0 ,也就是说,这个变化不需要PID的D调整。
图b的误差是一条曲线,说明误差一次比一次大,显然,我们调整的力度也需要一次比一次大,最好是超前调整
这时 (wc0-wc1)-(wc1-wc2) 〉0 ,也就是说,这个变化需要PID的D调整,即超前调整

panxiaoyi 发表于 2012-10-14 11:11:56

误差变量是“有符号”整数,它同样适合误差全部是负数,或者有负数有正数的混合运算,这个在理解上可能会复杂一点点

summarize 发表于 2012-10-14 22:42:20

panxiaoyi 发表于 2012-10-14 11:11 static/image/common/back.gif
误差变量是“有符号”整数,它同样适合误差全部是负数,或者有负数有正数的混合运算,这个在理解上可能会复 ...

谢谢您的解答!

marshallemon 发表于 2012-10-14 23:04:38

这个是使用增量式的pid吧,怎么感觉公式有点不对头?

wpnx 发表于 2012-10-14 23:12:49

简单有效

Delong_z 发表于 2012-11-1 11:23:53

xz=wc0*kp+(wc0+wc1+wc2)*ki+((wc0-wc1)-(wc1-wc2))*kd;//修正值=比例放大+积分放大+微分放大

积分部分只有连续3次误差之和,如何理解?增量式积分?

tranquilly86 发表于 2012-11-1 11:30:58

好东西{:victory:}

jackiezeng 发表于 2012-11-1 11:44:07

这个可以研究哈,,,,比以前那些例子好很多,

wcm_e 发表于 2012-11-1 14:34:03

mark , 谢谢

cdust 发表于 2012-11-1 21:08:28

记号,什么时候用下

eryueniao 发表于 2012-11-1 21:24:41

cool                                                                        

AVRTDK 发表于 2012-11-2 00:53:35


谢谢,参考一下

phone 发表于 2012-11-2 09:11:00

有空也试试。

beyond870215 发表于 2012-11-2 09:44:26

有意思,学习了

YS126 发表于 2012-11-2 10:07:29

保存先,以后有用

ls81250 发表于 2012-11-2 10:11:16

程序简单,谢谢分享

Randy1022 发表于 2012-11-2 10:17:53

非常实用哦,我等小白很适合!

panxiaoyi 发表于 2012-11-2 20:49:00

Delong_z 发表于 2012-11-1 11:23 static/image/common/back.gif
xz=wc0*kp+(wc0+wc1+wc2)*ki+((wc0-wc1)-(wc1-wc2))*kd;//修正值=比例放大+积分放大+微分放大

积分部分 ...

只有 wc0 wc1 wc2,是从节省单片机资源来考虑的,当然,有更多次数的误差累积更好,还有使用实数变量也更好,只是,程序会变得复杂,运行会变慢,代码也会变大。
至于什么是增量式,我还真的不懂,我在1楼上是这样说的
“本例比较简单,没有多少语句,且都是16位的整数运算,适合8位单片机运行,但是它并没有按照PID的公式来套(说实话我对那些公式也是一知半解),它只是按照PID的思路来工作而已,所以,这个程序只能说是山寨程序,适合要求不高的场所。还好,它的语句短、运行速度特快”
呵呵,献丑了

cdwess 发表于 2012-11-2 23:30:26

呵呵,我把楼主的程序变形了下,做成子程序,对象是控制直流电机电压,计算可控硅导通角,还没调试通,还在调试中,先谢谢楼主分享了
/*-----------------------------------------------------------------
函数名称: void PID(void)
函数功能: 行走电机电压控制
参    数: 入口行走电压
返 回 值: pwm调节
说    明: Iv为给定,adc_data为实际值
      int wc0,wc1,wc2, xz, pwm;    //当前,上次,再上次的误差,修正,输出
-----------------------------------------------------------------*/
uchar PID_xz(uchar Iv,uchar adc_data)
      {   
              static int wc0,wc1,wc2,xz,pwm; //当前,上次,再上次的误差,修正,输出
          uchar kp=1;                  //P系数/请小心全局数据溢出!9
          uchar ki=1;                  //I系数/取消则I=0          1
          uchar kd=0;                  //D系数/取消则D=0          3
         
      wc2=wc1;
      wc1=wc0;
      wc0=Iv-adc_data;                                    //误差值=目标值-当前值
      xz=wc0*kp+(wc0+wc1+wc2)*ki+((wc0-wc1)-(wc1-wc2))*kd;//修正值=比例放大+积分放大+微分放大
      pwm=pwm+xz;                                           //输出值=旧数值+修正值
      if(pwm>256)pwm=200; if(pwm<0)pwm=0;                   //输出值限幅
      return pwm;
      }

xxoo14 发表于 2012-11-2 23:45:35

panxiaoyi 发表于 2012-10-14 10:54 static/image/common/back.gif
搞这个东西,我们不能只看文字,还要动手画图才会有比较好的理解,如下图。
图a的误差是一条直线,说明误 ...

不错,好好学习一下

xxoo14 发表于 2012-11-2 23:46:03

cdwess 发表于 2012-11-2 23:30 static/image/common/back.gif
呵呵,我把楼主的程序变形了下,做成子程序,对象是控制直流电机电压,计算可控硅导通角,还没调试通,还在 ...

这个更牛呀

xxoo14 发表于 2012-11-2 23:48:17

正在弄步进电机加速算法 ,不错,

kxm2008 发表于 2012-11-3 09:36:46

不错,谢了

liujinhan 发表于 2012-11-3 09:55:46

mark 顶                     

司马朝阳007 发表于 2012-11-3 10:20:06

简单有效

cdwess 发表于 2012-11-4 21:05:54

{:smile:}非常不错的东西啊

acai039033 发表于 2012-11-5 11:07:24

好东西,对学习PID有帮助

llluomengran 发表于 2012-11-8 19:23:34

学习了 谢谢{:smile:}{:smile:}

zzj2009a1 发表于 2012-11-9 13:58:19

不错,学习了

chenbelief_007 发表于 2012-11-11 14:38:11

楼主用的是增量PID吧 ,简单易懂 ,就是不知道精度怎么样。 顶一个{:smile:}{:smile:}{:smile:}

fangmcu 发表于 2012-11-11 15:16:58

感谢楼主,亲民的PID,我等小菜受教了!!!

zhenglingo 发表于 2012-11-15 20:42:26

楼主能留下扣扣吗?我也正在学习这个遇到很多问题想要请教你,谢谢

panxiaoyi 发表于 2012-11-15 20:53:47

zhenglingo 发表于 2012-11-15 20:42 static/image/common/back.gif
楼主能留下扣扣吗?我也正在学习这个遇到很多问题想要请教你,谢谢

呵呵,我从来就不太喜欢QQ聊天的

zhenglingo 发表于 2012-11-15 20:55:19

panxiaoyi 发表于 2012-11-15 20:53 static/image/common/back.gif
呵呵,我从来就不太喜欢QQ聊天的

哪在这问你篇幅太长啊也不方便啊

zhenglingo 发表于 2012-11-15 21:07:29

zhenglingo 发表于 2012-11-15 20:55 static/image/common/back.gif
哪在这问你篇幅太长啊也不方便啊

我就是想请教你一些关于PWM输出PIDAD 等遇到的问题开始时和我宿舍的同学一起去参加了个四轴的比赛 那时候真的没有珍惜好机会所以没学到什么东西不过或多或少学到一些   所以打算模拟下PID 控制PWM输出然后AD采集很楼主的几乎一模一样而在当中我遇到了很多问题希望和楼主多多交流谢谢

zhenglingo 发表于 2012-11-15 21:12:51

panxiaoyi 发表于 2012-11-15 20:53 static/image/common/back.gif
呵呵,我从来就不太喜欢QQ聊天的

楼主还在吗?

panxiaoyi 发表于 2012-11-15 21:15:08

楼上,有什么事就论坛说吧,这里有很多热心人的

yuyu87 发表于 2012-11-15 21:24:09

简单明了! 不错。。。。。。

zhenglingo 发表于 2012-11-15 21:43:38

panxiaoyi 发表于 2012-11-15 21:15 static/image/common/back.gif
楼上,有什么事就论坛说吧,这里有很多热心人的

好 吧哪我将我的问题贴上楼主多多指点啊
在AD模块上我根据数据手册上的信息需要将IO口先设置成高阻状态或者开漏状态(STC12C5A60S2的片子)但是用这个带AD功能的IO去采集模拟PWM输出的IO,结果我先用电压表测量采集值和输出的值相差很大不知道是否是因为万用表采集频率低无法动态显示变化的值   
模拟PWM的输出我的程序是
sbit PWM_IO = P0^0 ;   
externINT16U TimeCounter ;
void pwm(INT16U PWM)
{
        staticINT16U LedPWMCounter = 0 ; // PWM_IO占空比
        staticINT16U PWMCounter = 0 ;
      
        if(TimeCounter > 256) //每50MS 调整一下 PWM_IO 的占空比
      {      
                                           
             TimeCounter = 0;
             LedPWMCounter = PWM ;

             if(LedPWMCounter > 257)
          {
             LedPWMCounter = 257 ;
          }
             if(LedPWMCounter < 0)
          {
                                                                       
              LedPWMCounter = 0 ;
          }
                                                                                                                                    PWMCounter = LedPWMCounter ; //获取LED 的占空比
       }
                               
          if( PWMCounter > 0)        
                   {
             PWM_IO = 1 ;
             PWMCounter--;
          }
           else
       {
             PWM_IO = 0 ;
       }
               }
}
void Time0Isr(void) interrupt 1
{   
          
        TH0 = (65536 - 195) / 256 ; //定时器重新赋初值
        TL0 = (65536 - 195) % 256 ;

        TimeCounter++;
        pwm(Pwm) ;
          
}

                               
                               

zhenglingo 发表于 2012-11-15 21:48:00

zhenglingo 发表于 2012-11-15 21:43 static/image/common/back.gif
好 吧哪我将我的问题贴上楼主多多指点啊
在AD模块上我根据数据手册上的信息需要将IO口先设置成 ...

sbit PWM_IO = P0^0 ;   
externINT16U TimeCounter ;
void pwm(INT16U PWM)
{
      staticINT16U LedPWMCounter = 0 ; // PWM_IO占空比
      staticINT16U PWMCounter = 0 ;
      
      if(TimeCounter > 256) //每50MS 调整一下 PWM_IO 的占空比
      {      
                                             
               TimeCounter = 0;
               LedPWMCounter = PWM ;

               if(LedPWMCounter > 257)
          {
               LedPWMCounter = 257 ;
          }
               if(LedPWMCounter < 0)
          {
                                                                        
            LedPWMCounter = 0 ;
          }
            PWMCounter = LedPWMCounter ; //获取LedPWMCounter的占空比
      }
                                                                                                                              }
                              
            if( PWMCounter > 0)         
                   {
             PWM_IO = 1 ;
             PWMCounter--;
          }
         else
         {
             PWM_IO = 0 ;
         }
            }
void Time0Isr(void) interrupt 1
{   
         
      TH0 = (65536 - 195) / 256 ; //定时器重新赋初值
      TL0 = (65536 - 195) % 256 ;

      TimeCounter++;
      pwm(Pwm) ;
         
}

PWM是这个问题可能有我测试过不加AD采集能根据输入的占空比来显示出电压

zhenglingo 发表于 2012-11-15 22:10:41

panxiaoyi 发表于 2012-11-15 21:15 static/image/common/back.gif
楼上,有什么事就论坛说吧,这里有很多热心人的

楼主能否帮我解答下呢?谢谢

miyadai 发表于 2012-11-16 09:12:24

很好,楼主是高手~~

cash95 发表于 2012-11-16 10:25:04

这个是正常的pid算法
wc0*kp这个是比例控制的值,后面两个来修正这个值。
(wc0+wc1+wc2)*ki误差越大调整力度越大
((wc0-wc1)-(wc1-wc2))*kd;数据趋势,决定调整值的正负

主要是kp,ki,kd的值不好确定,有个牛逼的自整定算法就好了。

avrydy 发表于 2012-11-16 19:08:56

果然强大,哈哈,简单明了,干脆利落

shiyingyifan 发表于 2012-11-16 21:42:49

值得收藏的资料

panxiaoyi 发表于 2012-11-16 23:02:17

zhenglingo 发表于 2012-11-15 22:10 static/image/common/back.gif
楼主能否帮我解答下呢?谢谢

对不起,我帮不了你,因为我看不懂你的代码,也没有用过这个片子,不过,你的代码好像与PID也扯不上什么关系

zhenglingo 发表于 2012-11-16 23:21:53

panxiaoyi 发表于 2012-11-16 23:02 static/image/common/back.gif
对不起,我帮不了你,因为我看不懂你的代码,也没有用过这个片子,不过,你的代码好像与PID也扯不上什么 ...

这只是PWM部分啊,我用的是PID去控制PWM输出,然后用AD去采集   我用的是51的单片机    目前我的模块就是用电压表测的电压与用串口显示出来的电压区别有点大而且串口上电压是动态变化的 这个也好理解   但是万用表上测的是静态的这种情况是否为万用表采样率太低呢 无法读会变化的电压?还有就是感觉会有这种变化可能是AD采样输出的状态,开始AD输出的状态为高阻或者开漏但是我测了下这两种状况下都还会有电压输出这样是否会影响采集呢?

hncel 发表于 2012-11-17 10:02:41

很好,很精练,值得一学

panxiaoyi 发表于 2012-11-17 11:14:24

回复zhenglingo ,PWM输出的是方波,瞬时输出电压要么是VCC电压,要么是GND电压,要输出其它电压,改变PWM的占空比即可,且必须是IO口串联一个电阻,然后电阻的另外一端对地并联一个滤波电容,电阻越大、电容越大,电压越稳定,这样AD模块才能检测。如果不是这个问题,请你上传一个电路图让大家看看

lcmdw 发表于 2012-11-17 11:40:11

mark{:smile:}

zhenglingo 发表于 2012-11-18 01:45:36

panxiaoyi 发表于 2012-11-17 11:14 static/image/common/back.gif
回复zhenglingo ,PWM输出的是方波,瞬时输出电压要么是VCC电压,要么是GND电压,要输出其它电压,改变PWM ...

我的硬件是没问题了都是这样连接的限流电阻1K滤波电容用的是10uF   我的思想是用定时器产生一个可以改变占空比的PWM输出,然后用AD采集输出,目标电压是3V   然后通过PID来时PWM输出稳定在3V,到时可以加进负载,来改变采样电压使PID做出调整    现在我遇到的问题就是用AD采集回来的值在串口上显示与万用表测量的值不相同,而且相差很大,并且串口上的值时变化的(开始时是允许的,但稳定后还是很大变动),而万用表的是不变的所以现在特别纠结我现在不知道是我哪里出错了    我就想请教下楼主的控制思想是否和我的一样?

贪吃的蚂蚁 发表于 2012-11-24 21:55:05

marl............................

15813191501 发表于 2012-11-26 14:10:41

学习一下

maimaige 发表于 2012-11-26 16:08:53

发一个简单的山寨版PID控制例子--AVr实现,mark一下

tospo_mwb 发表于 2012-11-29 10:07:41

MARK~~~~~~~~~

喜羊羊 发表于 2012-11-30 15:22:12

真的不错,呵呵呵,,,学习了,,,

sangyue 发表于 2012-11-30 15:27:30

学习学习

工程师030 发表于 2012-12-14 16:57:37

学习了,楼主思路不错

工程师030 发表于 2012-12-14 18:56:19

自己用VB写了一个小的测试程序奉献给大家

dfzcx 发表于 2012-12-15 16:44:49

谢谢楼主,学习了

chengtina 发表于 2012-12-15 16:59:57

这玩意有意思,短小精干

panxiaoyi 发表于 2012-12-15 21:33:03

工程师030 发表于 2012-12-14 18:56 static/image/common/back.gif
自己用VB写了一个小的测试程序奉献给大家

有意思,有机会向你学习一下VB

gongkailin 发表于 2012-12-15 21:53:44

这里是标准的PID直接计算法公式,而不是PID增量法计算公式,所以:
pwm=pwm+xz;                                           //输出值=旧数值+修正值
应该为
pwm=xz;

panxiaoyi 发表于 2012-12-15 22:05:39

gongkailin 发表于 2012-12-15 21:53 static/image/common/back.gif
这里是标准的PID直接计算法公式,而不是PID增量法计算公式,所以:
pwm=pwm+xz;                           ...

假设由于负载变化、供电变化、程序调节等原因,使得误差1、误差2、误差3都是0的话,那么
xz=wc0*kp+(wc0+wc1+wc2)*ki+((wc0-wc1)-(wc1-wc2))*kd;//修正值=比例放大+积分放大+微分放大
xz就会等于0
那么pwm也会等于0
所以,在本例中,pwm不能等于xz

gongkailin 发表于 2012-12-15 22:51:23

本帖最后由 gongkailin 于 2012-12-15 22:59 编辑

我以前做的孵化机控温用的用的这个公式,M128的PWM驱动固态继电器用电热管加热,PWM周期0.5秒。当检测温度与设定温度偏差为0时,PWM输出为零停止加热。设定温度37.5可以准确控制到+37,4至37.4,已经用了近10年了。
在你的例子中,当一瞬间误差1、误差2、误差3都是0的话,那么电容C上的电压正好为设定电压,这一瞬间PWM应该为0没有输出。

panxiaoyi 发表于 2012-12-16 20:24:50

但是,本例中是有负载的,pwm一旦为0,那么,输出电压就会马上下降,经测试,电位器旋转到某个位置时,pwm就会快速停留在某个值不变,或者在临近两个值中不断变动

jz701209李 发表于 2012-12-16 20:26:06

学习学习.......
页: [1] 2
查看完整版本: 发一个简单的山寨版PID控制例子