📄 zhoujian.c
字号:
#include <reg52.h>
#include <absacc.h>
#define uchar unsigned char
#define uint unsigned int
#define ulong unsigned long
#define CSKEY XBYTE[0x0080] //键盘
#define CSBIT XBYTE[0x0081] //位选
#define CSSEG XBYTE[0x0082] //段选
#define OLE1 XBYTE[0x0083]
#define Baud 0xf4 //计数初值
#define ADDR 0 //YDY地址
sbit P10=P1^0; //data
sbit P12=P1^2; //clock
sbit P11=P1^1; //latch
sbit P33=P3^3; ///INT1 h1
sbit P34=P3^4; //T0 h2
bit judge1,dd1,dd2; // ++++++++
bit ss; //串口接收标志
uchar seg[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90, 0x08,0x06,0xc6,0xff,0x7f,0xbf,0x0e,0x03}; //数码管
// 0 1 2 3 4 5 6 7 8 9 //"A.""E." "C" " " " ." "-" "F.""b."
uchar aa,bb,cc; //测试时数码管显示暂存
uchar dSegD[8]=0xff; //显示段码内容存放
uchar Tt[4]; //测量结果 Tt[0]:均值
uchar TtHD; //结果指针 0:无测量 1~3:结果
uchar Md; //最大差值
uchar sbuffer[4]; //串口缓冲区
uchar sbufferpt; //缓冲区指针
uchar sbuftemp;
uchar accTime; //加速测试定时器计数
void delay(uint t)
{ while(t--); //22+11*t us延时
}
void delayl(uint t)
{ uchar i;
for(i=0;i<t;i++)
{ delay(0xffff); // 0.721*t S延时
}
}
uchar Mdpr(uchar a,b,c) //求三数最大差值
{ uchar M,S;
if(a>b){M=a;S=b;}
else{M=b;S=a;}
if(M<c){M=c;}
else if(S>c){S=c;}
return(M-S);
}
//------------------------------------------------------------
void initD() //数据初始化
{ Tt[0]=0;Tt[1]=0;Tt[2]=0;Tt[3]=0;
TtHD=0;
Md=0;
accTime=0;
}
void initS()
{ SCON=0;
TCON=0;
IE=0;
}
void initSB()
{ sbuffer[0]=0;sbuffer[1]=0;sbuffer[2]=0;sbuffer[3]=0; //串口缓冲区
sbufferpt=0;
sbuftemp=0;
ss=0; //串口接收标志
}
//---------------------------------------------------------------
void SgBtOut(uchar s,b)
{ CSSEG=s;
CSBIT=b;
}
void TstDspP(uchar a,b,c) //测试时数码管显示准备
{ uchar temp;
aa=a;bb=b;cc=c;
//if (a>=4) ah=seg[10];
//else ah=seg[a];
dSegD[0]=seg[aa];
dSegD[1]=0xff;
temp=bb/10;
dSegD[2]=seg[temp]&0x7f; //加小数点
temp=bb%10;
dSegD[3]=seg[temp];
dSegD[4]=0xff;
dSegD[5]=0xff;
temp=cc/10;
dSegD[6]=seg[temp]&0x7f; //加小数点
temp=cc%10;
dSegD[7]=seg[temp];
}
void dsply2p(uchar j1,d1,d2)
{ judge1=j1;dd1=d1;dd2=d2;
}
void dsply()
{ uchar i;
uchar b=0x01; //位选
for(i=0;i<7;i++)
{ SgBtOut(dSegD[i],b);
delay(20);
b=b<<1;
}
SgBtOut(dSegD[7],b);
delay(10);
}
dsply2()
{ if(judge1==0)
{ if(dd2==0) OLE1=0xff;
else OLE1=0xef;
}
else if (dd1) OLE1=0xfb; //0xf7 错误; 0xfb 正确;
else OLE1=0xf7;
}
void Idsply(uchar i,d)
{ uint t;
dSegD[0]=seg[i];dSegD[1]=0xff;dSegD[2]=0x7f;dSegD[3]=seg[d];
dSegD[4]=0xff;dSegD[5]=0xff;dSegD[6]=0xff;dSegD[7]=0xff;
t=0x500;
while(t--) //显示3 s
{ dsply();
}
TstDspP(TtHD,Tt[TtHD],Md);
}
void dsplytemp() //4.2s显示当前烟度值
{ uint t;
t=0x0800;
while(t--)
{dsply();
}
}
void waitDspP() //等待状态显示:两点
{ SgBtOut(0x7f,0x44);
//OLE1=0xff;
}
//-----------------------------------------------------------------
void receive(void) interrupt 4 using 3
{ RI=0;
ss=1;
sbuftemp=SBUF;
sbuffer[sbufferpt++]=sbuftemp; //以后改为工作寄存器之类的存储
}
void OutToSBF(bit tb,uchar x) //串口输出
{ TB8=tb;
SBUF=x;
while(!TI);
TI=0;
}
void testM()
{ uint t;//t1;
SCON=0xc0; //方式3,不允许接收,SM2=0
TMOD=0x20; //TIMER1 工作于方式2
TH1=230; //波特率 1200
TR1=1; //启动TIMER1
ET1=0; //关回0中断
ES=0;
EA=0;
OutToSBF(1,ADDR); //-----地址帧-----
//++++++++++++++++++检查烟度仪准备好否+++++++++++++++++++
REN=1; //准备接收 SCON=0xd0; 串行方式3,sm2=0,REN=1;
IE=0x90; //ES=1;EA=1; 开接收中断
t=0;
ss=0;
while((!ss)&&(t<32000))//0.4s 超时
{t++;}
IE=0; //关中断
REN=0;
if(!ss)Idsply(11,1); //+++++++ 1#号错误:烟度yi没准备好 ++++++++++++++++++++++++
else
{
OutToSBF(0,0xc0); //-----数据帧 复位命令--------
delayl(1); //0.7 mS延时
OutToSBF(1,ADDR); //-----地址帧 -------
OutToSBF(0,0x88); //-----数据帧 测量命令--------
delayl(16); //11s~12s
/*
//============测完判断===============//
t1=0;
sbuftemp=0;
while((!(sbuftemp&0x01))&&(t1<15)) //0.7+0.4s查询一次,共15次,>16s
{
OutToSBF(1,ADDR); //----------地址帧------------
OutToSBF(0,0xa0); //-----数据帧 返回状态码命令-----
REN=1; //准备接收 SCON=0xd0; 串行方式3,sm2=0,REN=1;
IE=0x90; //ES=1;
//EA=1;
sbuftemp=0;
ss=0;
t=0;
while((!ss)&&(t<32000)) //0.4s 接收状态码
{ t++; //
}
REN=0;
IE=0;
t1++;
delayl(1); //0.7s延时
}
//=======================================//
if(t1==15)Idsply(11,2); //++++++++++++++ 2#错误,YDY测量超时+++++++++++
else
{
REN=0;IE=0;
delayl(1); //让前面的数据超时失效,为后面的数据准备
*/
OutToSBF(1,ADDR); //----------地址帧------------
OutToSBF(0,0x90); //-----数据帧 返回数据命令-----
REN=1; //准备接收 SCON=0xd0; 串行方式3,sm2=0,REN=1;
IE=0x90; //ES=1;
//EA=1;
sbuftemp=0;
sbufferpt=0; //t=0;
t=0;
while((sbufferpt<3)&&(t<32000)) //while((i<3)&(t<200))
{ t++; //{ t++;
} //}
initS(); //串口复位
if(t==32000)Idsply(11,3); // 3#错误:串口接收测量结果超时0.4s
//...判断正确否
//
//
else
{
switch (TtHD)
{ case 3:initD();TtHD=1;Tt[1]=sbuffer[1];break;
case 2:Tt[++TtHD]=sbuffer[1];Md=Mdpr(Tt[1],Tt[2],Tt[3]);break; //+++++++++++++++++
case 1:Tt[++TtHD]=sbuffer[1];Md=(Tt[1]>Tt[2])?(Tt[1]-Tt[2]):Tt[2]-Tt[1];break;
case 0:Tt[++TtHD]=sbuffer[1];Md=0;break;
}
if(TtHD!=0)
{ if(Md>3)dd1=0;
else dd1=1;
judge1=1;
}
else judge1=0;
}
//}
}
dd2=0;
TstDspP(TtHD,Tt[TtHD],Md); //aa=TtHD; bb=Tt[TtHD];cc=Md;
initSB(); //串口缓冲区复位
}
void testA()
{ testM();dsplytemp();waitDspP();
testM();dsplytemp();waitDspP();
testM();
}
//-----------------------------------------------------------
void del()
{
switch(TtHD)
{ case 0:break;
case 1:initD();break;//Tt[TtHD--]=0;Md=0;break;//Tt[0]=0;
case 2:Tt[TtHD--]=0;Md=0;break;//Tt[0]=Tt[1];
case 3:Tt[TtHD--]=0;Md=(Tt[1]>Tt[2])?(Tt[1]-Tt[2]):(Tt[2]-Tt[1]);break;
}
if(TtHD!=0)
{ if(Md>3)dd1=0;
else dd1=1;
judge1=1;}
else judge1=0;
dsply2p(judge1,dd1,0);
TstDspP(TtHD,Tt[TtHD],Md);//aa=TtHD;bb=Tt[TtHD];cc=Md;
}
//---------------------------------------------------------
void avr()
{ uchar i;
i=TtHD;
Tt[0]=0;
while(i)
{ Tt[0]+=Tt[i--];
}
if(TtHD!=0)Tt[0]=Tt[0]/TtHD;
TstDspP(10,Tt[TtHD],Md);//aa=10;bb=Tt[TtHD];cc=Md;
dsply2p(0,0,0);
}
//---------------------------------------------------------
void sendlatch()
{ P11=0; ______
delay(900); | |
P11=1; | |
delay(900); _____| |
}
void senddata(uchar a1) // ++++++++++
{ bit s;
uint a; uchar i=16;
sendlatch();
//P11=0;
//P11=1;
a=a1*35; //类型转换
a=a/100;
a=a+a1*655;
while(i--)
{ if(a&0x8000) s=1;
else s=0;
P10=s;
delay(900); //等待数据有效
P12=0;
delay(900); //等待放电完成
P12=1;
a=a<<1;
delay(900);
}
sendlatch();
}
void send()
{ uchar i,daNO;
for(i=0;i<=3;i++)
{ daNO=i|0xfc;
OLE1=daNO; //选通所要发送的DA 1#:平均值 2~4#:测量值
delay(10000);
senddata(Tt[i]);
}
dsply2p(0,0,1); //led1灭
//led2亮
/*
for(i=0;i<30;i++)
{ delay(10000); //60*i mS延时
}
*/
}
//------------------------------------------------------------
void save() //****************
{
OLE1=0x7f;
delayl(3);
OLE1=0xff; //复位
initD();
initS();initSB();
dsply2p(0,0,0);
TstDspP(TtHD,Tt[TtHD],Md);
}
//---------------------------------------------------------
uchar Jkey()
{ uchar key,key1,key2;
uint t;
key1=CSKEY;
key1=key1&0x3f;
if(key1!=0x3f) //有键按下
{ //waitDspP();
delay(1500); //10mS左右去抖
waitDspP();
key1=CSKEY; //读稳定值
key1=key1&0x3f;
if(key1!=0x3f)
{ key2=key1; //保存
delay(500);
key1=CSKEY;
key1=key1&0x3f;
if(key1==key2) //按的同一键
{ key=key1;
t=0;
while(key1!=0x3f) //等松手
{ key1=CSKEY;
key1=key1&0x3f;
if(t<65535)t++;
}
if(t>30000)
{ if(key2==0x3e)key=0x11;
if(key2==0x3d)key=0x22;
if(key2==0x1f)key=0x66;
}
}
}
}
else key=0;
return(key);
}
//---------------------------------------------------------------
void accP()
{ bit r;
uint t;
SgBtOut(0xbf,0x01);
r=0; //
IE=0;
while(!r)
{ switch(Jkey())
{ case 0x3b: SgBtOut(0x0e,0x01);
t=0;
OLE1=0xff;//电源不接通24v 靠弹簧向前 //OLE1=0xdf; //电源接通24v 向前
while((P34==1)&&(t<34000)) //1.4s
{t++;}
if(t==34000)Idsply(11,4); //++++++++4#错误:活塞无法回起始点+++++++
SgBtOut(0x0e,0x01);
break;
case 0x37:SgBtOut(0x03,0x01);
t=0;
OLE1=0xbf;
OLE1=0x9f; //活塞向后拉
while((P33==1)&&(t<34000))
{t++;} //s
if(t==34000)Idsply(11,6); //6#错误:活塞向后拉杆超时,汽缸问题
SgBtOut(0x03,0x01);
break;
case 0x3d:OLE1=0xff;r=1;initD();break;
default:break;
}
}
}
//---------------------------------------------------------------
void accout(void) interrupt 2 using 2
{ TR2=0; //停定时器
F0=1; //测试结束标志
}
void timer2(void) interrupt 5 using 3
{ TF2=0;
accTime++;
}
void acctestM() //人工
{ uint t;
ulong accT; //总时间结果
accTime=0;
OLE1=0xff; //电源不接通24v 靠弹簧向前
delayl(1); // 向前0.7s左右
if(P34==1)Idsply(11,4); //4#错误:活塞无法回起始点
else
{ T2CON=0;
TH2=0;
TL2=0;
F0=0;
t=0;
OLE1=0xbf; //向后拉
OLE1=0x9f; //并接通24v
while((P34==0)&&(t<34000)) //等离开H2(T0) 加超时判断 1.4s
{t++;}
if(t==34000)Idsply(11,5); //++++++++++ 5#错误:活塞无法离开起始点++++++++++
else{
TR2=1; //开始计时
TCON=0x04; //INT1下降沿触发
IP=0x04; //INT1高优先,TIMER低优先
IE=0xa4; //TIMER2开溢出中断,开INT1中断,开cpu中断
while((!F0)&&(accTime<50)); //3.2s
IP=0;
IE=0;
if(!F0)Idsply(11,6); //6#错误:活塞向后拉杆超时,汽缸问题
else // ---------
{ //
accT=accTime*65536+TH2*256+TL2; // 数据处理
accT=accT/1000; //舍去us部分 //
for(t=0;t<=3;t++) //
{ dSegD[7-t]=seg[accT%10]; accT=accT/10; //
} //
dSegD[0]=0x88;dSegD[1]=0xc6;dSegD[2]=0xc6;dSegD[3]=0xff; //
// ----------
dsplytemp(); //4.2s显示拉杆时间
waitDspP();
OLE1=0xff; //向前拉
testM();
dsplytemp(); //4.2s显示烟度值
}
}
}
OLE1=0xff; //复位
TstDspP(TtHD,Tt[TtHD],Md);
dsply2p(0,0,0);
}
void acctestA() //自动
{
initD();
acctestM();acctestM();acctestM();
//avr();
}
//--------------------------------------------------------
main()
{
SgBtOut(0x00,0xff); //数码管检查
OLE1=0xff; //控制端初始化
initD(); //测量结果初始化
initS(); //串口初始化
initSB();
//OLE1=0xff; //控制端初始化
send(); //DA初始化送0
send();
TstDspP(0,0,0);
dsply2p(0,0,0);
while(1) //查询
{
switch(Jkey())
{ case 0x3e :testM();break; //1
case 0x3d :del();break; //2
case 0x3b :avr();break; //3
case 0x37 :send();break; //4
case 0x2f :save();break; //5***********
case 0x1f :acctestM();break; //6
case 0x66 :acctestA();break; //66
case 0x22 :accP();break; //22 加速调试
case 0x11 :testA();break; //11
default: break;
}
dsply();
dsply2();
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -