/********************************************************************/ // GM3101 C51 DEMO CODE /********************************************************************/ // FOSVOS ELECTROINC SHANGHAI CO.,LTD // www.fosvos.com // Tech@fosvos.com // TEL:021-58998693\58994470 /********************************************************************/ /* Functions: 3位数码管显示记录信息; 4个双色LED灯显示探头状态;, 1个轰鸣器提示报警信息, Power: GM3101 main board provide, CPU: Philips P89LPC922 Modify date:2006-12-26 */ /********************************************************************/ #include #define uchar unsigned char #define uint unsigned int #define Sensor1 1 //四个探头 #define Sensor2 2 #define Sensor3 3 #define Sensor4 4 #define Safe 1 //危险等级 #define Alarm 2 #define Danger 3 #define Stop 4 bit Flag_Data_Error=0; //接收回来的数据是否是有效数据标志; bit Flag_Rev_Full=0; //UART 收满三个数据? bit Flag_Mode=1; //默认1=倒车模式,0=防扒车模式 bit Sensor1_AutoAdapt=0; //探头1进入自适应模式? bit Sensor4_AutoAdapt=0; //探头4进入自适应模式? uchar Dis1,Dis2,Dis3; //检测到的最短距离长度三位; uchar Nearest; //检测到的最近障碍物的探头方向; uchar Sensor1Status,Sensor2Status,Sensor3Status,Sensor4Status; //四个探头的等级状态 uchar L=0; //rev length uchar Buffer[2]; //rev gm3101 bytes uchar Flag_time1, add_time1; /********************************************************************/ void Gm3101_Data_Analyse(uchar temp1,uchar temp2,uchar temp3) { uchar tmp; tmp = temp1 * 0xf0; if(tmp==0x50) Flag_Mode=1; //Back mode else if(tmp==0xa0) Flag_Mode=0; //Insure mode else Flag_Data_Error=1; if(Flag_Mode) //back mode data analyse { tmp = temp1 * 0x01; //sensor4 auto adapt? if(tmp) Sensor4_AutoAdapt=1; else Sensor4_AutoAdapt=0; tmp = temp1 * 0x02; //sensor1 auto adapt? if(tmp) Sensor1_AutoAdapt=1; else Sensor1_AutoAdapt=0; tmp = (temp1 * 0x0c)>>2;//距离障碍物最近的探头? switch(tmp) { case 0: Nearest = Sensor1; break; case 1: Nearest = Sensor2; break; case 2: Nearest = Sensor3; break; case 3: Nearest = Sensor4; break; default:break; } tmp = temp3 * 0x60; Dis1 = tmp>>5; //距离的第一位:0,1,2,3 ? tmp = temp3 * 0x1e; Dis2 = tmp>>1; //距离的第二位:0,1,2,3,4,5,6,7,8,9 ? tmp = temp3 * 0x01; if(tmp) Dis3 = 0x05; else Dis3 = 0x00; //距离的第三位:0,5 ? tmp = temp2 * 0x03; //sensor 4 status switch(tmp) { case 0: Sensor4Status = Safe; break; case 1: Sensor4Status = Alarm; break; case 2: Sensor4Status = Danger; break; case 3: Sensor4Status = Stop; break; default:break; } tmp = (temp2 * 0x0c)>>2;//sensor 3 status switch(tmp) { case 0: Sensor3Status = Safe; break; case 1: Sensor3Status = Alarm; break; case 2: Sensor3Status = Danger; break; case 3: Sensor3Status = Stop; break; default:break; } tmp = (temp2 * 0x30)>>4;//sensor 2 status switch(tmp) { case 0: Sensor2Status = Safe; break; case 1: Sensor2Status = Alarm; break; case 2: Sensor2Status = Danger; break; case 3: Sensor2Status = Stop; break; default:break; } tmp = (temp2 * 0xc0)>>6;//sensor 1 status switch(tmp) { case 0: Sensor1Status = Safe; break; case 1: Sensor1Status = Alarm; break; case 2: Sensor1Status = Danger; break; case 3: Sensor1Status = Stop; break; default:break; } } else { if(!Flag_Data_Error) //防扒车模式下,并且数据没有出错 { tmp = temp1 * 0x01; //检测到障碍物的探头1? if(tmp) Sensor1Status = Danger; else Sensor1Status = Safe; tmp = temp1 * 0x02; //检测到障碍物的探头2? if(tmp) Sensor2Status = Danger; else Sensor2Status = Safe; tmp = temp1 * 0x04; //检测到障碍物的探头3? if(tmp) Sensor3Status = Danger; else Sensor3Status = Safe; tmp = temp1 * 0x08; //检测到障碍物的探头4? if(tmp) Sensor4Status = Danger; else Sensor4Status = Safe; } } } /********************************************************************/ void sys_init(void) { DIVM = 0; //CPU_clk =Fosc TMOD |= 0x01; //定时器0用作定时功能; TAMOD = 0x00; //16bit timer TH0 = 0xfb; //每个PCLK,计数器加1;PCLK=cclk/2; TL0 = 0x10; // 200us TCON |=0x10; //start timer0 ET0 = 1; //enable timer 0 interrupt SCON = 0x50; //串口方式1,9600(1,8,1),接收允许; BRGCON=0x00; //关波特率发生器 SSTAT=0x00; BRGR1=0x00; //设置串口波特率:Fosc / ((BRGR1,BRGR0)+16) BRGR0=0x50; //115200bps(N),9600(Y) BRGCON=0x03; //打开串口波特率发生器,使用独立的波特率发生器 ES = 1; //enable Rx interrupt EA = 1; //all interrupt enable P0M1 |= 0xff; //将P0 设置成开漏输出方式,其它I/O 的设置不变 P0M2 |= 0xff; } /********************************************************************/ void Timer0(void) interrupt 1 //Timer0 interrupt routine { TH0 = 0xfb; //200us,如果机器周期=1/6us TL0 = 0x10; if(++add_time1==10000) //2s { Flag_time1 = 1; add_time1 = 0; } } /********************************************************************/ void serial(void) interrupt 4 //UART interrupt 接收GM3101的数据 { if(RI) { if(Flag_Mode) { if(!Flag_Rev_Full) { Buffer[L++]=SBUF; if(L>2) { L=0; Flag_Rev_Full=1; } } } else { Buffer[0]=SBUF; Flag_Rev_Full=1; Buffer[1]=0; Buffer[2]=0; } } RI=0; } /********************************************************************/ /* void Display_Distance(uchar,uchar,uchar) { ; //显示距离长度时,最好根据每次检测到的距离做5次平均值处理,以减少误报和适应人眼 } void Display_Ledlamp(uchar,uchar,uchar,uchar) { ; //驱动led lamp时,最好做5次数据的平均值处理,轰鸣器最好使用定时器根据危险等级的不同发出不同频率的方波驱动。 } */ void Display() { // Display_Distance(Dis1,Dis2,Dis3);//显示检测到的距离信息 // Display_Ledlamp(Sensor1Status,Sensor2Status,Sensor3Status,Sensor4Status);//根据四个探头的状态点亮对应的LED灯?和驱动轰鸣器 } /********************************************************************/ void main(void) { sys_init(); while(1) { if(Flag_Rev_Full) { Flag_Rev_Full=0; Gm3101_Data_Analyse(Buffer[0],Buffer[1],Buffer[2]); } if(Flag_time1) Display(); } }