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

📄 电机无级调制控制系统.cpp

📁 关于8279的中文资料 要用到这个芯片的朋友们肯定用得着
💻 CPP
字号:
/*  电机无级调速控制系统   */
#include <stdio.h>
#include <conio.h>
#include "ApiEx.h"
#pragma comment(lib,"ApiEx.lib")

#define	ioport	0x2b0		//8279 数据口
#define	ioport1	0x2b1		//8279 控制口
#define	time	0x280		//8253 定时器0口地址
#define	time1	0x281		//8253 定时器1口地址
#define	timec	0x283		//8253 控制口地址
int k;
int disled[6]={0x00,0x00,0x00,0x00,0x00,0x00};//led从右到左显示,最左显示功能键
int realkey[4]={0x00,0x00,0x00,0x00};//得到真实的按键值
int led[] ={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x77,0x7C,
		0x39,0x5E,0x79,0x71,0x80,0x40};//0,1,2,3,4,5,6,7,8,9,A,b,C,d,E,F,g,m,P,r,w,x,y,.,-
int table[]={0x1b,0x13,0x0b,0x03,0x1a,0x12,0x0a,0x02,0x19,0x11,0x09,0x01,0x18,0x10,0x08,0x00};
int keyin=0;
void key();		//键盘显示
void disp();	//显示
void int_proc();	//中断处理程序
void motorstart();//启动电机
void measurespeed();//测量转速
void pidadapt();//PID调速
int funkey=0;//0表示是功能键,1表示数字键
int datakey=0;//表示之前未按功能键,1表示按下了功能键
int keydatanum=0;//表示按下数字键的个数
int keycdown=0;//表示按下了E键
int keyedown=0;//表示按下了C键
int keyadaptspeed=0xff;
int getspeed=0;//测得的转速
int j=0;
int jj=0;
int d=0;//存放给定的速度换算成高电平持续时间
int saved=0;
int  keysave=0;//保存初始转速的键值
BYTE  data;//存放按键值
BYTE data1=0x00;//存计数的低8位
BYTE data2=0x00;//存计数的高8位
int count=0;//得到定时器2的当前计数值
int count1=0;//测到的转速值
int mspeed[2]={0x00,0x00};
void main()
{
	printf("--------------------EXP29_21_SYB---------------------\n");
	printf("Press any key to begin!\n\n");
	getch();
	printf("Press small keybord:\n");
	printf("A--please input the given speed;\n");
	printf("B--STOP MOTOR \n");
	printf("c--start the motor according the given speed;\n");
	printf("F--EXIT\n");
	if(!Startup())		/*打开设备*/
	{
		printf("ERROR: Open Device Error!\n");
		return;
	}
	PortWriteByte(ioport1,0xd3);	//8279 清零
	PortWriteByte(ioport1,0x40);	//读FIFO存储器命令
	PortWriteByte(ioport1,0x00);	//置键盘显示模式
	PortWriteByte(ioport1,0x80);	//写显示缓冲区命令
	PortWriteByte(0x283,0x36);		//设置8253工作方式,定时器0工作方式3
    PortWriteByte(0x280,0x50);		//设置定时器0的初始计数值50000,低位为50
    PortWriteByte(0x280,0xc3);		//设置定时器0的初始计数值50000,高位为c3产生50ms的脉冲
    PortWriteByte(0x283,0xb0);		//设置8253工作方式,定时器2工作方式0,(计脉冲的个数)
	PortWriteByte(0x282,0xff);		//设置定时器2的初始计数值ffff,低位为ff
	PortWriteByte(0x282,0xff);		//设置定时器2的初始计数值ffff,高位为ff
    PortWriteByte(0x28b,0x81);		//设置8255工作方式,C口低四位输入, C口高四位输出,A口输入,B口输入
	PortWriteByte(0x283,0x50);		//设置8253工作方式,定时器1工作方式0
	PortWriteByte(0x281,0x0a);		//设置定时器1的初始计数值20,低位为14,定时1s 
    RegisterLocalISR(int_proc);		/*注册中断程序*/
EnableIntr();		/*开中断*/
	do{
   	key();		//调键盘显示子程序

if(keyin==0x0a)		//是否'a'命令,启动输入电机起始值
		{
			disled[5]=led[0x0a];//显示键A
			for(jj=0;jj<4;jj++)//清真实的数字键值
			{ realkey[jj]=0;	}	
            disled[0]=led[0];//显示给定值为00
            disled[1]=led[0];
            disled[2]=led[0];//显示测速值为00
            disled[3]=led[0];
			funkey=0;//表示按下了功能键    
			keycdown=0;//表示没有按下功能键E  
		    keyedown=0;//表示没有按下功能键C        
			datakey=1;//表示当前按下A功能键
			mspeed[0]=0;//测定的速度显示为00
			mspeed[1]=0;
	        d=0;//给定的脉宽值为0
		}

		
else if(keyin==0x0b)		//是否'b' 命令,停止电机
		{
			disled[5]=led[0x0b];//显示键B
            disled[0]=led[0];//显示给定值为00
            disled[1]=led[0];
            disled[2]=led[0];//显示测速值为00
            disled[3]=led[0];
	        disled[4]=0x00;
			for(jj=0;jj<4;jj++)
			{
               realkey[jj]=0;
			}
			mspeed[0]=0;//测定的速度显示为00
			mspeed[1]=0;
			funkey=0;//表示按下了功能键		         
			keycdown=0;//表示没有按下功能键E  
		    keyedown=0;//表示没有按下功能键C    			    
		    datakey=0;//表示当前没按下A功能键
	        d=0;//给定的脉宽值为0
			keydatanum=0; //计录的按下数字键值为0个           
			PortWriteByte(0x290,0x80);	/*D/A 输出*/
		}

else if(keyin==0x0c)	//是否'c' 命令,按照a给定的值使电机转动
		{	
			d=realkey[0]+realkey[1]*10;
   	        disled[5]=led[0x0e];
            disled[0]=led[realkey[0]];//显示给定值
            disled[1]=led[realkey[1]];
            disled[2]=led[0];//显示测速值为0
            disled[3]=led[0];
	        disled[4]=0x00;
			mspeed[0]=0;//测定的速度显示为00
			mspeed[1]=0;
			funkey=0;//表示按下了功能键           
			keycdown=1;//表示没有按下功能键C  
		    keyedown=0;//表示按下功能键E  
        	keydatanum=0; //计录的按下数字键值为0个 	
	        disled[2]=led[mspeed[0]];//显示测速值的低位
	        disled[3]=led[mspeed[1]];//显示测速值的高位
	
	}
		else //按下的是数字键
		{
			mspeed[0]=0;//测定的速度显示为00
			mspeed[1]=0;
			if ((datakey==1)&&(keycdown==0))//如果按下了A键之后,可以继续按数字键,此时输入的是给定的转速值
		   {
	        
			 keycdown=0;//表示没有按下功能键C 
		     keyedown=0;//表示按下功能键E  
	          d=0;//给定的脉宽值为0              
			  keysave=keyin;
			  keydatanum++;
			  realkey[keydatanum-1]=keyin;
              disled[keydatanum-1]=led[keysave];
              disled[2]=led[0];
              disled[3]=led[0];
              disled[4]=0x00;
		
		   }
		}
	}

while(!(keyin==0x0f));		//'f'命令,退出程序
	d=0;
    PortWriteByte(0x290,0x80);	/*D/A 输出*/
	PortWriteByte(ioport1,0xd1);		//清显示
    DisableIntr();	/*关中断*/
	Cleanup();		/*关闭设备*/ 

}

