?? 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 //計數(shù)初值
#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}; //數(shù)碼管
// 0 1 2 3 4 5 6 7 8 9 //"A.""E." "C" " " " ." "-" "F.""b."
uchar aa,bb,cc; //測試時數(shù)碼管顯示暫存
uchar dSegD[8]=0xff; //顯示段碼內(nèi)容存放
uchar Tt[4]; //測量結(jié)果 Tt[0]:均值
uchar TtHD; //結(jié)果指針 0:無測量 1~3:結(jié)果
uchar Md; //最大差值
uchar sbuffer[4]; //串口緩沖區(qū)
uchar sbufferpt; //緩沖區(qū)指針
uchar sbuftemp;
uchar accTime; //加速測試定時器計數(shù)
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) //求三數(shù)最大差值
{ 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() //數(shù)據(jù)初始化
{ 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; //串口緩沖區(qū)
sbufferpt=0;
sbuftemp=0;
ss=0; //串口接收標志
}
//---------------------------------------------------------------
void SgBtOut(uchar s,b)
{ CSSEG=s;
CSBIT=b;
}
void TstDspP(uchar a,b,c) //測試時數(shù)碼管顯示準備
{ 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; //加小數(shù)點
temp=bb%10;
dSegD[3]=seg[temp];
dSegD[4]=0xff;
dSegD[5]=0xff;
temp=cc/10;
dSegD[6]=seg[temp]&0x7f; //加小數(shù)點
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顯示當(dāng)前煙度值
{ uint t;
t=0x0800;
while(t--)
{dsply();
}
}
void waitDspP() //等待狀態(tài)顯示:兩點
{ 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; //關(guān)回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; //關(guān)中斷
REN=0;
if(!ss)Idsply(11,1); //+++++++ 1#號錯誤:煙度yi沒準備好 ++++++++++++++++++++++++
else
{
OutToSBF(0,0xc0); //-----數(shù)據(jù)幀 復(fù)位命令--------
delayl(1); //0.7 mS延時
OutToSBF(1,ADDR); //-----地址幀 -------
OutToSBF(0,0x88); //-----數(shù)據(jù)幀 測量命令--------
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); //-----數(shù)據(jù)幀 返回狀態(tài)碼命令-----
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ài)碼
{ 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); //讓前面的數(shù)據(jù)超時失效,為后面的數(shù)據(jù)準備
*/
OutToSBF(1,ADDR); //----------地址幀------------
OutToSBF(0,0x90); //-----數(shù)據(jù)幀 返回數(shù)據(jù)命令-----
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(); //串口復(fù)位
if(t==32000)Idsply(11,3); // 3#錯誤:串口接收測量結(jié)果超時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(); //串口緩沖區(qū)復(fù)位
}
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; //類型轉(zhuǎn)換
a=a/100;
a=a+a1*655;
while(i--)
{ if(a&0x8000) s=1;
else s=0;
P10=s;
delay(900); //等待數(shù)據(jù)有效
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; //選通所要發(fā)送的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; //復(fù)位
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; //讀穩(wěn)定值
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; //測試結(jié)束標志
}
void timer2(void) interrupt 5 using 3
{ TF2=0;
accTime++;
}
void acctestM() //人工
{ uint t;
ulong accT; //總時間結(jié)果
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下降沿觸發(fā)
IP=0x04; //INT1高優(yōu)先,TIMER低優(yōu)先
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; // 數(shù)據(jù)處理
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; //復(fù)位
TstDspP(TtHD,Tt[TtHD],Md);
dsply2p(0,0,0);
}
void acctestA() //自動
{
initD();
acctestM();acctestM();acctestM();
//avr();
}
//--------------------------------------------------------
main()
{
SgBtOut(0x00,0xff); //數(shù)碼管檢查
OLE1=0xff; //控制端初始化
initD(); //測量結(jié)果初始化
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 加速調(diào)試
case 0x11 :testA();break; //11
default: break;
}
dsply();
dsply2();
}
}
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -