📄 电机调速控制程序.txt
字号:
附录Ⅰ(程序清单)
#include<reg51.h>
#define uchar unsigned char
#define uint unsigned int
#define time0 65536-3000
float tt;
uchar n,ptr,tn; //频率控制字
sbit ADCS = P1^4;
sbit ADAT = P1^3;
sbit ACLK = P1^2; //adc0832/cs/data/clk/
uint u,ki,kp,kd,u0;
uint e0,e1,e2;
uint vvv,r,para[6];
uchar y,out,ts,tm;
uint pwmh,pwml; //脉冲高低电平
uchar pwm; //控制量输出
sbit pwma=P1^0;
sbit pwmb=P1^1;
bit pwmx;pid_b;
sbit dis0 =P2^7;
sbit dis1 =P2^6;
sbit dis2 =P2^5;
sbit dis3 =P2^4;
sbit key1 =P2^3;
sbit key0 =P2^2;
uchar disp[4],dis;
uchar key,keyx,flag0,flag1;
uchar code numtab[4]={0x10,0x80,0x40,0x20};
uchar code distab[16]={0x28,0xee,0x32,0xa2,0xe4,0xa1,0x21,0xea,
0x20,0xa0,0x60,0x25,0x39,0x26,0x31,0x71};
//**************************************************************
void time(uint t)
{
uint i;
for(i=0;i<t;i++);
}
//**************************************************************
//adc0832
//**************************************************************
uchar adc0832()
{
uchar x=0,i;
ADAT=1;ACLK=0;ADCS=0;
for(i=0;i<4;i++)
{
ACLK=0;
ADAT=1;
ACLK=1;
}
ACLK=0;
for(i=0;i<8;i++)
{
ACLK=1;
x=x<<1;
if(ADAT) x++;
ACLK=0;
}
ACLK=1;ADCS=1;
return x;
}
//**************************************************************
//脉宽调制
//**************************************************************
void Timer() interrupt 3 using 3 //产生pwm脉冲
{
if(!pwmx)
{
TH1=pwmh>>8;TL1=pwmh;
}
else
{
TH1=pwml>>8;TL1=pwml;
}
pwmx=~pwmx;
if(flag1) {pwma=1;pwmb=1;}
else if(flag0){pwma=pwmx; pwmb=1;}
else {pwma=1;pwmb=pwmx;}
}
//**************************************************************
//PID算法
//**************************************************************
void PID()
{ tt=300.0/107.0;
if(y<127)
{vvv=(vvv+300-(uint)(y-41)*tt)/2;}
if(y>127)
{vvv=(vvv+(uint)(y-148)*tt)/2;}
e2=e1;e1=e0;e0=r-vvv;
u+=ki*e0+kp*(e0-e1)+kd*(e0-2*e1+e2);
if(u>0xfff) u=0xfff;
if(u<0) u=0;
u0=(u+u0*3)/4;
out=(uchar)(u0/16);
pwm=out;
pwmh=pwm|0xff00;
pwml=0xffff-pwm;
pwmh=pwmh<<n;
pwml=pwml<<n;
}
//**************************************************************
//显示
//**************************************************************
void distran()
{
disp[0]=distab[para[ptr]%10];
disp[1]=distab[(para[ptr]/10)%10];
disp[2]=distab[(para[ptr]/100)%10];
// disp[3]=~ledtab[ptr];
disp[3]=distab[ptr];
}
void display()
{
dis=(dis+1)%4;
P2=0xff;
P0=disp[dis];
P2=~numtab[dis];
key0=1; key1=1;
if(!key0) keyx=dis+1;
if(!key1) keyx=dis+5;
}
//**************************************************************
//键盘
//**************************************************************
void keyproc()
{
if(key>0)
{
switch(key)
{ case 1: ptr--; break;
case 5: ptr++; break;
case 2: para[ptr]--; break;
case 6: para[ptr]++; break;
case 3: para[ptr]-=10; break;
case 7: para[ptr]+=10; break;
case 4: flag0=(flag0+1)%2; break;//正反转
case 8: flag1=(flag0+1)%2; break;//启动停止
}
if(ptr>5) ptr=5;
if(ptr<0) ptr=0;
switch(ptr)
{
case 0:para[0]=vvv; break;
case 1:r=para[1]; break;
case 2:kp=para[2]; break;
case 3:ki=para[3]; break;
case 4:kd=para[4]; break;
case 5:n=para[5]; break;
}
if(para[ptr]<0) para[ptr]=0;
if(para[ptr]>300) para[ptr]=300;
distran();
}
key=0;
}
//**************************************************************
//定时采样
//**************************************************************
timer0() interrupt 1 using 2 //定时中断
{
TH0=time0>>8; TL0=time0;
if(tm++>ts)
{
pid_b=1;tm=0;
}
display();
}
//**************************************************************
void main()
{
IE=0x8a;
IP=8;
TMOD=0x11;
TH0=time0>>8;
TL0=time0;
TR0=1;
TR1=1;
ki=4;
kp=8;
kd=10;
ts=3;
r=200;
n=5;
para[1]=r;
para[2]=kp;
para[3]=ki;
para[4]=kd;
para[5]=n;
distran();
for(;;)
{
if(keyx>0)
{
key=keyx;
while(keyx!=0) {keyx=0; time(1000);}
keyproc();
}
if(pid_b)
{
y=adc0832();
PID();
pid_b=0;
if(tn++>10)
{if(ptr==0)
{ para[ptr]=vvv;
distran();
display();
tn=0;
}
}
}
time(1000);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -