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

📄 dttsc21c04.c

📁 多款电脑绣花机电机驱动控制程序
💻 C
字号:
/*********************************
毛巾换色单头提升控制程序
	补绣
	断线检测
**********************************/
#include "REG52.h"
#include <intrins.h>	
#include <math.h>

#define PRECISION		1	//提升精度
#define PRECISION1	5	//静态精度
#define STEPAD		46	//色序间隔A/D值
code unsigned int res[11]={104,150,196,242,288,334,380,426,472,518,945};		//提升11个档位固定电阻值11档为锁头档
//**************************************
int data result;				//A/D转换10位结果
int data dataen;			//数据选通
int direction;				//正反转
unsigned int head;			//头数0~31
unsigned int readseq;		//=0读低2位......=4读最高2位

int run;					//是否运转中	0:停车状态1: 运转状态
unsigned int revcmd;

unsigned int uppoints;
unsigned int contime;
unsigned int contime1;

unsigned int newposition;	//提升或者下降的档位,不含最高档位
unsigned int newp;			//读取档位值
unsigned int nowpos;		//
unsigned int workpos;		//

unsigned int curad;
unsigned int curad1;
unsigned int curad2;		//A/D转换结果
unsigned int oldad;
unsigned int newad;		//新档标准阻值

bit runFlag;
bit down;					//拨下位,只上升一次
bit ok;
bit mendFlag;				//补绣标志
bit lockFlag;				//锁头标志
bit mendswitch;			//补绣开关

unsigned int syc;      		//循环读档
unsigned int nowswitch;		//当前机头板开关档位值
//**************************************
//回送主控信号**********************
sbit riseerr=P3^1;		//err=0 针杆高度异常=1到位
sbit rising=P3^6;		//state0=0  正在提升  =1提升完毕
sbit lores=P3^6;		//读档位,低一位
sbit hires=P3^7;		//读档位,高一位
sbit sd0=P3^6;				//测试状态
sbit sd1=P3^7;
sbit sd2=P0^5;
sbit sd3=P0^6;
//功能选通信号
sbit u5e0=P0^0;		//选通AD0-AD7
sbit u5e1=P0^1;		//选通AD8-AD11、AD13
sbit u5e2=P0^2;		//选通拨码开关
//TLC1549信号*********************
sbit sclk=P2^1;
sbit cs=P2^2;
sbit dout=P2^3;
//提升电机驱动信号**************
sbit step=P2^5;
sbit dir=P2^6;
sbit en=P2^7;
sbit hf=P2^4;
//上位机输入信号******************
sbit ad0=P1^0;            //AD8
sbit ad1=P1^1;            //AD9
sbit ad2=P1^2;            //AD10
sbit ad3=P1^3;            //AD11
sbit ad4=P1^4;
sbit ad5=P1^5;            //AD13
sbit ad6=P1^6;
sbit ad7=P1^7;

sbit ad8=P1^0;
sbit ad9=P1^1;
sbit ad10=P1^2;
sbit ad11=P1^3;
sbit ad13=P1^5;
sbit ad12=P3^2;		//C1板数据选通信号INT0
//断检信号**********
sbit broken=P2^0;		//jpos1  =0断线 =1正常
//锁头补绣信号*****************
sbit mendin=P1^6;		//IN0
sbit lockin=P1^5;		//IN1
//锁头补绣指示灯信号*******
sbit locklamp=P0^4;		//OUT1锁头
sbit mendlamp=P0^3;	//OUT0补绣/提升出错闪烁
//**************************************
sbit lamp=P0^7;
//**************************************
void	ex44us(void)
{
	int	i=2;
	while(i--);
}
void delay44us(unsigned int nums)
{
	do
	{
	   	ex44us();
		nums--;
	}while(nums!=0);
}
/**********************************************
	串行10位AD转换函数AtoD()
	返回值result
***********************************************/
unsigned int  AtoD()
{   
	int data i;
	cs=1;     	//禁止
	result=0;
	cs=0;  	//开启控制电路,使能DATA OUT和I/O CLOCK
	_nop_();
	_nop_();
	result=(unsigned int)(dout) ;      
	for(i=0;i<9;i++)    //采集10次 ,即10bit
	{                   
		result=result<<1;
		sclk=1;
		_nop_();
		sclk=0;
		result=(result|(unsigned int)(dout));  
	}
	sclk=1;
	_nop_();
	sclk=0;		      
	for(i=0;i<9;i++);
	cs=1; //DATA OUT 返回到高阻状态而终止序列	
	return(result); //返回变量result
}
//************************************
void evenAD(void)
{
	curad=AtoD();
	curad1=AtoD();
	curad2=AtoD();
	curad=(curad1+curad2)/2;
}
/*************************************
	区分命令
	IN:ad8~ad11
	OUT:	0:提升	2:读提升档位	13:初始化
*************************************/
unsigned int RevCommand()
{
	unsigned int cmd=0;
	u5e1=0;
	delay44us(3);
	cmd=(unsigned int)ad13;
	cmd=(cmd<<1)|(unsigned int)ad11;
	cmd=(cmd<<1)|(unsigned int)ad10;
	cmd=(cmd<<1)|(unsigned int)ad9;
	cmd=(cmd<<1)|(unsigned int)ad8;
	u5e1=1;
	return (cmd);
}

/*************************************
	IN:ad7~ad0		cmdtype=0:提升	2/3:读档位	13:初始化
	OUT:档位/运转否
*************************************/
 unsigned int DealCmdData(int cmdtype)
 {
 	unsigned int cmd=0;
 	unsigned int cmdsir[8];
 	int i;
 	
 	u5e0=0;
 	delay44us(3);
 	if(cmdtype==0)			//档位0~10
 	{
 		cmd=ad3;
 		cmd=(cmd<<1)|(unsigned int)ad2;
		cmd=(cmd<<1)|(unsigned int)ad1;
		cmd=(cmd<<1)|(unsigned int)ad0;
	}
	else if(cmdtype==1)
	{
		head=ad4;	
		head=(head<<1)|(unsigned int)ad3;
		head=(head<<1)|(unsigned int)ad2;
		head=(head<<1)|(unsigned int)ad1;
		head=(head<<1)|(unsigned int)ad0;
		readseq=ad7;
		readseq=(readseq<<1)|(unsigned int)ad6;
		readseq=(readseq<<1)|(unsigned int)ad5;
	}
	if(cmdtype==2)			//1:补绣/0:补绣完
 	{
 		cmd=ad0;
	}
	if(cmdtype==3)		//当前位置
 	{
 		cmd=ad1;
		cmd=(cmd<<1)|(unsigned int)ad0;
	}
	else if(cmdtype==10)	//转速0~60
 	{
 		cmd=ad5;
		cmd=(cmd<<1)|(unsigned int)ad4;
		cmd=(cmd<<1)|(unsigned int)ad3;
		cmd=(cmd<<1)|(unsigned int)ad2;
		cmd=(cmd<<1)|(unsigned int)ad1;
		cmd=(cmd<<1)|(unsigned int)ad0;
	}
	else if(cmdtype==13)
	{
		cmdsir[0]=ad0;
		cmdsir[1]=ad1;
		cmdsir[2]=ad2;
		cmdsir[3]=ad3;
		cmdsir[4]=ad4;
		cmdsir[5]=ad5;
		cmdsir[6]=ad6;
		cmdsir[7]=ad7;
		for(i=0;i<8;i++)
		{
			if(cmdsir[0]!=cmdsir[i])
			{
				u5e0=1;
				return(1);					//通讯不过
			}
		}
		u5e0=1;
		return(0);
	}
	u5e0=1;
 	return (cmd);
}

 /*************************************
	发送一个脉冲(f=1k),驱动电机
*************************************/
void	SendPulse(unsigned int ttime)
{
	step=1;
	ex44us();
	step=0;
	delay44us(ttime);
}

 /*************************************
	提升函数		
	传动比1:4
	细分:1:32
	输入:要提升的档位
	返回:0:正常  1:错误
*************************************/
int HeadUpOrDown(unsigned int newpos)
{
	int i=0;
	
	riseerr=0;
	rising=0;
	
	newad=res[newpos];

	evenAD();
	oldad=curad;
	
	if(abs(newad-curad)<PRECISION1)		//精度范围内,到位
	{
		riseerr=1;
		rising=1;
		return(0);
	}
	
	en=1;
	_nop_();
	_nop_();
	_nop_();
	_nop_();
	_nop_();
	
	//if((curad>980)||(curad<50))
	//	return(1);	
	
	if(newad>curad)
	{
		direction=0;					//电机正转
		dir=0;
	}
	else
	{
		direction=1;					//电机反转
		dir=1;
	}
	if(abs(newad-curad)>(STEPAD-20))
	{
		uppoints=abs(newad-curad)*40;
		uppoints=uppoints/1023;
		uppoints=uppoints*80-60;
		runFlag=1;
	}
	else
	{
		uppoints=0;
		runFlag=0;
	}
	
	i=0;
	contime=5;
	contime1=10;
	while(abs(newad-curad)>PRECISION)	
	{
		if(runFlag==1)
			SendPulse(contime);
		else
		{
			SendPulse(contime1);
			evenAD();
		}
		//if((curad>98)||(curad<50))
		//	return(1);	

		i++;
		if(i>uppoints)		//开始变速
		{
			runFlag=0;
		}
		if(i>3200)			//转一圈,没到位,说明电位器有问题
		{
			en=0;
			rising=1;
			return(1);
		}
	}
	en=0;
	
	evenAD();
	if(abs(newad-curad)<=PRECISION1)		//精度范围内,到位
	{
		riseerr=1;
		rising=1;
		return(0);
	}
	else
	{
		rising=1;
		return(1);
	}
}

void External0(void) interrupt 0 using 2
{
	EA=0;
	dataen=0;
	EA=1;
}
		 		
void main()
{
	unsigned char  i;
	unsigned int myhead=0;	//本机编号,由上电读拨码开关识别
	unsigned char	bpos;
	unsigned char	breakpos;
	//int checkcom=1;		//开机检查通讯线全低		=1有错误   =0正常
	//int checkcom2=1;		//开机检查通讯线全高		=1有错误   =0正常
	
	run=0;
	nowpos=15;
	newp=0;
	down=1;
	syc=0;
	mendFlag=0;			//补绣命令
	lockFlag=0;			//锁头开关
	breakpos=1;			//未断线
	mendswitch=0;			//补绣开关
	
	
	for(i=0;i<3;i++)
	{
		lamp=0;
		delay44us(3000);
		lamp=1;
		delay44us(3000);
	}
		
	IT0=1;
	EX0=1;
	TR0=0;
	ET0=0;
	IE0=0;
	EA=1;
  	
  	dataen=1;
	riseerr=1;
	rising=1;
	
	//读拨码开关确定本机头号
	u5e2=0;
	ex44us();
	myhead=ad4;
	myhead=(myhead<<1)|(unsigned int)ad3;
	myhead=(myhead<<1)|(unsigned int)ad2;
	myhead=(myhead<<1)|(unsigned int)ad1;
	myhead=(myhead<<1)|(unsigned int)ad0;
	u5e2=1;
	
	en=0;	//提升电机关闭
	_nop_();
	
	/*while(checkcom==1)
	{
		_nop_();
		locklamp=1;		//有错误,熄灯
		mendlamp=1;
		if(dataen==0)
		{
			revcmd=RevCommand();
			dataen=1;
		}
		if(revcmd==13)	
			checkcom=DealCmdData(13);
		if(checkcom==0)
			riseerr=1;
	}
	
	while(checkcom2==1)
	{
		_nop_();
		locklamp=1;		//有错误,熄灯
		mendlamp=1;
		riseerr=0;
		if(dataen==0)
		{
			revcmd=RevCommand();
			dataen=1;
		}
		if(revcmd==13)
			checkcom2=DealCmdData(13);
		if(checkcom2==0)
			riseerr=1;
	}*/
	
	while(1)
	{
		revcmd=15;
		
		if(run==0)
		{
			evenAD();
			nowpos=15;
			if((curad>(res[0]-PRECISION1*2))&&(curad<(res[9]+PRECISION1*2)))
			{
				for(i=0;i<=9;i++)
				{
					if(abs(curad-res[i])<PRECISION1*2)
						nowpos=i;
				}
			}
			if((curad>935)&&(curad<1000))
				nowpos=10;
				
			/*if(breakpos==1)
			{
				mendlamp=0;		//点亮断线(补绣)灯
				locklamp=1;
				lamp=0;
			}*/
	
			u5e2=0;//选通拨码开关
			delay44us(10);
			nowswitch=lockin;							//in1
			nowswitch=(nowswitch<<1)|(unsigned int)mendin;	//in0
			u5e2=1;
			if(nowswitch==3)		//中位
			{
				down=1;
				if((mendswitch==0)&&(breakpos==1))	//不补绣未断线
				{
					locklamp=0;	//绿灯亮out0
					mendlamp=1;	//out1
				}
				if(lockFlag==1)
				{
					lockFlag=0;
					locklamp=0;
					mendlamp=1;
				}
			}
			else if(nowswitch==1)	//上位(补绣)
			{
				delay44us(1000);
				if(mendswitch==0)
				{
					mendswitch=1;		//置标志
					locklamp=1;
					mendlamp=0;		//亮红灯
				}
				else
				{
					mendswitch=0;		//清标志
					mendlamp=1;		//灭红灯
					locklamp=0;
				}
				down=1;
				delay44us(10000);
			}
			else if(nowswitch==2)	//下位(锁头)
			{
				if(down==1)
				{
					lockFlag=1;
					locklamp=1;
					mendlamp=1;
					mendswitch=0;
					HeadUpOrDown(10);
					nowpos=10;
					down=0;
				}
			}
		}
		
		if(dataen==0)
		{
			revcmd=RevCommand();
			dataen=1;
			sd0=1;
			sd1=1;
			sd2=1;
			riseerr=1;
		}
		switch(revcmd)
		{
			case 15:			//无效
			break;
			case 0:				//提升
				if(lockFlag==1)
					break;
				newp=DealCmdData(0);		//工作位
				if(newp==nowpos)
				{
					riseerr=1;
					rising=1;
				}
				else
				{
					if(mendFlag==0)
					{
						ok=HeadUpOrDown(newp);
						nowpos=newp;
					}
					else
					{
						if(mendswitch==1)
						{
							ok=HeadUpOrDown(newp);
							nowpos=newp;
						}
					}
					if((breakpos==0)&&(nowpos==10))
					{
						locklamp=0;
						mendlamp=1;
					}
					if(ok==0)
						riseerr=1;
					rising=1;
					//nowpos=newp;
				}
			break;
			case 1:
				DealCmdData(1);
				if(readseq==7)		//进入读档位界面,内循环
					syc=1;
				
				while(syc==1)
				{
					lamp=0;
					revcmd=15;
					if(dataen==0)
					{
						revcmd=RevCommand();
						revcmd=RevCommand();
						dataen=1;
					}
					if(revcmd==1)
					{
						DealCmdData(1);
						DealCmdData(1);
						if(readseq==6)			//退出读档界面
						{
							syc=0;
							lores=1;
							hires=1;
							lamp=1;
						}
						else if(readseq==7)	//进入读档界面
						{
							syc=1;
						}
						else if(readseq==5)	//查询一次完毕
						{
							lores=1;
							hires=1;
						}
						else if(readseq<5)	//5次查询
						{
							if(head!=myhead)
								curad=AtoD();
							else
							{
								curad=AtoD();
								lores=(curad>>(readseq*2))&0x01;
								hires=(curad>>(readseq*2+1))&0x01;
							}
						}
					}	
				}
			break;
			case 2:
				if(DealCmdData(2)==1)
					mendFlag=1;		//此头要补绣,置标志
				else
				{
					if(lockFlag==0)
						locklamp=0;
					else
						locklamp=1;
					mendlamp=1;
					mendFlag=0;
					mendswitch=0;
				}
			break;
			case 3:
				if(lockFlag==1)
					break;
				bpos=DealCmdData(3);		//命令值
				if(bpos==3)
				{
					//sd0=breakpos&0x01;
					riseerr=breakpos&0x01;
					
					if(broken==1)
					{
						i=0;
						do
						{
							if(broken==0)
							{
								breakpos=1;
								break;
							}
							delay44us(230);
							i++;
						}while(i<5);
						breakpos=0;
					}
					else
						breakpos=1;
				}
			break;
			case 10:
				if(DealCmdData(10)!=0)
				{
					run=1;
					
					breakpos=1;
					if((lockFlag==0)&&(mendFlag==0))
					{
						mendlamp=1;		//灭断线(补绣)灯
						locklamp=0;
					}
				}
				else
				{
					run=0;
					//if((breakpos==1)&&(lockFlag==0))
					if(broken==1)
					{
						mendlamp=0;		//点亮断线(补绣)灯
						locklamp=1;
					}
				}
			break;
			default:
			break;
		}
	}
}

⌨️ 快捷键说明

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