📄 新建 文本文档 (5).txt
字号:
#include <AT89X52.H>
#define uint unsigned int
#define uchar unsigned char
#define tim 65535-5000
#define pwm 10000
#define K 1
#define Kp 1
#define Ki 0
#define Kd 1
#define T 4
sbit dis0 =P2^6;
sbit dis1 =P2^5;
sbit dis2 =P2^4;
sbit dis3 =P2^3;
sbit dis4 =P2^2;
sbit key1 =P2^1;
sbit key0 =P2^0;
sbit PWMB=P1^0;
bit PWMX;
uint pwmh,pwml;
int sudu_set,sudu_now,sudu_old;
int e0=0,e1=0,e2=0,sudu_d;
int sb;
uchar pid_b,tm;
uchar count;
uchar disp[5],dis;
uchar key,keyx,ts;
int para[8],ptr;
uchar code numtab[5]={0x40,0x20,0x10,0x04,0x08};
uchar code distab[16]={ 0x28,0xee,0x32,0xa2,0xe4,0xa1,0x21,0xea,
0x20,0xa0,0x60,0x25,0x39,0x26,0x31,0x71};
uchar code ledtab[8]={0x08,0x10,0x20,0x40,0x88,0x90,0xa0,0xc0};
void time(uint tm)
{
for(tm;tm>0;tm--);
}
void distran()
{
disp[4]=distab[para[ptr]%10]; //编码转换
disp[0]=distab[(para[ptr]/10)%10];
disp[1]=distab[(para[ptr]/100)%10];
disp[2]=distab[(para[ptr]/1000)%10];
disp[3]=~ledtab[ptr]; //选中要点亮的LED
}
void display()
{
dis=(dis+1)%5;
P2=0xff;
P0=disp[dis]; //扫描数码管和LED
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: para[ptr]--; break; //设定速度值
case 5: para[ptr]++; break;
case 2: para[ptr]-=10; break;
case 6: para[ptr]+=10; break;
case 3: para[ptr]-=100; break;
case 7: para[ptr]+=100; break;
case 4: ptr--; break;
case 8: ptr++; break;
}
if(ptr>2) ptr=0;
if(ptr<0) ptr=2;
if(para[ptr]<0) para[ptr]=0;
if(para[ptr]>1000) para[ptr]=1000;
distran(); //刷新显示
}
key=0;
}
/***************PID算法********************/
void PID_Control(void)
{
sudu_old = sudu_now;
sudu_now =TH1*256+ TL1; //读取速度反馈值
para[1] = sudu_now*40;
para[2]=TH1;
TH1=0; TL1=0;
e2=e1;e1=e0;
e0 = sudu_set-(sudu_now*40); // 偏差
//sudu_d = sudud_now-sudu_old; // 微分
sb += Kp*e0; //+ Kd*sudu_d;
if(sb<1) sb=0;
else if(sb>6000) sb=6000;
pwml=sudu_set;//sb*K; // pwmh=sb*k,k=30
pwmh=pwm-pwml; //计算输出占空比
pwmh=65535-pwmh;
pwml=65535-pwml;
}
void timer0() interrupt 1 using 0 //显示扫描
{
TH0=tim>>8;
TL0=tim;
tm++;
if(tm>T)
{pid_b=1;tm=0; }
display();
}
void timer1() interrupt 3 using 1 //脉冲检测-----计数法
{
}
void temer2() interrupt 5 using 2 //PWM输出
{ TF2=0;
if(!PWMX)
{
TH2=pwmh>>8;TL2=pwmh;
}
else
{
TH2=pwml>>8;TL2=pwml;
}
PWMX=~PWMX;
PWMB=PWMX;
}
void main()
{ char i;
EA = 1;
TMOD=0X01; //设置定时器0的工作模式----定时模式
ET0=1; //定时器0开中断
TH0=tim>>8; TL0=tim; TR0=1; //启动定时器0定时5ms
TMOD|=0X50; //设置定时器1的工作模式----计数模式
ET1=0; //定时器1关中断
TH1=0; TL1=0; TR1=1; //启动计数器1
T2MOD=0x00; //定时器2模式设置----定时模式(向上计数)
T2CON=0x00;
ET2=1; //定时器2开中断
TH2=tim>>8; TL2=tim; TR2=1; //启动定时器2
dis=0;ptr=0;
for(i=0;i<5;i++) para[i]=i; //初始化速度存储数组
distran(); //刷新显示缓存区
sudu_set = para[0];
/*pwmh=sudu_set*30;
pwml=pwm-pwmh;
pwmh=65535-pwmh;
pwml=65535-pwml; */
for(;;)
{
if(keyx>0)
{
key=keyx;
while(keyx!=0) {keyx=0; time(3000);} //等待按键
keyproc(); //调用按键处理程序
sudu_set = para[0];
}
if(!para[0]){PWMB=1;} else
if(pid_b)
{ pid_b = 0;
PID_Control(); //调用PID调速程序
count++;
if(count>10) {count=0; distran();} //刷新显示
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -