原创 智能救援车

2010-10-9 23:42 1604 4 4 分类: MCU/ 嵌入式

#include"reg52.h"
#include<intrins.h>     //调用汇编指令   
#include<stdio.h>      
#include<math.h>       
#define uchar unsigned char
#define  uint unsigned int
//电机转向定义
#define  forward  0x5f   //前进
#define  back     0x0f   //后退 
#define  right    0x4f   //右转
#define  left     0x1f   //左转
#define  stop     0xff   //停止
#define  bleft    0x9f   //后左转
#define  bright   0x6f   //后右转 
#define  fright   0x7f   //左轮单独前进 右轮停止
#define  fleft    0xdf   //右轮单独前进 左轮停止
//转向灯定义
#define forwardd  0x3f   //前两个灯亮
#define backd     0xcf   //后两个灯亮
#define rightd    0xaf   //右两个灯亮
#define leftd     0x5f   //左两个灯亮
#define  yes      1      //液晶延时选择
#define  no       0      //液晶延时选择 
#define LCD_Data P0      //液晶数据口
#define Busy     0x80    //用于检测LCD状态字中的Busy标识 当RS=0;RW=1;E=0来判断D7为1
#define ad0832_delay();  { _nop_();_nop_();};  //AD0832用到的时间定义3us
//传感器所用到的I/O口
sbit          c=P1^2;    //转向灯使能端控制位
sbit     LCD_RS=P1^5;    //液晶定义引脚
sbit     LCD_RW=P1^6;    //液晶定义引脚
sbit      LCD_E=P1^7;    //液晶定义引脚
sbit       play=P2^0;    //语音模块启动位(低电平触发)
sbit      add_0=P2^1;    //语音地址高位
sbit      add_1=P2^2;    //语音地址低位
sbit       jdq1=P3^0;    //捡起金属继电器控制位2
sbit        jdq=P3^1;    //捡起金属继电器控制位1
sbit    baojing=P3^3;    //蜂鸣报警控制位
sbit     cs_245=P3^4;    //避障和循迹信号输入控制位
sbit wendu_data=P3^5;    //DS18B20的通信端口
sbit     qidong=P3^6;    //无线遥控启动小车位
sbit      ad_cs=P2^3;    //tlc1549使能线
sbit    ad_date=P1^4;    //tlc1549数据输出线
sbit     ad_clk=P1^3;    //tlc1549时钟信号线
sbit  ad0832_cs=P1^0;    //AD0832片选使能端
sbit ad0832_clk=P1^1;    //AD0832时钟信号线
sbit ad0832_d0=P1^2;    //AD0832的数据输出线
//系统用到的标志位
bit        bj_flag=0;    //定时5秒时间标志位
bit        ts_flag=0;    //避障与循迹的速度切换位
bit     xunji_flag=0;    //报警2秒控制位
bit     count_flag=0;    //循迹线速度调节位
bit         jianqi=0;    //继电器保持控制位
bit     dingshi_3s=0;    //捡起金属,停3秒控制位
bit          jdqbc=0;    //捡起金属继电器保持位
//固定代码   
uchar  code BD[]={"BD"};   
uchar  code DC[]={"DC"};
uchar  code miao[]={"s"};
uchar  code shijianshwo[]={" TIME "}; //液晶显示字符
uchar  code fenmiao[]={":"};   
uchar  code kongge[]={"       "};
uchar  code wendu[]={"wendu"};
uchar  code mi[]={"m"};
uchar  code jiao[]={"jiao"};
uchar  code lcd[]={0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x38,0x39}; //显示
uchar  data  temp[]={0x00,0x00,0x00};       //中间变量存储单元
uchar date1=0,second=0,minute1=0,minute2=0; //时间显示有到的变量
uchar wei_flag=0,wei_flag2=0,wei_flag3=0,wei_flag4=0,wei_flag5=0,wei_flag6=0; //前方障碍个数变量
uchar ting;                                 //停车5秒用定时器1对应的计数变量
uchar a=0,b=0;                              //DS18B20用到的变量
uint number=0,number1=0;                   //中断测距离用到的变量
/****************/
//函数群
void CD_display();
void DisplayListChar(uchar X, uchar Y,uchar ListLength, uchar  *DData,uchar n);
void Djs();         //停车5秒显示
void display();     //液晶显示函数
void ad_1602xianshi();
void zhouchang();   //避障和循迹切换函数
void lcddisplay2(uchar *lcd1,uchar *lcd2,uchar *lcd3,uchar *lcd4);//液晶专用函数
void jinshu();      //金属探测函数
void tz();          //避障和循迹的速度的函数
void xunji() ;      //循迹子函数
void xunjiks();     //循迹开始和BD时间控制位
void zhuanquan();   //寻找黑线函数
void BD_display();  //BD段时间显示
void wendu_show();  //温度显示函数
void  juli_show();  //距离显示函数
void jiaodu_show(); //坡度度数的显示函数
void dianchidaya(); //电压电量显示函数


