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

📄 main.c

📁 51单片机的内存优化和中断的有用知识
💻 C
字号:
//切板机控制程序//
///////////////////
//////////////////////////////////////////////////////////////////////////
//									//							//									//
//作者:郑玉杰                                                     	//
//Author:Jacky Zheng							//
//国籍:中华人民共和国							//
//Nationality:People's Republic of China				//							//									//
//身份识别码:320924198602016132					//
//ID NO.:320924198602016132						//									//
//声明联系方式:电子邮箱:come_on_yujie@163.com				//
//Contact Information: E-mail:come_on_yujie@163.com			//
//日期:2009年3月1日测试完成						//
//Date:Have been finished on Mar.1,2009.				//									//
//声明版权:								//
//Copyrights:								//							//									//
//本程序为有版权的程序,未经本人书面同意任何组织和个人不得传播或使用。	//
//Please do not transmit or use it if you have not the copyrights.	//
//版权归作者所有。							//
//The copyrights belongs to the author.					//									//
//									//							//									//
//////////////////////////////////////////////////////////////////////////

/*****************************************************************************/

//头文件加入
#include "REG52.h"
#include <intrins.h>
#include <absacc.h>
#include "VI2C_C51.h"
#include "stdio.h"
#include "STRING.H"
/*****************************************************************************/
//寻址定义
#define UCHAR unsigned char
#define uint unsigned int

/****************************************************************************/
//LCD读写使能位
sbit LCDRSPIN = P3^7;
sbit LCDRWPIN = P3^6;//读写使能,lcd&da0832
sbit LCDEPIN = P2^6;

/*****************************************************************************/
//输出
sbit RING_OUT = P2^1;			//RING输出位

sbit CS = P2^4;				//步进电机使能
sbit CW = P2^5;				//步进电机正反转标志位
sbit CLK = P2^7;			//脉冲位

 
/*****************************************************************************/
//输入
sbit LEFT_BIT = P1^0;			//左限位
sbit RIGHT_BIT = P1^1;   		//右限位
sbit SAFE = P2^0;				//光电保护位
/*****************************************************************************/
//按键
sbit P3_0 = P3^4;//MANU
sbit P3_1 = P3^3;//ENTER&SAVE
sbit P3_2 = P3^2;//RUN&<-
sbit P3_3 = P3^1;//INC
sbit P3_4 = P3^0;//DEC

/*****************************************************************************/
UCHAR MANU=0;//0:运行使能状态;1:speed设置状态;2:length设置状态。
UCHAR RUN=0;// 运行
UCHAR INC=0;// 增加&向上
UCHAR DEC=0;// 减小&向下
UCHAR LEFT=0;//左移
/*****************************************************************************/
UCHAR SPEED;//速度
uint LENGTH;//行程设置
uint PLUSE;//脉冲量转换

int COUNT;

bit FLAG = 0;//按键一次标志位
bit SAVE = 0;	//保存标志位
//bit Rong = 0;
/*****************************************************************************/
void LcdWDA(unsigned char x,unsigned char y,unsigned char *s);
void Lcd_THREENO(int x,int y,int i);
/*****************************************************************************/
//显示字符定义
char * MM="MM";
char * R="R";

char * SPD="SPEED:";
char * L="L:";

char * COMPANY =  "PS-3000";
char * CLEAR = "                ";
char * PLACE=" ";
char * GO="<--";
char * BACK="-->";
char * CPS="PCS";

/*****************************************************************************/
//延时
void delaysst(unsigned int i)
{
    UCHAR j;
    for(i; i > 0; i--)
        for(j = 180; j > 0; j--);
}

/*****************************************************************************/
//RING
void RING(void)
{UCHAR S;
for(S=200;S>0;S--)
{
delaysst(1);
RING_OUT=~RING_OUT;
}
}

