求单片机温度PID控制的程序

2019-07-15 11:27发布

详细一点的,有注释的。拜托
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
10条回答
jblbin2008
1楼-- · 2019-07-15 15:49
你要上OS???
太子的空间
2楼-- · 2019-07-15 19:12
 精彩回答 2  元偷偷看……
太子的空间
3楼-- · 2019-07-15 23:33
这是一个8051单片机PID温度控制的程序
太子的空间
4楼-- · 2019-07-16 00:53
#include<reg51.h>
#include<intrins.h>
#include<math.h>
#include<string.h>
struct PID {
unsigned int SetPoint; // 设定目标 Desired Value
unsigned int Proportion; // 比例常数 Proportional Const
unsigned int Integral; // 积分常数 Integral Const
unsigned int Derivative; // 微分常数 Derivative Const
unsigned int LastError; // Error[-1]
unsigned int PrevError; // Error[-2]
unsigned int SumError; // Sums of Errors
};
struct PID spid; // PID Control Structure
unsigned int rout; // PID Response (Output)
unsigned int rin; // PID Feedback (Input)
sbit data1=P1^0;
sbit clk=P1^1;
sbit plus=P2^0;
sbit subs=P2^1;
sbit stop=P2^2;
sbit output=P3^4;
sbit DQ=P3^3;
unsigned char flag,flag_1=0;
unsigned char high_time,low_time,count=0;//占空比调节参数
unsigned char set_temper=35;   
unsigned char temper;        
unsigned char i;
unsigned char j=0;
unsigned int s;
/***********************************************************
延时子程序,延时时间以12M晶振为准,延时时间为30us×time
***********************************************************/
void delay(unsigned char time)
  {
   unsigned char m,n;
     for(n=0;n<time;n++)
       for(m=0;m<2;m++){}
  }
/***********************************************************
写一位数据子程序
***********************************************************/
void write_bit(unsigned char bitval)
  {
    EA=0;
      DQ=0;  /*拉低DQ以开始一个写时序*/
    if(bitval==1)
       {
        _nop_();
        DQ=1;   /*如要写1,则将总线置高*/
        }
      delay(5);   /*延时90us供DA18B20采样*/
    DQ=1;  /*释放DQ总线*/
    _nop_();
    _nop_();
   EA=1;
   }
/***********************************************************
写一字节数据子程序
***********************************************************/
void write_byte(unsigned char val)
{
  unsigned char i;
  unsigned char temp;
  EA=0;
  TR0=0;
  for(i=0;i<8;i++)  /*写一字节数据,一次写一位*/
      {
       temp=val>>i;  /*移位操作,将本次要写的位移到最低位*/
       temp=temp&1;
       write_bit(temp);  /*向总线写该位*/
       }
   delay(7);   /*延时120us后*/
// TR0=1;
  EA=1;
  }
/***********************************************************
读一位数据子程序
***********************************************************/
unsigned char read_bit()
{
  unsigned char i,value_bit;
  EA=0;
  DQ=0;   /*拉低DQ,开始读时序*/
  _nop_();
  _nop_();
  DQ=1;   /*释放总线*/
  for(i=0;i<2;i++){}
  value_bit=DQ;
  EA=1;
  return(value_bit);
  }
/***********************************************************
读一字节数据子程序
***********************************************************/
unsigned char read_byte()
  {
   unsigned char i,value=0;
   EA=0;
   for(i=0;i<8;i++)
      {
       if(read_bit())  /*读一字节数据,一个时序中读一次,并作移位处理*/
         value|=0x01<<i;
       delay(4);  /*延时80us以完成此次都时序,之后再读下一数据*/
       }
   EA=1;
   return(value);
  }
/***********************************************************
复位子程序
***********************************************************/
unsigned char reset()
  {
   unsigned char presence;
   EA=0;
   DQ=0;   /*拉低DQ总线开始复位*/
   delay(30);   /*保持低电平480us*/
   DQ=1;   /*释放总线*/
   delay(3);   
   presence=DQ;   /*获取应答信号*/
   delay(28);   /*延时以完成整个时序*/
   EA=1;
   return(presence);  /*返回应答信号,有芯片应答返回0,无芯片则返回1*/
  }
/***********************************************************
获取温度子程序
***********************************************************/
void get_temper()
{
  unsigned char i,j;
  do
  {
    i=reset();  /*复位*/
  }while(i!=0);  /*1为无反馈信号*/
  i=0xcc;  /*发送设备定位命令*/
  write_byte(i);
  i=0x44;  /*发送开始转换命令*/
  write_byte(i);
  delay(180);  /*延时*/
  do
  {
  i=reset();  /*复位*/
  }while(i!=0);  
  i=0xcc;  /*设备定位*/
  write_byte(i);
  i=0xbe;  /*读出缓冲区内容*/
  write_byte(i);
  j=read_byte();
  i=read_byte();   
  i=(i<<4)&0x7f;
  s=(unsigned int)(j&0x0f);
  s=(s*100)/16;
  j=j>>4;
  temper=i|j;                                      /*获取的温度放在temper中*/
  }
/*====================================================================================================
Initialize PID Structure
=====================================================================================================*/
void PIDInit (struct PID *pp)
{
memset ( pp,0,sizeof(struct PID));
}
/*====================================================================================================
PID计算部分
=====================================================================================================*/
unsigned int PIDCalc( struct PID *pp, unsigned int NextPoint )
{
unsigned int dError,Error;
Error = pp->SetPoint - NextPoint; // 偏差
pp->SumError += Error; // 积分
dError = pp->LastError - pp->PrevError; // 当前微分
pp->PrevError = pp->LastError;
pp->LastError = Error;
return (pp->Proportion * Error // 比例项
+ pp->Integral * pp->SumEror // 积分项
+ pp->Derivative * dError); // 微分项
}
/***********************************************************
温度比较处理子程序
***********************************************************/
compare_temper()
{
  unsigned char i;
     if(set_temper>temper)
         {
          if(set_temper-temper>1)   
             {
              high_time=100;
              low_time=0;
             }
          else
             {
               for(i=0;i<10;i++)
                 {  get_temper();
                    rin = s; // Read Input
                    rout = PIDCalc ( &spid,rin ); // Perform PID Interation
                 }
               if (high_time<=100)
                 high_time=(unsigned char)(rout/800);
               else
                 high_time=100;
               low_time= (100-high_time);
             }
         }
      else if(set_temper<=temper)
             {
               if(temper-set_temper>0)
                 {
                   high_time=0;
                   low_time=100;
                 }
               else
               {
                 for(i=0;i<10;i++)
                 {  get_temper();
                    rin = s; // Read Input
                    rout = PIDCalc ( &spid,rin ); // Perform PID Interation
                 }
                 if (high_time<100)
                   high_time=(unsigned char)(rout/10000);
                 else
                   high_time=0;
                 low_time= (100-high_time);
               }
             }
     //  else
     //      {}
    }
/*****************************************************
T0中断服务子程序,用于控制电平的翻转 ,40us*100=4ms周期
******************************************************/
void serve_T0() interrupt 1 using 1
  {
   if(++count<=(high_time))
     output=1;
   else if(count<=100)
     {
      output=0;
      }
   else
      count=0;
   TH0=0x2f;
   TL0=0xe0;
   }
/*****************************************************
串行口中断服务程序,用于上位机通讯
******************************************************/
void serve_sio() interrupt 4 using 2
  {
/*   EA=0;
   RI=0;  
   i=SBUF;
   if(i==2)
      {
       while(RI==0){}  
       RI=0;
       set_temper=SBUF;  
       SBUF=0x02;  
       while(TI==0){}
       TI=0;
       }
    else if(i==3)  
       {
        TI=0;
       SBUF=temper;
        while(TI==0){}
        TI=0;
        }
     EA=1;   */
   }