/****************/
//延时程序
void delay(uint i)     
{ while(i--);
 }
//延时程序
void Delay5Ms(void)
{uint Temp = 5552;
 while(Temp--);
}
//转向灯控制函数
void deng(uchar DENG)
{  cs_245=1;
   c=1;
   P0=DENG;
   c=0;
}
/**********************/
/*速度调节控制部分
/*********************/
void run_forward()        //向前运动
{ if(ts_flag==1)          //循迹用的速度
    { P2=forward;    
      delay(600);         
         P2=0xff;   
     delay(1500);
   }
else { P2=forward;        //避障用的速度
      delay(5000);       
        cs_245=1;
       display();}        //液晶显示时间函数
           c=0; 
 }
void run_back()           //向后运动
{      P2=back; 
   delay(1000);          
       P2=0xff;
      cs_245=1; 
     display();           //液晶显示函数
           c=0;
   }
void run_left()           //向前左转
{      P2=left; 
   delay(2500);       
       P2=0xff; 
      cs_245=1;    
           c=0;
}
void run_right()         //向前右转
{  P2=right; 
  if(ts_flag==1)         //寻找黑线用到的速度
  { delay(400);   
       P2=0xff;
   delay(1500);   
   }
  else{delay(2000);     //转向调速      
       P2=0xff; 
      cs_245=1;   
           c=0;
    }
}
void bl()               //小车后左转
{    P2=bleft; 
   if(ts_flag==1)
   {delay(600);
       P2=0xff;
  delay(1500);
    } 
else if(count_flag==1)
   {delay(400);
    P2=0xff;
   cs_245=0;
    delay(800);
   }
else{delay(2000);
    P2=0xff;
   cs_245=1; 
        c=0;
      }
}
void br()                //小车后右转
{   P2=bright;
  if(ts_flag==1)
  { delay(400);
       P2=0xff;
   delay(1500);
   }
else if(count_flag==1)
  { delay(300);   
    P2=0xff;
   cs_245=0;
    delay(800);
  }
 else{delay(2000);
       P2=0xff;
      cs_245=1;   
        c=0;
   }
}
void fl()               //右轮向前,左轮停驶函数
{  P2=fleft;
 if(count_flag==1)
   {delay(400);
    P2=0xff;
   cs_245=0;
   delay(2000);
   }
else{delay(600);
       P2=0xff;
   delay(1000);
   }
}
void fr()               //左边前进,右轮停驶函数
{    P2=fright;
 if(count_flag==1)
 {  delay(400);
    P2=0xff;
   cs_245=0;
   delay(2000);
}
else{delay(600);
       P2=0xff;
   delay(1000);
 }
}
void run_stop()         //停车函数
{      P2=0xff;
   delay(2500);
      cs_245=1;   
}
/*********************************/
/*循迹函数
/*74HC245上的: B6-左循迹光电开关 B7 -右循迹光电开关
/*黑为高,白为低
/*原理是哪一个探头检到白线,就向相反的方向转
/********************************/
void xunji()              //正向运动程序
{  uchar temp=0;        
         ting=0;
 while(1)
 {     cs_245=0; 
   temp=P0&0xc0;          //74HC245检测黑线信号 
    switch(temp)
        { case 0xc0:{ run_forward(); deng(forwardd);cs_245=0;TR0=1; } break;
          case 0x80:{fl();deng(rightd); cs_245=0;TR0=1; } break; //左轮前进
          case 0x40:{fr();deng(leftd);cs_245=0; TR0=1; } break; //右轮前进
          case 0x00:{ run_stop();jdqbc=0;TR0=0;if(date1>=50)baojing=0;cs_245=0;} break;       
          default :break;
        }     
       jinshu();          //金属探测函数
 
 if(jianqi==1)            //停车3s,继电器捡起
   { jdqbc=1;  
  run_forward();           
       jdq=0; 
      jdq1=0;
       TR1=1;           
  run_stop();
   BD_display();          //BD段时间显示
   ting=0;          //重新计数
    TR1=1;        
     add_0=0;          //语音地址高
     add_1=1;          //语音地址低
   play=0;          //语音播放D段
while(dingshi_3s);        //等待3秒时间
    TR1=0;          //关闭 
   dingshi_3s=0;        
        date1=0;
       second=0;          //为了从D点开始计数    
        }         
else{ jdq=0;jdq1=0;}      //一直开着       
       jianqi=0;          //关着里,只执行一次/标志位清零
 if(jdqbc==1)          //继电器保持位
 { jdq=0;jdq1=0;
  } 
  if(second>0)            
 {if(temp==0x00)          
  {   jdq=1;
     jdq1=1;
  baojing=0;
   delay(5000);
     baojing=1;     
  delay(65000);
    run_stop();
  CD_display();           //CD段显示时间 可以了
  BD_display();           //BD段显示时间
    add_0=1;           //语音地址高位 
    add_1=1;           //语音地址低位   
     play=0;           //语音播放c段
      juli_show();        //显示小车行驶总路程
       }
   }
        temp=0;           //信号变量清零
      }
   }
