雨润年华

电子DIY爱好者的家园

一个简单的通过PID调节电压输出的例子

/*****************************************************
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 这三个系数,还有调整间隔检测时间,即可调整负载电压的稳定度和皱纹度。
213035r9xd7hac27dekbsd.gif
本例比较简单,没有多少语句,且都是16位的整数运算,适合8位单片机运行,但是它并没有按照PID的公式来套(说实话我对那些公式也是一知半解),它只是按照PID的思路来工作而已,所以,这个程序只能说是山寨程序,适合要求不高的场所。还好,它的语句短、运行速度特快
PWM电压调整与PID控制.rar

本原创文章未经允许不得转载 | 当前页面:雨润年华 » 一个简单的通过PID调节电压输出的例子

评论