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

📄 新建 文本文档 (5).txt

📁 基于8051的电机调速程序 基于8051的电机调速程序
💻 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 + -