/*****************************/
/*金属探测函数部分
/*74HC245上的:B1-金属探测传感器
/****************************/
void jinshu()
{uchar temp_jishu;
temp_jishu=P0&0x01;      //74HC245检测金属
  if( temp_jishu==0)     //判断金属有无
    {  jdq=0 ;       //捡起金属
    jdq1=0;           //捡起金属
    baojing=0;           //蜂鸣器报警
  delay(2000);           //报警时间    
   P0=0xff;           //灯光提示 
   delay(500);
 baojing=1;           //报警关闭
  jianqi=1;           //继电器一直吸着金属
               
   }
}
void BD_display()                 //显示BD所用时间
{ temp[1]=lcd[ting/20];           //个位
  temp[0]=lcd[ting/200];          //十位
  date1=0;second=0;               //为了从D点开始计数 
  DisplayListChar(9,0,2,BD,no);   //显示BD
  DisplayListChar(9,1,2,temp,no); //显示BD时间 
  DisplayListChar(11,1,1,miao,no);//显示s字符    
}
void CD_display()                //显示CD段时间
{uchar CD1[1],CD2[1];
  temp[2]=lcd[date1];
  temp[3]=lcd[second];
      CD1[0]=temp[2];
      CD2[0]=temp[3];
  DisplayListChar(0,0,6,kongge,no);  //清除其他显示字符
  DisplayListChar(0,1,7,kongge,no); 
  DisplayListChar(13,0,2,DC,no);  //显示CD
  DisplayListChar(14,1,1,CD1,no);  //显示CD时间个位
  DisplayListChar(13,1,1,CD2,no);  //十位
 DisplayListChar(15,1,1,miao,no);  //显示s字符
  }  
 /**************************************************/
 /*寻找循迹线函数
 /*原理是左右摇摆寻找循迹线:
           左循迹光电开关找到黑线右转 
           右循迹光电开关找到黑线左转
 /*74HC245上的: B6-左循迹光电开关 B7 -右循迹光电开关
 /*黑为高,白为低
 /*************************************************/
void zhuanquan()
 { uchar zhuan_temp=0x00;
   uchar c9=0;  
while(1)
 {    count_flag=1;
       cs_245=0;
 if(zhuan_temp!=0x00)               //对寻找黑线的信号判断
    { switch (P0&0xc0)
  { case 0x40:xunji();break;     //找到后跳到循迹函数
    case 0x80:xunji();break;     //找到后跳到循迹函数
    case 0xc0:xunji();break;     //找到后跳到循迹函数
    default :break;
   }
 }
 else {for(c9=0;c9<=2;c9++)         //左寻找循迹线
    {     fl();
     delay(300);
     deng(leftd);       
  }                        
   
   }   
  }
}
//停车5秒和报警函数
void tz()
{ while(1)
  {
    run_stop();        //停车。
    delay(6000);
      TR0=0;      //定时器0关闭
      TR1=1;      //定时器1开启
       add_0=1;      //语音地址高位
    add_1=0;      //语音地址低位
     play=0;      //语音播放 
while(bj_flag)      //5秒定时开始         
 {       TR1=1;      //定时器1开启   
        c=1;
    P0=0xff;      //灯光提示
    delay(500);
       P0=0x0f; 
while(xunji_flag)    //蜂鸣报警时
   {     TR1=0;      //关闭定时器1
  xunji_flag=1;       
     baojing=1;      //关闭蜂鸣报警
    P0=0x0f;      //关闭提示灯
    add_0=0;      //语音地址高位 
    add_1=1;      //语音地址低位  
  play=0;      //语音播放B段
   zhuanquan();      //开始找循迹线       
 }
   }
  }
}
/************************/
/*74HC245上的数据端:
/* B5-前避障光电开关
/* B3-右避障光电开关
/* B4-左避障光电开关
/* B2-E门检测光电开关
/*有障碍为0 ,无障碍位 1
/************************/
//避障函数
void bizhang()      
{ uchar temp2=0,temp3=0;    
  uchar c1=0,c2=0,c3=0,c4=0,c5=0,c6=0,c7=0,c8=0,c10=0;  //变量  
             cs_245=0;
 temp2=P0&0x38;//采集左,右,前边变量
  switch(temp2)
      { case 0x38:{ run_forward(); deng(forwardd);cs_245=0;} break;//无障碍前进,前灯亮
        case 0x28:{ run_right();  deng(rightd);   cs_245=0;} break;//左边有障碍,右转,右边灯亮
        case 0x30:{ run_left();   deng(leftd);    cs_245=0;} break;//右边有障碍,左转,左边灯亮
        case 0x18:{ deng(backd);cs_245=0;wei_flag++;wei_flag6++;}break;//前边有障碍,标志位wei_flag自加(K値)
        case 0x10:{ run_left();  deng(leftd);     cs_245=0;} break;  //右边和前方有障碍,左转,左边灯亮
        case 0x08:{ run_right(); deng(rightd);    cs_245=0;} break;  //左边和前方有障碍,右转,右边灯亮
  case 0x00:{ run_back();  deng(backd);     cs_245=0;} break;  //有死角,后退,后灯亮
  case 0x20:{ run_back();  deng(backd);     cs_245=0;} break;  //有死角,后退,后灯亮
        default :break;
  }
//前避障光电开关扫描到到第一个,第二个前方障碍,对应的转向控制
  if(wei_flag4==0)    
   {               
    { for(c1=0;c1<=6;c1++)         
    {run_right();                //右轮向后转,左轮想前转,右边灯亮
     delay(2000);
    deng(rightd);
        cs_245=0; 
   }
      wei_flag=0;                //前方标志位清零
     wei_flag2++;
     
    }
//前避障光电开关扫描到第三,四个前方障碍,对应的转向控制
  if(wei_flag2>=2)
  { for(c2=0;c2<=7;c2++)       
     {    run_left();             //左轮想后转,右轮向前转,左边灯亮
      delay(2000);
      deng(leftd);
         cs_245=0;
    }
       wei_flag=0;
      wei_flag2++;
      
   if(wei_flag2>=4)
     {   wei_flag2=0;
      wei_flag3=1;
        }
 }    
//E门检测光电开关扫描到的E门,对应的控制
 if(wei_flag3==1)
    {  temp3=P0&0x02;           //采集E门光电开关信号
 if(temp3==1)      
     {   run_forward();            
     delay(6550);
         delay(6550);                          
     delay(6000);     
 for(c3=0;c3<=10;c3++)                      
     {      run_right();          //右轮向后转,左轮想前转,右边灯亮
     delay(2000);
    deng(rightd);
     cs_245=0;
     }      
     wei_flag3=0;
     wei_flag4=1; 
      wei_flag=0;
     }
 }
//前避障光电开关扫描到到第五个前方障碍,对应的控制 
 if(wei_flag4==1)
  { if(wei_flag==1)
  for(c6=0;c6<=11;c6++)   
    {         bl();
    delay(2000);
    deng(leftd);     
   }
 }
//前避障光电开关扫描到到第六个前方障碍,对应的控制
 if(wei_flag5==1)
  {if(wei_flag==1)
 for(c4=0;c4<=32;c4++) 
        {    br();
   delay(2000);
  deng(rightd);
      cs_245=0;
      }
   }   
//当到达B门时,对应的控制
  if(wei_flag5==1)
  { for(c6=0;c6<=1;c6++) 
    {        br();         //转轮右转,右轮不动
      delay(2000);
     deng(rightd);     
     }
  for(c7=0;c7<=5;c7++)         
   { run_forward();
  delay(2000);
     deng(forward);      
       }
  for(c10=0;c10<=3;c10++)          
   {  run_right();
      delay(2000);
      deng(rightd);       
    }
   }
 //当无障碍时停车 
   if(temp3==1)            
   { delay(3000);
    if(temp3==1)
           tz();        //停车5秒和报警函数开始进入寻找循迹线         
       }
  }
}
//5秒计数定时函数
void time() interrupt 3 using 3
 {  TH1=(65536-50000)/256;
    TL1=(65536-50000)%256;
     ting++;          
    if(ting==100)bj_flag=1;      //计数时间到产生的标准位
 if(ting>=160)xunji_flag=1;   //循迹标志位
 if(jianqi==1)
   { if(ting==60)
       dingshi_3s=1;
     else
          dingshi_3s=0;
       } 
 }