/*****************************************************************************/
//输入键扫描
KEY()
{FLAG=0;
//设置模
if(MANU!=0)
{
while(P3_0==0)
	{delaysst(5);
	if(P3_0 ==0&&FLAG ==0)
		{
		if(MANU<3)
		MANU++;
		else
		MANU=0;		
		LEFT=0;
		FLAG=1;
		RING();
		}
	}

while(P3_1==0)
	{delaysst(5);
	if(P3_1==0&&FLAG==0)
		{
		SAVE=1;
		MANU=0;
		FLAG=1;		
		}
	}
while(P3_2==0)
	{delaysst(5);
	if(P3_2==0&&FLAG==0)
		{if(LEFT<=3)
		LEFT++;
		else
		LEFT=0;		
		FLAG=1;
		RING();
		}
	}
while(P3_3==0)
	{delaysst(5);
	if(P3_3==0&&FLAG==0)
		{
		INC=1;		
		FLAG=1;
		RING();
		}
	}
while(P3_4==0)
	{delaysst(5);
	if(P3_4==0&&FLAG==0)
		{
		DEC=1;	
		FLAG=1;
		RING();
		}
	}
	FLAG=0;
}


/*****************************************************************************/
//使用模式
if(MANU==0)
{
	while(P3_0==0)
		{delaysst(5);
		if(P3_0==0&&FLAG==0)
			{MANU=1;
			RUN=0;	
			FLAG=1;
			RING();
			}
		}

	while (P3_1==0)
		{
		delaysst(5);
		if (P3_1==0&&FLAG==0)
			{
			SAVE=1;
			MANU=0;	
			FLAG=1;
			
			}
		}

	while (P3_2==0)
		{delaysst(5);
		if(P3_2==0&&FLAG==0)
			{
			RUN=~RUN;
			FLAG=1;
			RING();
			}
		}

 	while (P3_3==0)
		{delaysst(5);
		if(FLAG==0)
		{RING();FLAG=1;}
		if(LEFT_BIT==1&&SAFE==1)
		LcdWDA(11,1,GO);
		while(P3_3==0&&(LEFT_BIT==1||SAFE==1))
			
		{	CW=1;//步进电机正反转设置-》正转
			CLK=~CLK;
			delaysst(10000);
			}
		
		//	Lcd_THREENO(11,1,LENGTH);
		}

	while (P3_4==0)
		{delaysst(5);
		if(FLAG==0)
		{RING();FLAG=1;}
		if(RIGHT_BIT==1&&SAFE==1)
		LcdWDA(11,1,BACK);
		while(P3_4==0&&(RIGHT_BIT==1||SAFE==1))
			
		{	CW=0;//步进电机正反转设置-》正转
			CLK=~CLK;
			delaysst(10000);
			}
		//	Lcd_THREENO(11,1,LENGTH);
		
	  if(FLAG)
	  Lcd_THREENO(11,1,LENGTH);
		FLAG=0;
}
}
}
 /*****************************************************************************/
//延时
void delay(unsigned int i)
{
    UCHAR j;
    for(i; i > 0; i--)
        for(j = 8000; j > 0; j--);
KEY();
}

 /*****************************************************************************/
//初始化(单片机)
void sercon(void)
{
	SCON  = 0x50;		
	TMOD  |= 0x20;		
	TH1   = 0xFD;      
	TR1   = 1;        	
	TI	  = 1;         	
}

/*****************************************************************************/
//控制LCD
unsigned char XPOS,YPOS;

/*****************************************************************************/
//测忙
void LcdWaitIdle(void)
{  P0=0xff; 
   LCDRSPIN=0; 
   LCDRWPIN=1; 
   LCDEPIN=1;
while((P0&0x80)==0x80);
   LCDEPIN=0;
}

/*****************************************************************************/
//写指令代码
void LcdWCN(unsigned char c)
{  LCDRSPIN=0; 
   LCDRWPIN=0; 
   P0=c;
   LCDEPIN=1;
   _nop_(); 
   LCDEPIN=0; 
}

/*****************************************************************************/
//写指令代码(测忙)
void LcdWC(unsigned char c)
{  LcdWaitIdle();
   LcdWCN(c); 
}

/*****************************************************************************/
//写数据
void LcdWD(unsigned char d)
{  LcdWaitIdle(); 
   LCDRSPIN=1; 
   LCDRWPIN=0; 
   P0=d; 
   LCDEPIN=1;
   _nop_(); 
   LCDEPIN=0; 
}

