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

📄 text1.c

📁 基于8051的电机调速程序 基于8051的电机调速程序
💻 C
字号:
#include <REG52.H>

#define uint  unsigned int
#define uchar unsigned char

#define tim 65535-5000
#define pwm 2000

#define	T   5

sbit key0 =P2^0;
sbit key1 =P2^1;
sbit PWMB =P3^3;					//PWM输出口

bit  PWMX;

uint pwmh,pwml,pwmm;
uint sudu_set,sudu_now;
int e0,sudu_d;

uchar pid_b,tm=0;
uchar count;

uchar disp[5],dis =0;
uchar key,keyx;
int 	para[4];
char 	ptr =0;
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,0x80 };					//LED显示


void delay(uint timer)
{
	for(;timer >0;timer --);
}

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)
	{
		if(ptr!=1)
		{
			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;
			}
		}
		else
		{
			switch(key)
			{
				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_now = TH1*256+TL1;    					//读取速度反馈值
	
	TH1 =0; 
	TL1 =0;
	TR1 =1;
	para[1] = sudu_now*40;
	if(para[1] >(sudu_set+40))
	{
		e0 =(para[1]-sudu_set)/4;
		pwml =pwmm-e0;
		if(pwml >2000)
		{
			pwml =2000;
		}
		pwmh =pwm-pwml;
		pwmh =65535-pwmh;  
		pwml =65535-pwml;
	}
	else
	if(para[1] <(sudu_set-40))
	{
		e0 =(sudu_set-para[1])/4;
		pwml =pwmm+e0;       			//计算输出占空比
		if(pwml <1)
		{
			pwml =1;
		}
		pwmh =pwm-pwml;
		pwmh =65535-pwmh;  
		pwml =65535-pwml;
	}
}

void timer0() interrupt 1 using 0  //显示扫描
{
	if(!PWMX)
  	{
    	TH0 =pwmh>>8;
		TL0 =pwmh;
  	}
  	else
  	{
    	TH0 =pwml>>8;
		TL0 =pwml;
  	}
  	PWMX =~PWMX;
  	PWMB =PWMX;
	
}

void timer2() interrupt 5 using 2	//PWM输出
{
	TF2 =0;
	TH2 =tim>>8; 
	TL2 =tim;
	tm ++;
	if(tm ==T) 
    {		
		tm =0;
		TR1 =0;
		pid_b =1;
	}
 	display();
}

void timer_int(void)
{
	TMOD=0x51;					//设置定时器0的工作模式----定时模式,定时器1的工作模式----计数模式 //51
	T2CON=0x00;					//T2MOD=0x00;	//定时器2模式设置----定时模式(向上计数)

	TH0 =tim>>8; 
	TL0 =tim; 
	TH1 =0; 
	TL1 =0; 
	TH2 =tim>>8;
   	TL2 =tim;
	
	ET0 =0;			//定时器0开中断
	ET1 =0;			//定时器1关中断
	ET2 =1;	   		//定时器2关中断

	TR0 =1;			//启动定时器0
	TR1 =1;			//启动计数器1
   	TR2 =1;			//启动定时器2

	EA = 1;			//开总中断
}

void main()
{ 	
	char i;

	PWMB =1;
	timer_int();
	for(i=0;i<3;i++) 
		para[i]=i;					//初始化速度存储数组
	distran();						//刷新显示缓存区
	sudu_set = para[0];
	while(1)
	{
		if(keyx >0)
		{
			key =keyx;
			while(keyx!=0) {keyx=0; delay(2500);}	
			keyproc();         						//调用按键处理程序
			sudu_set =para[0];
			if(sudu_set <300)
			{
				PWMB =1;
				ET0 =0;
			}
			else
			{
				PWMB =0;
 			  	pwmm = (sudu_set/1.28)-para[2];	
				pwmh =pwm-pwmm;
				pwmh =65535-pwmh;  
				pwml =65535-pwmm;
				ET0 =1;
			}
		}
	    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 + -