直流电机PID控制

直流电机PID控制
直流电机PID控制

实验一直流电机控制

1、实验目的

(1)了解直流电机控制的一般情况;

(2)掌握直流电机的H桥PWM驱动电路结构;

(3)掌握直流电机角度控制的电位器方法;

2、实验内容

直流电动机的角度测量采用360旋转电位器,模数转换采用MCP3001,H桥驱动采用L293,显示采用LCD1602,键盘采用4*4扫描键盘,实验电路图如下:

控制硬件的关键:L293的H桥驱动原理,PWM电机控制的方法;

控制程序的关键:电动机转角的采集与标度变换;给定转角的标度逆变换;PID控制程序实现;

3、实验步骤

利用PROTEUS软件画出电机控制系统的仿真原理图,在KEIL软件下对控制程序进行编译,然后下载到控制系统的单片机,进行运行调试,观察控制效果。

4、实验报告

(1) 整理好实验电路图与程序。

(2) 总结比例参数P、微分D和采样周期对控制系统性能的影响。

附:实验控制程序源代码#include

#define uchar unsigned char #define uint unsigned int

sbit CLK=P2^3;

sbit DAT=P2^4;

sbit CS =P2^5;

uint MCP3001(void) //10bit {

uint i,x=0;

DAT=1; CS=0;

for(i=0;i<12;i++)

{

CLK=1; CLK=0;

x<<=1;

if(DAT==1) x++;

}

CS=1;

return (x&0X3FF);

}

#define kd 4

#define kp 30

#define TIM1 -30000

sbit UP=P3^3;

sbit DN=P3^4;

sbit EN=P3^5;

int e0,e1,e2,y,r,u,sr;

uchar con=0;

void PID() interrupt 3

{

TH1=TIM1>>8; TL1=TIM1&0XFF; y=MCP3001();

e0=e1; e1=e2; e2=r-y;

u=kp*(e2+kd*(e2-e1));

if(u>1) {UP=10; DN=0;}

else if(u<-10) {UP=0; DN=1;} else {UP=0; DN=0;}

if(u<0) u=-u;

if(u>2550) u=2550;

con=u/10;

}

bit ppp;

void PWM() interrupt 1

{

if(ppp)

{

TH0=0XFF; TL0=con;

EN=0;

}

else

{

TH0=0XFF; TL0=-con;

EN=1;

}

ppp=!ppp;

}

#define uchar unsigned char

#define uint unsigned int

#define LCD_COM 0 // Command

#define LCD_DAT 1 // Data

sbit LcdRS=P2^0;

sbit LcdRW=P2^1;

sbit LcdEN=P2^2;

void time(uint t)

{

while(t--);

}

void LCD_WRITE(uchar x,bit WS)

{

P0=x;

LcdRW=0; LcdRS=WS;

LcdEN=1; time(100); LcdEN=0;

}

void LCD_Initial()

{

LCD_WRITE(0x38,LCD_COM); time(200);

LCD_WRITE(0x38,LCD_COM); time(200);

LCD_WRITE(0x01,LCD_COM);

time(200);

LCD_WRITE(0x06,LCD_COM);

time(200);

LCD_WRITE(0x0c,LCD_COM);

time(200);

}

void GotoXY(uchar x,uchar y)

{

uchar code table[4]={0x00,0x40,0x10,0x50};

LCD_WRITE(0x80+table[x]+y,

LCD_COM);

}

void PutCh(uchar m)

{

LCD_WRITE(m,LCD_DAT);

}

void Print(uchar *str)

{

while(*str!='\0')

{

PutCh(*str);

str++;

}

}

void PutUint(int s)

{

uchar str[10];

str[0]=(s/1000)%10+'0';

str[1]=(s/100)%10+'0';

str[2]=(s/10)%10+'0';

str[3]=(s/1)%10+'0';

str[4]=0;

Print(str);

}

void PutInt(int s)

{

uchar str[10];

if(s>=0) str[0]='+';

else {str[0]='-'; s=-s;}

str[1]=(s/100)%10+'0';

str[2]=(s/10)%10+'0';

str[3]=(s/1)%10+'0';

str[4]=0;

Print(str);

}

uchar Getkey()

{

uchar const tab[4]={1,2,4,8};

uchar const

tran[16]={7,4,1,10,8,5,2,0,9,6,3,11,1

2,13,14,15};

uchar i,m,key=0xff;

for(i=0;i<4;i++)

{

P1=~tab[i];

m=(~P1)>>4;

switch(m)

{

case 1: key=i+0; break;

case 2: key=i+4; break;

case 4: key=i+8; break;

case 8: key=i+12; break;

}

}

if(key!=0xff) key=tran[key];

return key;

}

void main()

{

long s;

uchar key;

EA=1; ET1=1; ET0=1; PT1=1;

TMOD=0X11;

TH0=0xff; TL0=0xff; TR0=1;

TH1=TIM1>>8; TL1=TIM1&0xff;

TR1=1;

LCD_Initial(); sr=0;

GotoXY(0,0); Print("D= U= ");

GotoXY(1,0); Print("Y= R= ");

while(1)

{

time(1000);

s=y; s=(s*358)/1023-179;

GotoXY(0,2); PutUint(y);

GotoXY(0,9);PutInt(con);

GotoXY(1,2); PutInt(s);

s=sr; s=(s+179)*1023/358; r=s;

GotoXY(1,9); PutInt(sr);

key=Getkey();

if(key!=0xff)

{

switch(key)

{

case 0: sr=0; break;

case 1: sr=10; break;

case 2: sr=20; break;

case 3: sr=30; break;

case 4: sr=40; break;

case 5: sr=50; break;

case 6: sr=60; break;

case 7: sr=70; break;

case 8: sr=80; break;

case 9: sr=90; break;

case 10: sr=100; break;

case 11: sr=110; break;

case 12: sr=120; break;

case 13: sr=130; break;

case 14: sr=140; break;

case 15: sr=-sr; break;

}

time(5000);

}

}

}

相关主题
相关文档
最新文档