// +FHDR=============================================================== // Copyright 2007,FOSVOS R&D CENTRE,All rights reserved. // www.fosvos.com //-------------------------------------------------------------------- // File Name : FOSVOS_Display.c // TYPE : function // Department : R&D // Author : Robin //-------------------------------------------------------------------- // Release History // Version Date Author Description // 3.0 18/1/2007 initial version //-------------------------------------------------------------------- // Purpose : FOSVOS_Diaplay.c //-FHDR================================================================ #include #include #define FREQ 11059200L #define OneInstTime (12/FREQ) #define InterTime 3L #define ConstData (InterTime*FREQ/12000) //====================================================== //蜂鸣器的响应频率,根据不同的危险等级响应不同的频率 //====================================================== #define BeepFreq1Hz 100 #define BeepFreq2Hz 50 #define BeepFreq4Hz 25 #define BeepFreq8Hz 12 //======================================================= //定义危险等级 //======================================================= #define LevelSafe 0 #define LevelAlarm 1 #define LevelDanger 2 #define LevelStop 3 //======================================================= //设置响应频率的BUF //======================================================== BYTE code TimeLen[4] = {BeepFreq1Hz, BeepFreq2Hz, BeepFreq4Hz, BeepFreq8Hz}; #define ON 1 #define OFF 0 #define SOUND 0 #define MUTE 1 #define SEG_ON 0 #define SEG_OFF 1 #define MAX_BUF_SIZE 16 #define BUF_MASK (MAX_BUF_SIZE - 1) #define Minus 0xBF // '-' #define CharP 0x8C // 'P' bool bReverse, bTimer, bBeepOn, bEmpty, bFull,bDataChange,bStartDispaly; bool bMUTE, bRefresh,bDataChangeFlag,bStopFlag,bStartFlag,bRcvFinish,bParkFlag,bLedStart,bLedFlag; //======================================================== //段位显示0~9 //======================================================== BYTE code DispSeg[10] = {0xC0, 0xF9, 0xA4, 0xB0, 0x99, 0x92, 0x82, 0xF8, 0x80, 0x90}; BYTE cDispBuf[3]; BYTE cpBuf[3]; BYTE cSaveDispBuf[2]; BYTE cSaveBuf[8]; BYTE cSubBuf[8]; BYTE cByteCntr,cBufPrt,cSumSub,cSubData,cNextData,cSaveCount; BYTE cBeepType, cBeepCntr, cDispDig,cStopCounter,cSegCounter; BYTE cStartCount,cMinusCount,cParkCount,cDisplay,cLastData; BYTE cpByteBuf[MAX_BUF_SIZE]; BYTE ReadBuf, WriteBuf,cSaveSecondData; BYTE cDisplayBuf[3],cDsiplayCount; BYTE cLedBuf[8],cLedCount,cLedCountSart; void RefreshDisp(void); //================================================================= //段码显示的控制端 //================================================================= sbit bDigi1 = P3^2; //com1 sbit bDigi2 = P3^3; //com2 sbit bDigi3 = P3^4; //com3 sbit bBeep = P3^1; //蜂鸣器的控制端 sbit bLeftLed = P3^5; //左边方向指示LED sbit bRightLed = P3^7; //右边方向指示LED //================================================================ //功能:系统初始化函数,初始化定时器,串口以及变量,中断优先级 //================================================================ void SystemInit(void) { EA = 0; TMOD &= 0x0F; TMOD |= 0x20; PCON |= 0x80; // 2 *SMOD *f TH1 = 0xF4; // Freq = 11.0592M Br=4800bps 256-x = ----------- (Df: 机器分频率,普通51为12,高速的有4(如80C320,7 TL1 = TH1; // 32*Br*Df TR1 = 1; SCON = 0x50; // Serial mode 1, REN = 1 PS = 1; ES = 1; //定时器0的初始化 TMOD &= 0xF0; TMOD |= 0x01; TL0 = (-ConstData) % 256; TH0 = (-ConstData) / 256; TR0 = 1; ET0 = 1; //允许定时器0中断 cByteCntr = 0; bReverse = true; cDispBuf[0] = 0xFF; cDispBuf[1] = 0xFF; cDispBuf[2] = 0xFF; cpBuf[0] = 0; cpBuf[1] = 0; cpBuf[2] = 0; cSaveSecondData=0; cStopCounter=0; cSegCounter=0; bBeep = MUTE; bMUTE = true; bFull = false; bRefresh = false; bEmpty = true; ReadBuf = 0; WriteBuf = 0; bStopFlag=false; bDataChangeFlag=false; bLedFlag=false; bLedStart=false; cLedCountSart=0; bDigi1 = SEG_OFF; bDigi2 = SEG_OFF; bDigi3 = SEG_OFF; cDsiplayCount=0; cBeepCntr=2; } //======================================================================= //功能:定时中断函数,定时时间为( ConstData) 5ms //======================================================================= void Core_SystemTimer0(void) interrupt 1 { TL0 = (-ConstData) % 256; TH0 = (-ConstData) / 256; RefreshDisp(); // bTimer = true; } //====================================================================== //串口接收中断函数 //====================================================================== void Uart_Receive(void) interrupt 4 { BYTE c; if(RI) { RI = 0; c = SBUF; if(!bFull) { cpByteBuf[WriteBuf] = c; WriteBuf++; WriteBuf &= BUF_MASK; if(WriteBuf == ReadBuf) { bFull = true; } bEmpty = false; } } TI = 0; } //====================================================================== //蜂鸣器控制函数 //====================================================================== void Beep(void) { if(!bMUTE) { cBeepCntr--; if(!cBeepCntr) { if(bBeepOn) { bBeep = MUTE; } else { bBeep = SOUND; } cBeepCntr = TimeLen[cBeepType]; bBeepOn = !bBeepOn; } } else { bBeep = MUTE; bBeepOn = false; } } //======================================================================== //显示刷新函数 //======================================================================== void RefreshDisp(void) { cDispDig++; if(3== cDispDig) { cDispDig = 0; } P1 = cDispBuf[cDispDig]; bDigi1 = SEG_OFF; bDigi2 = SEG_OFF; bDigi3 = SEG_OFF; switch(cDispDig) { case 0: bDigi1 = SEG_ON; break; case 1: bDigi2 =SEG_ON; break; case 2: bDigi3 =SEG_ON; break; default: break; } } //============================================================== //数据方向判断,判断数据来自哪个探头 //============================================================== void RightOrLeftLED(void) { BYTE c, cTemp,cTemp1; bRightLed =true; bLeftLed =true; cTemp=0; if(cLedCount==8) { cLedCount=0; } if(bLedStart||bLedFlag) { cLedCountSart++; bLedFlag=true; if(cLedCountSart>8) { cLedCountSart=0; bLedFlag=false; } } else { c=(cpBuf[0]&0x08); //判断数据来自的探头号 if(c==0) { cLedBuf[cLedCount] = 0; cLedCount++; } else { cLedBuf[cLedCount] = 1 ; cLedCount++; } for(cTemp1=0; cTemp1<8; cTemp1++) { cTemp= cTemp+cLedBuf[cTemp1]; } if(cTemp>3) { bLeftLed =false; } else { bRightLed =false; } } } //================================================= //功能:将BYTE C的BCD码转换为HEX码 前提将大于3米的数据丢弃 //================================================= BYTE BcdSwitchHex(BYTE c) { BYTE Temp ,Temp1; Temp =c&0x7E; Temp >>=1; Temp1 = 0x0F &Temp; //取出低位 Temp &=0x30; if(Temp==0x30) { c= Temp1 +30; } else if(Temp==0x20) { c= Temp1 +20; } else if(Temp==0x10) { c= Temp1 +10; } else { c= Temp1; } return c; } //========================================================================== //数据处理 //========================================================================== void DataSaveBuf(void) { BYTE Temp0,Temp1,Temp2,i=0 ,cDispalyData ,cData,Temp3; cSumSub=0; if(cSaveCount==8) { cSaveCount=0; } cSaveBuf[cSaveCount]=cpBuf[2]; cDispalyData =BcdSwitchHex(cLastData); cData=BcdSwitchHex(cpBuf[2]); cSaveCount++; Temp0=((cSaveCount-1)&0x07); Temp1=((cSaveCount-2)&0x07); Temp2=((cSaveCount-3)&0x07); Temp3=((cSaveCount-4)&0x07); if(bStartDispaly) //开始显示 { if(cpBuf[2]>=0xc0) //处理数据大于2米的情况 0xc0为2米 { bDataChange=false; if(cSaveBuf[Temp0]==cSaveBuf[Temp1]) //有两个数据相等才开始显示 { if(cSaveBuf[Temp0]==cSaveBuf[Temp2]) { bDataChange=true; bRefresh=true; } for(i=0;i<8;i++) { cSubBuf[i]=0; } } } else if(cData >cDispalyData+5) //处理数据突然变大的情况 { bDataChange=false; //数据突然变大不改变显示 if(cSaveBuf[Temp0]==cSaveBuf[Temp1]) { if(cSaveBuf[Temp1]==cSaveBuf[Temp2]) { if(cSaveBuf[Temp1]==cSaveBuf[Temp2]) { bDataChange=true; bRefresh=true; } } for(i=0;i<8;i++) { cSubBuf[i]=0; } } } else if(cData <= (cDispalyData-1)) //处理数据突然变小的情况 { bDataChange=true; bRefresh=true; } else //数据正常变大或者变小的情况 { cNextData =cData; bDataChange=false; if(cBufPrt == 8) { cBufPrt=0; } if(cNextData >=cDispalyData) { cSubData =cNextData-cDispalyData; } else { cSubData =cDispalyData-cNextData; } cSubBuf[cBufPrt] = cSubData; cBufPrt++; for(i==0;i<8;i++) { cSumSub = cSumSub+cSubBuf[i]; } if(cSumSub>7) //表示在均匀变化数据不需要处理 { bDataChange=true; bRefresh=true; } else { bDataChange=false; if(cSaveBuf[Temp0]==cSaveBuf[Temp1]) { if(cSaveBuf[Temp1]==cSaveBuf[Temp2]) { if(cSaveBuf[Temp2]==cSaveBuf[Temp3]) { bDataChange=true; bRefresh=true; } } } } } } else { if(cSaveBuf[Temp0]==cSaveBuf[Temp1]) //有两个数据相等才开始显示 { bStartDispaly=true; bDataChange=true; bRefresh=true; } else if(cSaveBuf[Temp0]==cSaveBuf[Temp2]) { bStartDispaly=true; bDataChange=true; bRefresh=true; } else if(cSaveBuf[Temp1]==cSaveBuf[Temp2]) { bStartDispaly=true; bDataChange=true; bRefresh=true; } } } //========================================================================== // 功能:从BUF中读取数据 //========================================================================== BYTE GetData(void) { BYTE c; c = cpByteBuf[ReadBuf]; ReadBuf++; ReadBuf &= BUF_MASK; if(WriteBuf == ReadBuf) { bEmpty = true; } bFull = false; return c; } //====================================================================== //fuctoin Display //====================================================================== void Display(void) { BYTE cTemp0,cTemp1,cTemp2; bLedStart=false; if(bDataChange) //改变显示数据标志 { cDisplay=cpBuf[2]; cLastData= cDisplay; //将显示的数据存入 cTemp0 = (cDisplay&0x60); //显示数据的高位 cTemp0 >>=5; cTemp1 = (cDisplay&0x1E); //显示数据的次高位 cTemp1 >>=1; cTemp2 = (cDisplay&0x01); //显示数据的低位 if(cTemp2) { cTemp2=5; //显示5 } else { cTemp2=0; //显示0 } } if(bParkFlag) //停车状态标志 { if(cDisplay>=0x86) //0x86为0.3米 0x8c 为0.6米 { if(cDsiplayCount==3) { cDsiplayCount=0; } cDisplayBuf[cDsiplayCount]=cDisplay; cDsiplayCount++; if(cDisplayBuf[0]=cDisplayBuf[1]) { if(cDisplayBuf[1]=cDisplayBuf[2]) { cParkCount++; } } } else if(cDisplay==0x84 ) //0x84为0.2米 { cParkCount=0; } if(cParkCount==16) //进入停车状态后退出延时320 ms { bParkFlag=false; cParkCount=0; } } else { if((cDisplay>=0xFE)||cTemp1>9) { cMinusCount++; //滤掉错误的0xFF 或者0xFE bLedStart=true; if(cMinusCount>5) { cDispBuf[0] =Minus; cDispBuf[1] =Minus; cDispBuf[2] =Minus; cMinusCount=0; cBeepType=LevelSafe; bMUTE = true; } } else if(cDisplay >0x85) { cDispBuf[0] =DispSeg[cTemp0]; cDispBuf[0]&=0x7F; //点亮小数点 cDispBuf[1] =DispSeg[cTemp1]; cDispBuf[2] =DispSeg[cTemp2]; cMinusCount=0; bMUTE = false; if(cDisplay >0x8c) { cBeepType=LevelAlarm; } else { cBeepType=LevelDanger; } } else { bParkFlag=true; //停车标志置位 cMinusCount=0; cDsiplayCount=0; } } if(bParkFlag) { cDispBuf[0] =Minus; cDispBuf[1] =CharP; cDispBuf[2] =Minus; cBeepType=LevelStop; bMUTE = false; } } //=========================================================================== //功能:主函数 //========================================================================== void main(void) { BYTE c; SystemInit(); EA = 1; for(;;) { if(!bEmpty) { c = GetData(); cpBuf[cByteCntr] = c; bMUTE = true; bRcvFinish = false; //每次进入前将接收完标志清0; if(!cByteCntr) //数据开始位判断 { bReverse = false; //清标志位 if(0x50 == (c & 0xF0)) { bReverse = true; //为倒车模式将标志位置1 cByteCntr++; } } else if(bStartFlag) //开始接收数据标志位 { if(bReverse) { cByteCntr++; if(3 == cByteCntr) { cByteCntr = 0; bRcvFinish = true; //开始标志置位后每接收完成一次数据接收标志置1 } } } else { //滤掉错误数据并产生开始标志bStartFlag=true if(bReverse) { cByteCntr++; if(3 == cByteCntr) { cByteCntr = 0; cStartCount++; if(cStartCount>10) //滤掉开始时错误的数据。 { bStartFlag= true; } } } } RightOrLeftLED(); //判断数据来自探头号 if(bRcvFinish) //每次产生接收完标志后对数据进行处理 { bRefresh=false; DataSaveBuf(); //数据存储和处理函数 处理数据决定是否刷新显示 } if(bRefresh) //数据刷新标志 { Display(); //改变显示 Beep(); //处理蜂鸣器声音 RefreshDisp(); //刷新显示 } } } } //////////////////////////////////////////////////////////////////////////////// /********************************************************************/ // FOSVOS ELECTROINC SHANGHAI CO.,LTD // www.fosvos.com // Tech@fosvos.com // TEL:021-58998693\58994470 /********************************************************************/