/*********************************/
//液晶1602的驱动子函数
//读状态
unsigned char ReadLCD(void)
{LCD_Data=0xFF;
 LCD_RS=0;
 LCD_RW=1;
 LCD_E= 0;
 LCD_E= 0;
 LCD_E= 1;
 while (LCD_Data&Busy);                         //检测忙时信号
 return(LCD_Data);
}
//写数据
void WriteDataLCD(unsigned char WDLCD)
{ ReadLCD();                                   //检测液晶处理器是否忙?
 LCD_Data=WDLCD;
 LCD_RS=1;
 LCD_RW=0;
 LCD_E=0;        
 LCD_E=0;      
 LCD_E=0;      
 LCD_E=1;
}
//写指令
void WriteCommandLCD(unsigned char WCLCD,BuysC)
{if (BuysC)ReadLCD();                          //根据需要检测忙
 LCD_Data=WCLCD;
 LCD_RS=0;
 LCD_RW=0;
 LCD_E=0;
 LCD_E=0;
 LCD_E=0; //延时
 LCD_E=1;
}
//LCD初始化
void LCDInit(void)       
{delay(10000);
 LCD_Data  = 0;
 WriteCommandLCD(0x38,0);                  //三次显示模式设置,不检测忙信号
 Delay5Ms();
 WriteCommandLCD(0x38,0);
 Delay5Ms();
 WriteCommandLCD(0x38,0);
 Delay5Ms();
 WriteCommandLCD(0x38,1);                  //显示模式设置,开始要求每次检测忙信号
 WriteCommandLCD(0x08,1);                  //关闭显示
 WriteCommandLCD(0x01,1);                  //显示清屏
 WriteCommandLCD(0x06,1);                  //显示光标移动设置
 WriteCommandLCD(0x0c,1);                  //显示开及光标设置
}
//按指定位置显示一个字符
void DisplayOneChar(uchar X, uchar Y, uchar DData)
{
 Y&=0x1;
 X&=0xF;                  //限制X不能大于15,Y不能大于1
 if(Y)
 X|= 0x40;                //当要显示第二行时地址码+0x40;
 X|= 0x80;                //算出也液晶对应的指令码
 WriteCommandLCD(X, 0);   //这里不检测忙信号,发送地址码
 WriteDataLCD(DData);
}
//按指定位置显示一串字符
void DisplayListChar(uchar X, uchar Y,uchar ListLength, uchar  *DData,uchar n)
{ uchar i;
 Y&=0x01;
 X&=0x0F;                 //限制X不能大于15,Y不能大于1
 for(i=0;i<ListLength;i++)
 {if (X <= 0x0F)          //X坐标应小于0xF
  { DisplayOneChar(X, Y, DData); //显示单个字符
 if(n==yes)
 delay(60000);
   X++;
   }
  }
 }
//定时器的产生的时间
void time50ms() interrupt 1 using 3     //定时器T0的中断子程序
  { uchar date;
    TH0=(65536-45000)/256;
    TL0=(65536-45000)%256;
     date=date++;
    if(date==20){date=0;date1++;}       //秒一
    if(date1==11){ date1=0; second++;}  //秒二
    if(second==6){second=0;minute1++;}  //分钟1
    if(minute1==9){minute1=0;minute2++;}
    if(minute2==6){minute2=0;}          //分钟2
    }