void key()
{ 
	PortWriteByte(ioport1,0xd1);		//清显示
    PortWriteByte(0x290,0x80);	/*D/A 输出*/
	Sleep(100);
	do{
		disp();		//调显示子程序
		if(keycdown==1)//C键
		{
           motorstart();//电机开始转动
          
		   if(keyedown==1)//如果进入调速函数
		   {
                pidadapt();            
			
		   }
		}

		PortReadByte(ioport1,&data);
	}
	while(!(data&0x07));

	PortReadByte(ioport,&data);		//读状态
	keyin = data & 0x07;
	data = data & 0x3f;
    for(k=0;k<16;k++)
	{
		if(data==table[k])
			keyin=k;
	}
}
//数码管显示,最高位(最左)显示当前功能键,最右两位显示给定值,第三、四位显示测速值
//由void key()函数调用
void disp()
{
	PortWriteByte(ioport1,0x90);
	Sleep(100);
	PortWriteByte(ioport,disled[0]);
	PortWriteByte(ioport,disled[1]);
	PortWriteByte(ioport,disled[2]);
	PortWriteByte(ioport,disled[3]);
	PortWriteByte(ioport,disled[4]);
	PortWriteByte(ioport,disled[5]);
}
//中断处理程序,定时1s,由void measurespeed()进入
void int_proc()
{        
	         getspeed=0;
	         data1=0x00;//存计数的低8位
             data2=0x00;//存计数的高8位
             count=0;//得到定时器2的当前计数值
             count1=0;//测到的转速值
             PortReadByte(0x282,&data1);     //读入计数器的低8位
             PortReadByte(0x282,&data2);     //读入计数器的高8位
             count=data2*256+data1;
             count1=(65535-count)*2/6;         //得到转速  
             getspeed=count1;
			 printf("getspeed=%d\n",getspeed);
             mspeed[0]=getspeed%10;//得到测到的转速的低位
             mspeed[1]=getspeed/10;//得到测到的转速的高位
		     disled[2]=led[mspeed[0]];//显示测速值的低位
             disled[3]=led[mspeed[1]];//显示测速值的高位
	         PortWriteByte(0x283,0x50);		//设置8253工作方式,定时器1工作方式0
	         PortWriteByte(0x281,0x0a);		//设置定时器1的初始计数值200,低位为c8,定时1s
    	     PortWriteByte(0x283,0xb0);		//设置8253工作方式,定时器2工作方式0,(计脉冲的个数)
	         PortWriteByte(0x282,0xff);		//设置定时器2的初始计数值ffff,低位为ff
	         PortWriteByte(0x282,0xff);		//设置定时器2的初始计数值ffff,高位为ff
             PortWriteByte(0x28b,0x0f);     //初始状态时,PC7,393清零端置1,
             PortWriteByte(0x28b,0x0c);    //初始状态时,PC6,393计数端置0,

}
//电机转动函数模块,由void key()调用
void motorstart()
{
   
   int pulse=0;
   pulse=d*128/48;
	if(pulse>128)
	{
	  PortWriteByte(0x290,0xff);	/*D/A 输出*/
	}
	else
	{
		pulse=0x80+pulse;
	    PortWriteByte(0x290,pulse);	/*D/A 输出*/
	}
}
//测量电机的转速,由void key()调用
void measurespeed()
{  
}
//pid调速算法
void pidadapt()
{  
 int R=0;int es=0;int es1=0;int es2=0;
int es3=0;int es4=0;int es5=0;int es6=0;int es7=0;
int es8=0;int es9=0;int es10=0;int ies=0;int des=0;
int M=0;
int e1=0;  int S=0;
         es10=es9;        //(以下是PID控制算法)
			es9=es8;
			es8=es7;
			es7=es6;
    		es6=es5;  
			es5=es4;  
			es4=es3;
			es3=es2;
			es2=es1;
			es1=es;
			es=R-getspeed;
			ies=1*(es+es1+es2+es3+es4+es5+es6+es7+es8+es9+es10);
			des=es1-es2;
			M=int (es+0.1*des+0.0001*ies);
        motorstart();//电机开始转动
        e1=e1+M;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -