打印

温度PID控制_atm32f103——开贴记录!

[复制链接]
2964|28
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
wangjiahao88|  楼主 | 2017-12-4 10:20 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
沙发
wangjiahao88|  楼主 | 2017-12-4 10:32 | 只看该作者
int abs(int g)
{
if(g>0)
   {
    g=g;
       }
else
   {
    g=-g;
      }
return(g);

  }

使用特权

评论回复
板凳
wangjiahao88|  楼主 | 2017-12-4 10:32 | 只看该作者
ABS 取绝对值的一个函数!

使用特权

评论回复
地板
wangjiahao88|  楼主 | 2017-12-4 10:33 | 只看该作者
struct _pid
{
int pv;//测量值
int sp;//给定值
float integral;//积分偏差累计值
float pgain;//比例系数
float igain;//积分系数
float dgain;//微分系数
int deadband;  //死区
int last_error;
};

------------------------------
定义PID结构体

使用特权

评论回复
5
wangjiahao88|  楼主 | 2017-12-4 10:35 | 只看该作者
/*定义PID的结构体*/
struct _pid warm,*pid;
int process_point,set_point,dead_band;
float p_gain,i_gain,d_gain,integral_val,new_integ;
void pid_init(struct _pid *warm,int process_point ,int set_point)
{
struct _pid *pid;
pid = warm;//将WARM的首地址给pid
pid->pv = process_point; //        测量值                                       
pid->sp=set_point;                //        给定值
}

使用特权

评论回复
6
wangjiahao88|  楼主 | 2017-12-4 10:35 | 只看该作者
/*设置初始化变量*/
void pid_tune(struct _pid *pid,float p_gain,float i_gain,float d_gain,int dead_band)
{
pid->pgain=p_gain;
pid->igain=i_gain;
pid->dgain=d_gain;
pid->deadband=dead_band;
pid->integral=integral_val;
pid->last_error=0;
}

使用特权

评论回复
7
wangjiahao88|  楼主 | 2017-12-4 10:35 | 只看该作者
/*设定PID的参数*/
void pid_setting(struct _pid *pid ,float new_integ)
{
    pid->integral=new_integ;
    pid->last_error=0;
}

使用特权

评论回复
8
wangjiahao88|  楼主 | 2017-12-4 10:36 | 只看该作者
/*设定PID的初始输出值*/
void pid_bumpless(struct _pid *pid)
{
    pid->last_error=(pid->sp)-(pid->pv); //设定值与反馈值(测量值)的偏差

}

使用特权

评论回复
9
wangjiahao88|  楼主 | 2017-12-4 10:38 | 只看该作者
/*计算偏差*/
float pid_calc(struct _pid *pid)
{
    int err;
    float pterm,dterm,result,ferror;
    err=(pid->sp)-(pid->pv);//计算偏差
    if(abs(err)>pid->deadband)
    {
        ferror=(float)err; //数据类型转换
        /*设置偏差*/
        pterm=pid->pgain*ferror;//设置系数乘以偏差的值
        if(pterm>100||pterm<-100) //如果偏差大于100或小于-100积分没有输出作用 加快调节的速度 偏差较大
        {
            pid->integral=0.0;
        }
        else
        {
            pid->integral+=pid->igain *ferror;        //否则加入积分作用此时的偏差较小
            if(pid->integral>180.0)
            {
                pid->integral=180.0;
            }
            else if (pid->integral<0.0)

            {
                pid->integral=0.0;
            }
        }
        dterm=((float)(err-pid->last_error))*pid->dgain;
        result=pterm+pid->integral+dterm;
        if(result>255)
        {
            result= 255;
        }
        if(result<0)
        {
            result=0.0;
        }

    }
    else
        result=pid->integral;
    pid->last_error=err;
    return(result);
}

使用特权

评论回复
10
wangjiahao88|  楼主 | 2017-12-4 10:38 | 只看该作者
以上也就是PID 最核心的部分了。。。
当然这个也只是一个简单的PID模型。。。

使用特权

评论回复
11
wangjiahao88|  楼主 | 2017-12-4 11:52 | 只看该作者
#include  <stm32f10x_lib.h>
#include "stdio.h"
#include "PID.h"
#include "LCD_driver.h"
#include "HzLib_65k.h"
#define  ADC1_ADRESS ((u32)0x4001244C);
#define  DAC_DHR8R1_Address  0x40007410;
/*****LCD使用****************/
#define RED          0xf800
#define GREEN        0x07e0
#define BLUE         0x001f
#define WHITE        0xffff
#define BLACK        0x0000
extern u16 DigitFilter(u16 buf,u8 no);
u16 ADC_ConvertedValue;
void RCC_Configuration(void);                       
void USART_Configuration(void);
void NVIC_Configuration(void);
void ADC_Configuration(void);
void DMA_Configuration(void);
void DAC_Configuration(void);
void GPIO_Configuration(void);
void Delay_ms(u32 nTime);
void SysTick_Configuration(void);
void sendchar(int AD);
void USART1_Putc(unsigned char c);
void display(u16 AD,u16 a,u16 b);
       
void variety(int G);
int G;

int senddata(int ch);
u16 DataValue;

extern  u8  Escalator8bit;
u16  i;
char input[7];
char output[7];
extern vu32 TimingDelay;

