📄 pid.c.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 + -