void disp_1(unsigned char disp_num1[6])
{
     unsigned char n,a,m;
     for(n=0;n<6;n++)
      {
     //  k=disp_num1[n];
       for(a=0;a<8;a++)
         {
          clk=0;
           m=(disp_num1[n]&1);
            disp_num1[n]=disp_num1[n]>>1;
          if(m==1)
             data1=1;
          else
             data1=0;
          _nop_();
          clk=1;
          _nop_();
          }
       }
}
/*****************************************************
显示子程序
功能:将占空比温度转化为单个字符,显示占空比和测得到的温度
******************************************************/
void display()
{
unsigned char code number[]={0xfc,0x60,0xda,0xf2,0x66,0xb6,0xbe,0xe0,0xfe,0xf6};
unsigned char disp_num[6];
unsigned int k,k1;
k=high_time;
k=k%1000;
k1=k/100;
if(k1==0)
    disp_num[0]=0;
else
    disp_num[0]=0x60;
k=k%100;
disp_num[1]=number[k/10];
disp_num[2]=number[k%10];
k=temper;
k=k%100;
disp_num[3]=number[k/10];
disp_num[4]=number[k%10]+1;
disp_num[5]=number[s/10];
disp_1(disp_num);
}
/***********************************************************
主程序
***********************************************************/
main()
{
  unsigned char z;
  unsigned char a,b,flag_2=1,count1=0;
  unsigned char phil[]={2,0xce,0x6e,0x60,0x1c,2};;
  TMOD=0x21;   
  TH0=0x2f;   
  TL0=0x40;
  SCON=0x50;   
  PCON=0x00;            
  TH1=0xfd;   
  TL1=0xfd;
  PS=1;           
  EA=1;   
  EX1=0;   
  ET0=1;   
  ES=1;   
  TR0=1;  
  TR1=1;
  high_time=50;                 
  low_time=50;
  PIDInit ( &spid ); // Initialize Structure
  spid.Proportion = 10; // Set PID Coefficients
  spid.Integral = 8;
  spid.Derivative =6;
  spid.SetPoint = 100; // Set PID Setpoint
  while(1)
       {
           if(plus==0)
             {
              EA=0;
              for(a=0;a<5;a++)
                for(b=0;b<102;b++){}  
                if(plus==0)
                  {
                  set_temper++;
                  flag=0;
                  }
              }
            else if(subs==0)
              {
               for(a=0;a<5;a++)
                  for(b=0;a<102;b++){}  
                  if(subs==0)
                  {
                    set_temper--;
                    flag=0;
                   }
               }
            else if(stop==0)
               {
                for(a=0;a<5;a++)
                   for(b=0;b<102;b++){}  
                   if(stop==0)
                   {
                   flag=0;         
                   break;
                   }
             EA=1;
             }
      get_temper();
      b=temper;
      if(flag_2==1)
         a=b;
      if((abs(a-b))>5)
        temper=a;
      else
        temper=b;
      a=temper;
      flag_2=0;
      if(++count1>30)
         {
          display();
          count1=0;
          }
      compare_temper();   
       }
    TR0=0;
    z=1;
while(1)
      {
       EA=0;
       if(stop==0)
        {
         for(a=0;a<5;a++)
           for(b=0;b<102;b++){}
         if(stop==0)
           disp_1(phil);
        //        break;
           }
      EA=1;
         }
}
复制代码
周不妄
5楼-- · 2019-07-16 02:52
太子的空间 发表于 2017-4-6 21:10
#include
#include
#include

请问一下有这个程序的硬件电路图吗?直接看程序有点不明白。
周不妄
6楼-- · 2019-07-16 03:42
太子的空间 发表于 2017-4-6 21:10
#include
#include
#include

还有rin=s .这s是什么。然后high-time与low-time是调节占空比的吗?没看到具体输出是怎么一回事?

一周热门 更多>