//液晶1602的时间显示程序段
 void lcddisplay2(uchar *lcd1,uchar *lcd2,uchar *lcd3,uchar *lcd4)
 {  LCDInit();                         //LCD初始化
    P1|=0X04;         
    P1&=0XFB;         
  WriteCommandLCD(0x01,1);             //显示清屏
  DisplayListChar(1,0,5,shijianshwo,no);             
  DisplayListChar(2,1,1,lcd4,no);
  DisplayListChar(3,1,1,lcd3,no);      //用于5是用于跳过其他的字符f1
  DisplayListChar(4,1,1,fenmiao,no);
  DisplayListChar(5,1,1,lcd2,no);      //用于5是用于跳过其他的字符
  DisplayListChar(6,1,1,lcd1,no);      //第三个数值是后面数组的个数第二个数为行数的选择第一个为列的选则
    P1&=0XFB;
 }
/********************************/
/*利用DS18B20测温度
/*******************************/
//初始化函数1
uchar Init_DS18B20(void)
{    uchar x=0;
     wendu_data=1;                    //wendu_data复位
     delay(8);                        //稍做延时
     wendu_data=0;                    //单片机将DQ拉低
     delay(80);                       //精确延时大于480us
     wendu_data=1;                    //拉高总线
     delay(14);                       //稍作延时
     x=wendu_data;                    //稍做延时后 如果x=0则初始化成功 x=1则初始化失败
if(x)Init_DS18B20();                  //用于数据的传输判断
      delay(20);
}
//读一个字节
uchar ReadOneChar(void)
{  uchar i=0,dat=0;  
    for(i=8;i>0;i--)
    { wendu_data=0;                   //拉低,这时的读取有效给脉冲信号
      dat>>=1;
      wendu_data=1;                   //给脉冲信号
    if(wendu_data)
      dat|=0x80;
      delay(4);
      }
     return(dat);
}
//写一个字节
void WriteOneChar(unsigned char dat)
{unsigned char i=0;
 for(i=8;i>0;i--)
   { wendu_data=0;
     wendu_data=dat&0x01;
     delay(5);
     wendu_data=1;
     dat>>=1;
     }
     delay(4);                         //用于数据的传输时间延时
}
//读取温度
uchar ReadTemperature(void)
{uchar t=0;
 Init_DS18B20();                       //初始
 WriteOneChar(0xCC);                   //跳过读序号列号的操作
 WriteOneChar(0x44);                   //启动温度转换
 Init_DS18B20();                       //初始
 WriteOneChar(0xCC);                   //跳过读序号列号的操作
 WriteOneChar(0xBE);                   //读取温度寄存器等(共可读9个寄存器) 前两个就是温度
   a=ReadOneChar();                    //读取温度值低位  
   b=ReadOneChar();                    //读取温度值高位       
   a=a>>4;                             //低位右移4位,舍弃小数部分
   b=b<<4;                             //高位左移5位,舍弃符号位
   t=a|b;    
   return(t);                          //返回角度的値
}
/*************************/
/*倾角传感器经过AD1549转换为
  数字量,经过处理得到角度
/*AD1549的转化函数
/*************************/
uint ad_1549(void )
 { uchar time;
   uint datead=0;
    ad_cs=1;
    delay(1);
    ad_clk=0;
    ad_cs=0; 
for(time=0;time<10;time++)
   {  ad_clk=1;                          //下降沿有效
      datead=datead|ad_date;
      ad_clk=0;      
      datead<<=1;
     }
      ad_cs=1;
   return(datead);
}    
/***************************/
/*    电池电压的检测       */
/*ADC0832用了其中的一个通道*/
/**************************/
void ad_set()
 { ad0832_cs=0;                           //片选使能端
   ad0832_clk=1;
   ad0832_delay();
   ad0832_d0=1;                           //启动ADC0832
   ad0832_delay();
   ad0832_clk=0;                          //第一个下降沿
   ad0832_delay();
   ad0832_clk=1;
   ad0832_delay();
   ad0832_d0=1
   ad0832_delay();
   ad0832_clk=0;                          //第2个下降沿
   ad0832_delay();
   ad0832_clk=1;
   ad0832_delay();
   ad0832_d0=0;  
   ad0832_delay();
   ad0832_clk=0;                          //第3个下降沿,最后选单通道0
 }