/*****************************************************************************/
//内部数据地址指针定位
void LcdPos(void)
{  XPOS&=0x0f; 
   YPOS&=0x03;
   if(YPOS==0x00)
      LcdWC(XPOS|0x80);
   else if(YPOS==0x01)
      LcdWC((XPOS+0x40)|0x80);
   else if(YPOS==0x02)
      LcdWC((XPOS+0x10)|0x80);
}

/*****************************************************************************/
//lcd初始化
void InitLcd(void)
{  
LCDEPIN=0;
delay(150); LcdWCN(0x38);  /*设置8位格式,2行,2*16*/

   LcdWC(0x08);        /*清除显示*/
   LcdWC(0x06);       /*设定输入方式,增量不移位*/
   LcdWC(0x0c);    /*整体显示,关光标,不闪烁*/
}

/*****************************************************************************/
//字符串显示
void LcdWDA(unsigned char x,unsigned char y,unsigned char *s) //写显示
{
    YPOS=y;
    for(XPOS=x;XPOS<16 && *s != 0;XPOS++)
    {  LcdPos();
      LcdWD(*s);
      s++;
   }
}

/*****************************************************************************/
//数字-》一位数字显示
void Lcd_ONENO(int x,int y,int i)
{

char LS[2];
LS[0]=i+'0';
LS[1]='\0';
LcdWDA(x,y,LS);
}



/*****************************************************************************/
//数字-》三位数字显示
void Lcd_THREENO(int x,int y,int i)
{
char g,s,b,l;
char LS[4];
g=i%10;
l=i/10;
s=l%10;
l=l/10;
b=l%10;
LS[0]=b+'0';
LS[1]=s+'0';
LS[2]=g+'0';
LS[3]='\0';
LcdWDA(x,y,LS);
}

/*****************************************************************************/
//数字-》四位数字显示
void Lcd_FOURNO(int x,int y,int i)
{
char g,s,b,q,l;
char LS[4];
g=i%10;
l=i/10;
s=l%10;
l=l/10;
b=l%10;
l=l/10;
q=l%10;
LS[0]=q+'0';
LS[1]=b+'0';
LS[2]=s+'0';
LS[3]=g+'0';
LS[4]='\0';
LcdWDA(x,y,LS);
}


/*****************************************************************************/
//lcd显示
Lcdshow()
{
LcdWDA(0,0,COMPANY);
Lcd_FOURNO(9,0,COUNT);
LcdWDA(13,0,CPS);
LcdWDA(0,1,SPD);
LcdWDA(7,1,R);
LcdWDA(9,1,L);
LcdWDA(14,1,MM);
Lcd_ONENO(6,1,SPEED);
Lcd_THREENO(11,1,LENGTH);	
}

/*****************************************************************************/
//光标显示
void Lcdflash()
{
    if(MANU==1)
    { 	     
	LcdWDA(6,1,PLACE);
	delay(4000);
	Lcdshow();
	delay(4000);
	}

	if(MANU==2&&LEFT==0)
		{
		LcdWDA(13,1,PLACE);
		delay(4000);
		Lcdshow();
		delay(4000);
		}
	if(MANU==2&&LEFT==1)
		{
		LcdWDA(12,1,PLACE);
		delay(4000);
		Lcdshow();
		delay(4000);
		}
	if(MANU==2&&LEFT==2)
		{
		LcdWDA(11,1,PLACE);
		delay(4000);
		Lcdshow();
		delay(4000);
		}
	if(MANU==2&&LEFT>2)
		{
		LEFT=0;
		}

    if(MANU==3)
    { 	     
	LcdWDA(12,0,PLACE);
	LcdWDA(11,0,PLACE);
	LcdWDA(10,0,PLACE);
	LcdWDA(9,0,PLACE);
	delay(4000);
	Lcdshow();
	delay(4000);
	}	 
}
/*****************************************************************************/
//读数据
void READ()
{
UCHAR X;
UCHAR Y;
IRcvStr(0xA0,0x600,&SPEED,1);

IRcvStr(0xA0,0x620,&X,1);
IRcvStr(0xA0,0x630,&Y,1);
LENGTH=Y%10*100+X%100;

IRcvStr(0xA0,0x640,&X,1);
IRcvStr(0xA0,0x650,&Y,1);
COUNT=Y%100*100+X%100;
}

/*****************************************************************************/
//写数据
WRIGHT ()
{
UCHAR X;
UCHAR Y;
ISendStr(0xA0,0x600,&SPEED,1);

X=LENGTH%100;
Y=LENGTH/100%10;
ISendStr(0xA0,0x620,&X,1);
ISendStr(0xA0,0x630,&Y,1);

X=COUNT%100;
Y=COUNT/100%100;
ISendStr(0xA0,0x640,&X,1);
ISendStr(0xA0,0x650,&Y,1);

Lcdshow(); 
RING();
}
/*****************************************************************************/
//参数匹配
void MADE()
{
if (MANU==1)
	{if (INC==1)
		{SPEED++;
		INC=0;}
	if (DEC==1)
		{SPEED--;
		DEC=0;}
	}


if (MANU==2)
	{ if(LEFT>2)
		 	{
			 LEFT=0;
		 	}
		if(LEFT==0)
		 	{
			 if (INC==1)
				{LENGTH++;
				INC=0;}
			 if (DEC==1)
				{LENGTH--;
				DEC=0;}
		 	}
		if(LEFT==1)
		 	{
			 if (INC==1)
				{LENGTH+=10;
				INC=0;}
			 if (DEC==1)
				{LENGTH-=10;
				DEC=0;}
		  	}
		if(LEFT==2)
		 	{
			 if (INC==1)
				{LENGTH+=100;
				INC=0;}
			 if (DEC==1)
				{LENGTH-=100;
				DEC=0;}
		  	}
	}

if (MANU==3)
{
 			 if (INC==1)
				COUNT=0;
			 if (DEC==1)
				COUNT=0;


}

if(SPEED<0||SPEED>9)
SPEED=0;

if(LENGTH<0||LENGTH>999)
LENGTH=0;
}

/***************************************************************************/
//电机运行
MOTOR_RUN()
{
UCHAR WAIT;
WAIT=10-SPEED;	// 脉冲占空比设置
if(LEFT_BIT==1&&RIGHT_BIT==1&&SAFE==1)
LcdWDA(11,1,GO);
for(PLUSE=LENGTH*100;SPEED!=0&&PLUSE>0&&RUN;PLUSE--)// 脉冲量设置		
		{	
			CW=1;//步进电机正反转设置-》正转
			if(LEFT_BIT==0||RIGHT_BIT==0||SAFE==0)
			{CS=0;RUN=0;}
			else
			CS=1;// 步进电机使能
			CLK=~CLK;
			delay(WAIT);			
		 }

if(LEFT_BIT==1&&RIGHT_BIT==1&&SAFE==1)
LcdWDA(11,1,BACK);

for(PLUSE=LENGTH*100;SPEED!=0&&PLUSE>0&&RUN;PLUSE--)// 脉冲量设置		
		{	
			CW=0;//步进电机正反转设置-》反转
			if(LEFT_BIT==0||RIGHT_BIT==0||SAFE==0)
			{CS=0;RUN=0;}
			else
			CS=1;// 步进电机使能
			CLK=~CLK;
			delay(WAIT);			
		 }
Lcd_THREENO(11,1,LENGTH);

COUNT++;
WRIGHT();

RUN=0;
CS=0;
}

/*****************************************************************************/ 
//主程序
main()
{	
	sercon();
	InitLcd();
	CS=0;	
	LcdWDA(0,0,CLEAR);
	LcdWDA(0,1,CLEAR);
    READ();
	MADE();
	delay(2000);
	LcdWDA(0,0,CLEAR);
	LcdWDA(0,1,CLEAR);
    Lcdshow();	
while(1)
   {	
 if(SAVE)
	 {
	 WRIGHT();
	 SAVE=0;
	 }	 
	 KEY();
	 Lcdflash();
	 MADE();
  if(RUN)
	{
	MOTOR_RUN();
	}
   }
}

⌨️ 快捷键说明

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