⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pid.c.txt

📁 经典pid例程
💻 TXT
字号:
#include <reg51.h>
#include <string.h>
#include <stdio.h>
#include <intrins.h>
#define uint  unsigned int
#define uchar unsigned char
#define slong signed long
#define  data_port  P0   //液晶数据口
sbit P1_0=P1^0;
sbit P1_1=P1^1;
uint count0,zkb;
slong rIn,Uk,sum1,ad1=0,SumError=0,LastError=0,PrevError=0,
      Error=0,dError=0; //定义全局变量
uchar ding=20;
sbit    CLOCK= P1^2;       //时钟
sbit     _CS = P1^1;       //片选
sbit    D_IN = P2^5;       //数据入口
sbit   D_OUT = P3^3;       //数据出口
sbit   BUSY=P3^7;        // 液晶 BUSY
sbit   REQ=P3^6;         //液晶的REQ
sbit   RES=P2^0;          //液晶的REQ
void Dispay_asc16(unsigned char x,unsigned char y,unsigned char ascii);

void ocmj_write(uchar data1);                  //液晶显示字节
void ocmj_init(void);                          //液晶初始化
void  delay_ms(uchar t);                      //  延时1MS
void clr();
void Dispay_asc16str(unsigned char x,unsigned char y,unsigned char *ascii);//显示字符
void hz_tran(unsigned char x,unsigned char y,unsigned char *hz_p);// 传送LCD内部汉字数据到LCD函数 x:0x00~0x09 y:0x00~0x05
void disp_bit_dot(unsigned char x,unsigned char y);
void Dispay_asc16(unsigned char x,unsigned char y,unsigned char ascii);//显示数字字符(0-9)
void disp_cursor(void); //显示光标
void guanbi_cursor(void);//关闭光标
/****************************
函数功能:延时
****************************/
void delay(uchar n)
{
uchar i;
for(i=0;i<n;i++)
{
   _nop_();
}
}

/*****************************
函数功能:2543模拟量输入
*****************************/
uint read2543(uchar port)
{
uint ad=0,i;
CLOCK=0;
_CS=0;
port<<=4;
for(i=0;i<12;i++)
{
  if(D_OUT) ad|=0x01;
  D_IN=(bit)(port&0x80);
  CLOCK=1;
  delay(3);
  CLOCK=0;
  delay(3);
  port<<=1;
  ad<<=1;
}
_CS=1;
ad>>=1;
return(ad);
}
/**第一次读2543的值**/
void first2543(void)
{  uint n=12,cout1;
   read2543(0);
for(cout1=0;cout1<n;cout1++)
         {
          sum1+=(slong)read2543(0);
          delay(1);
         };
	  sum1=(slong)sum1/n;
}

/*****************************
函数功能:PID运算程序
******************************/
slong PIDprogra(slong a,b,c)
{
slong  SetPoint=0,Proportion=0,Integral=0,Derivative=0,
       sum=0,rOut;
       uint i=0,j=0,n=12,cout;



       Proportion=a;
       Integral=b;
       Derivative=c;

       ad1+=13;
       SetPoint=(slong)ad1+sum1;
        read2543(0);
      for(cout=0;cout<n;cout++)
         {
          sum+=read2543(0);
          delay(1);
         };
	  rIn=(slong)sum/n;
	  Error=SetPoint-rIn; 		     // 偏差
	   //Error=100;
		 if(Error>0)
                 {
                 if(Error>30)
		 rOut=1000;
		 else
                      {
                       SumError+=Error;              // 积分
                       dError=LastError-PrevError;   // 当前微分
                       PrevError=LastError;
                       LastError=Error;
                       rOut=(slong)(Proportion * Error      // 比例项
                            +Integral * SumError            // 积分项
                            +Derivative * dError);
		       }
                  }
                  else
                  rOut=0;
		  //P3=(slong)rOut;                          // 微分项

		  for(i=0;i<1000;i++)
                  {
                   for(j=0;j<800;j++)
                   _nop_();
                  }
                  return rOut;
}
/****************定时器T1初始化************/
void T1int(void)
{
  EA=1;
  ET0=1;
  ET1=1;
  TMOD=0x11;
  TH0=(65536-20000)/256;
  TL0=(65536-20000)%256;
  TH1=0xb0;
  TL1=0x3C;
  TR0=1;
  TR1=1;
  count0=1;
}
//液晶写数据
 void ocmj_write(uchar data1)
    {
         while(BUSY!=0);
         data_port=data1;
         _nop_();
         _nop_();
         REQ=1;
        _nop_();
        _nop_();
        while(BUSY==0) ;
        REQ=0;

    }

//延时1ms
void  delay_ms(uchar t)
{
  uchar j1,s1;
  for(j1=0;j1<t;j1++)
  for(s1=0;s1<125;s1++)
  { }
}
// 液晶初始化
void ocmj_init(void)
    {
         RES=0;                        //LCD复位
         delay_ms(10);
         RES=1;
         REQ=0;
         BUSY=1;
         delay_ms(10);
   }