使用特权

评论回复
12
wangjiahao88|  楼主 | 2017-12-4 11:52 | 只看该作者
以上位main函数的定义 变量

使用特权

评论回复
13
wangjiahao88|  楼主 | 2017-12-4 11:53 | 只看该作者
int main()
{

    LCD_Configuration();
    LCD_Init();
    Lcd_Clear(WHITE);
    RCC_Configuration();
    GPIO_Configuration();
    USART_Configuration();
    NVIC_Configuration();
    ADC_Configuration();
    DMA_Configuration();
    DAC_Configuration();

    set_point=75; //设置给定值


    p_gain=(float)(3.5);//设值比例系数
    i_gain=(float)(2.2);//设置积分系数
    d_gain=(float)(1.5);//设置微分系数
    dead_band=2;//设置死区
    pid = &warm;
    integral_val=(float)(0.01);
    pid_tune(&warm,p_gain,i_gain,d_gain,dead_band);// 设置PID的各个参数



    while(1)
    {
//        DataValue=ADC_GetConversionValue(ADC1);
        DAC_SetChannel1Data(DAC_Align_12b_R, 0xfff);
        i=DigitFilter(DataValue,16);        //滤波;
        i=100*(i*1.0)/4096;
        sendchar(i);
        process_point=i;
        pid_init(&warm,process_point,set_point); // PID参数的初始化设置测量值和给定值

        pid_bumpless(&warm); //        设置最终的偏差值

        if (i<set_point-10)
            Escalator8bit=255;
        else
            Escalator8bit=(int)pid_calc(&warm);//经过PID运算后的结果


//        if ((i<G-2)||(i>G+2 ))
//    Escalator8bit=(int)pid_calc(&warm);//经过PID运算后的结果
//        else  variety(G);
//    Escalator8bit=135;

//        variety(set_point);
        sendchar(Escalator8bit);
        LCD_PutString(60,100,"给定值:",BLACK,WHITE);
        LCD_PutString(60,120,"反馈值:",BLACK,WHITE);
        LCD_PutString(60,140,"输出值:",BLACK,WHITE);
        display(set_point,120,100);
        display(i,120,120);
        display(Escalator8bit,120,140);
    }


}



main函数的while 循环

使用特权

评论回复
14
wangjiahao88|  楼主 | 2017-12-4 11:54 | 只看该作者
/*利用串口发送数据*/
void sendchar(int AD)
{

    u8 a,b,c,d;
    a=AD/1000;
    b=(AD-a*1000)/100;
    c=(AD-a*1000-b*100)/10;
    d=AD-a*1000-b*100-c*10;
    USART1_Putc(a+'0');
    USART1_Putc(b+'0');
    USART1_Putc(c+'0');
    USART1_Putc(d+'0');
    USART1_Putc(' ');
    Delay_ms(300);
}

使用特权

评论回复
15
wangjiahao88|  楼主 | 2017-12-4 11:55 | 只看该作者
/*延时程序*/
void Delay_ms(u32 nTime)
{
    SysTick_CounterCmd(SysTick_Counter_Enable);
    TimingDelay=nTime;
    while(TimingDelay!=0);
    SysTick_CounterCmd(SysTick_Counter_Disable);
    SysTick_CounterCmd(SysTick_Counter_Clear);
}

使用特权

评论回复
16
wangjiahao88|  楼主 | 2017-12-4 11:55 | 只看该作者
void USART1_Putc(unsigned char c)
{
    USART_SendData(USART1, c);
    while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET );
}

使用特权

评论回复
17
wangjiahao88|  楼主 | 2017-12-4 11:55 | 只看该作者
void variety(int G)

{
    if ((i>G-3)&&(i<G+3 ))
        Escalator8bit=135;
}

使用特权

评论回复
18
wangjiahao88|  楼主 | 2017-12-4 11:55 | 只看该作者
未完待续…………

后面介绍 解析与计算

使用特权

评论回复
19
wangjiahao88|  楼主 | 2017-12-4 11:58 | 只看该作者
/**************************************************************
** 函数名:DigitFilter
** 功能:软件滤波
***************************************************************/
#include  <stm32f10x_lib.h>
#include "stdio.h"
extern void Delay_ms(u32 nTime);
u16 DigitFilter(u16 abc,u8 no)
{
        u8 i,j;
        u16 tmp;
        u8 cut_no=0;
        u16 buf[16];
        for(i=0;i<16;i++)
        {
        buf[i]=        abc;
        Delay_ms(50);

        }
        //排序
        for(i=0;i<no;i++)
        {
                for(j=0;j<no-i-1;j++)
                {       
                       
                        if(buf[j]>buf[j+1])
                        {       
                        tmp=buf[j];
                        buf[j]=buf[j+1];
                        buf[j+1]=tmp;
                        }
                }
        }
        if(no>5)
        {
                cut_no=no/5;
        }

        //平均
        tmp=0;
        for(i=cut_no;i<no-cut_no;i++)        //只取中间n-2*cut_no个求平均
                tmp+=buf[i];
        return(tmp/(no-2*cut_no));
}

使用特权

评论回复
20
wangjiahao88|  楼主 | 2017-12-4 11:58 | 只看该作者
软件滤波

ADC模拟量滤波的算法!

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

473

主题

7517

帖子

30

粉丝