uchar ad0832_read()
{ uchar i,ad_data;  
 for(i=0;i<8;i++)
  {   ad0832_clk=1;
   ad0832_delay();
   ad_data<<=1;
   ad_data|=ad0832_d0;
   ad0832_clk=0;
   ad0832_delay();
   }
    return(ad_data);
}
/******************/
/*电池电压显示函数*/
void dianchidaya()
{ uchar ad0832_temp,ad0832_shi[1]=0,ad0832_ge[1]=0;
   ad0832_temp=ad0832_read();                          //读取电压
   ad0832_temp=ad0832_temp*100/51;                     //电压的计算
   ad0832_shi[0]=ad0832_temp/100;                      //电压的十位 
   ad0832_ge[0]=ad0832_temp%100/10;                    //电压的个位 
   if(ad0832_temp<5)                                   //当电压低于设电压値时报警
     {DisplayListChar(14,1,1,ad0832_shi,no);           //电压显示
      DisplayListChar(15,1,1,ad0832_ge,no);            //电压显示
    baojing=0;                                      //蜂鸣器报警
       delay(100);
    baojing=1;
  }
 }                               
/***********************/
/*坡度角度的显示      */
void jiaodu_show()
{ uchar ad_shusw[1]=0,ad_shugw[1]=0;    
  uint shu1=0;
  shu1=(ad_1549())*51/1024;                           //角度的计算      
  ad_shusw[0]=shu1/10;                                //高位
  ad_shugw[0]=shu1%10;                                //低位
  DisplayListChar(12,0,4,jiao,no);                    //jiao字样显示
  DisplayListChar(12,1,1,ad_shusw,no);                //角度高位
  DisplayListChar(13,1,1,ad_shugw,no);
  }
/*********************/
/*液晶1602的显示时间部分*/
void display()
{ uchar lcd1[1]=0,lcd2[1]=0,lcd3[1]=0,lcd4[1]=0;
  lcd1[0]= lcd[date1]; //m1
  lcd2[0]=lcd[second]; //m2
  lcd3[0]=lcd[minute1];//f1
  lcd4[0]=lcd[minute2];//f2
  lcddisplay2(lcd1,lcd2,lcd3,lcd4);
 }
/********************************/
/*DS18B20测温对应的温度显示函数*/
void wendu_show()
{  uchar wd_data;
   uchar show_d[1]=0,show_g[1]=0;
   wd_data=ReadTemperature();
   DisplayListChar(6,0,5,wendu,no);     //wendu字样显示
   DisplayListChar(8,1,1,show_d,no);    //温度显示低位
   DisplayListChar(10,1,1,show_g,no);   //温度显示高位
}
/*************************************/
/*利用轮子上的编码盘测小车行驶的路程 */
/*外部中断0的下降沿触发来测轮子的转数*/
//利用中断函数
void count() interrupt 0 using 3
{  number++;     
  if(number==36)                        //number有编码盘来限制
   { number1++;number=0;}               //number=36时为轮子转了一圈
}
/**********************************/
/*总路程的显示函数                */
/*函数将会在任务完成的最后显示    */
void juli_show()
{float distance[1];
  distance[0]=(number1*0.18)*10/10;    //车轮的周长是0.18m
  DisplayListChar(9,0,1,mi,no);        //m字样显示
  DisplayListChar(11,1,1,distance,no); //显示路程
}
//对定时器和中断的的初始化
void star()
 { TMOD=0x11; //定时器初始化
        EA=1; //总中断     
       ET0=1; //定时器0中断
       ET1=1; //定时器1中断
       TR0=1; //定时器0开启
       EX0=1; //外部中断
       IT1=1; //外部中断为电平触发
  }
/******主函数*******************/
void main(void)
{ while(1)
  {if(qidong==0)     //判断无线遥控启动键是否按下
    {  delay(100);
     if(qidong==0)
       { star();    //定时器和外部中断的初始化   
         cs_245=1;  //出去避障          
         add_0=0;   //语音地址低
         add_1=0;   //语音地址高
         play=0;   //语音播放A段
       while(1)
        { bizhang();     //避障函数
          wendu_show();  //温度显示函数
        jiaodu_show(); //坡度角度显示
          dianchidaya(); //电池电压显示函数
           }
  }
  }
   }
 while(1); //防止程序跑飞
 while(1); //防止程序跑飞
 }

PARTNER CONTENT

文章评论0条评论)

登录后参与讨论
我要评论
0
4
关闭 站长推荐上一条 /3 下一条