//清屏
void clr()
{
   ocmj_write(0xf4);
}
/*-----------------显示国标汉字-----------------*/
/****************************************************************************************
**函数名称:Dispay_hz()
**函数功能:显示16*16汉字
**输入参数:x为横坐标(0x00-0x07);    (0--7)
           y为纵坐标(0x00-0x0e);    (0--15)
**输出参数:无
****************************************************************************************/
void hz_tran(unsigned char x,unsigned char y,unsigned char *hz_p)
    {
         x+=0;
     while((*hz_p)!=0)
            {
                 ocmj_write(0xf0);
                 ocmj_write(x);
                 ocmj_write(y);
                 ocmj_write(*hz_p-0xa0); //转区位码高位
                 hz_p++;
                 ocmj_write(*hz_p-0xa0); //转区位码低位
                 hz_p++;
                 if(x<0x0E)
                     x++;
                 else
                    {
                         x=0x00;
                         y++;
                    }
                }
  }

  /****************************************************************************************
**函数名称:send_asc16str()
**函数功能:显示8*16ASCII字符串
**输入参数:X坐标X从0x00到0x1D共30个字符以字符为单位递增;(0--29)
**         Y坐标Y从0到0x共80个点以点为单位递增;        (0--127)
**输出参数:无
****************************************************************************************/
void Dispay_asc16str(unsigned char x,unsigned char y,unsigned char *ascii)
{
    while((*ascii)!=0)
    {
        ocmj_write(0xF9);
        ocmj_write(x);
        ocmj_write(y);
        ocmj_write(*ascii);//写要显示的ASCII码;
        ascii++;
        if(x<0x1D)
           x++;
        else
        {
           x=0x00;
           y+=16;
           if(y==0x40)
           y=0;
        }
    }
}

/*-----------------显示字节点阵图形-----------------*/
void disp_img (uchar  *img)
{
      uchar i,j;
      for(j=0;j<80;j++)
      {
        for(i=0;i<20;i++)
        {
        ocmj_write(0xf3);
        ocmj_write(i);
        ocmj_write(j);

        ocmj_write(img[j*20+i]);
        }
      }
}
/*****************************************************************************************
**函数名称:Dispay_ASCII16()
**函数功能:显示8*16ASCII字符变量
**输入参数:X坐标X从0x04到0x13共16个字符以字符为单位递增;(0--15)
**         Y坐标Y从0到0x3F共64个点以点为单位递增;        (0--63)
**输出参数:无
*****************************************************************************************/
void Dispay_asc16(unsigned char x,unsigned char y,unsigned char ascii)
{
   ocmj_write(0xf9);
   ocmj_write(x);
   ocmj_write(y);
   ocmj_write(ascii+0x30);
}

//显示光标
void disp_cursor(void)
{
      ocmj_write(0xfb);
      ocmj_write(0x0f);
}
//关闭光标
void guanbi_cursor(void)
{
      ocmj_write(0xfb);
      ocmj_write(0x00);
}
//显示1*8位点
void disp_bit_dot(unsigned char x,unsigned char y)
{
      ocmj_write(0xf3);
      ocmj_write(x);
      ocmj_write(y);
      ocmj_write(0x01);
}

/*****************************
        主程序
*****************************/
void main()
{ T1int();
  ocmj_init();
  first2543();
  while(1){
            Uk=(slong)PIDprogra(2,0,30);
            if(Uk>999)
               zkb=125;
            else
            {zkb=(uint)(Uk*125/1000);}
          };
}
/***************PWM子程序*******************/
void timer0(void) interrupt 1 using 1
{
 TH0=-20000/256;
 TL0=-20000%256;
 count0++;
 if(count0>zkb)
 {
 P1_0=1;}
 else
 P1_0=0;
 if(count0==125)                       //占空比周期
 {
   count0=1;

 }
}


void time1(void) interrupt 3 using 0
 {   long xianshi11=0;
     uchar wendu1,wendu2,wendu3,wendu4;
    TH1=0x3C;
    TL1=0xB0;
    ding--;
  if(ding==0)
   {
     ding=40;
           xianshi11=read2543(0);

                   wendu1=xianshi11/1000;
                   wendu2=xianshi11%1000/100;
                   wendu3=xianshi11%100/10;
                   wendu4=xianshi11%10;

                   Dispay_asc16(0x12,46,wendu1);
                   Dispay_asc16(0x13,46,wendu2);
                   Dispay_asc16(0x14,46,wendu3);
                   Dispay_asc16(0x15,46,wendu4);

                     xianshi11=xianshi11*400;
                     xianshi11=xianshi11/4096;
                     wendu2=xianshi11%1000/100;
                     wendu3=xianshi11%100/10;
                     wendu4=xianshi11%10;
                    Dispay_asc16(0x13,65,wendu2);
                   Dispay_asc16(0x14,65,wendu3);
                   Dispay_asc16(0x15,65,wendu4);

  }
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -