📄 dttsc21c04.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 + -