找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 2526|回复: 1
打印 上一主题 下一主题
收起左侧

智能车超声波避障碍程序(LCD1602显示)

[复制链接]
跳转到指定楼层
楼主
ID:205988 发表于 2017-6-17 17:23 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 jiajiajia 于 2017-6-17 17:27 编辑

智能车超声波避障碍程序(LCD1602显示)

#include <at89x51.h>       
#include <intrins.h>
#include "LCD1602display.h"
//#include "STC12C5A60S2_PWM.h"
#define  TX  P2_1
#define  RX  P2_0
sbit DU = P2^6;
sbit WE = P2^7;
#define Forward_L_DATA  20//当前进不能走直线的时候,请调节这两个参数,理想的时候是100,100,最大256,最小0。0的时候最慢,256的时候最快
#define Forward_R_DATA  180        //例如小车前进的时候有点向左拐,说明右边马达转速过快,那可以取一个值大一点,另外一个值小一点,例如 200  190
                            //直流电机因为制造上的误差,同一个脉宽下也不一定速度一致的,需要自己手动调节

//sbit P4_0=0xc0;        //P4口地址

/*****按照原图接线定义******/
sbit L293D_IN1=P1^2;
sbit L293D_IN2=P1^3;
sbit L293D_IN3=P1^6;
sbit L293D_IN4=P1^7;
sbit L293D_EN1=P1^4;
sbit L293D_EN2=P1^5;

sbit BUZZ=P2^3;

void cmg88()//关数码管,点阵函数
{
DU=1;  
P0=0X00;
DU=0;
}

void Delay400Ms(void);//延时400毫秒函数

unsigned char code Range[] ="==Range Finder==";//LCD1602显示格式
unsigned char code ASCII[13] = "0123456789.-M";
unsigned char code table[]="Distance:000.0cm";
unsigned char code table1[]="!!! Out of range";

unsigned char disbuff[4]={0,0,0,0};//用于分别存放距离的值0.1mm、mm、cm和m的值

void Count(void);//距离计算函数
                          
unsigned int  time=0;//用于存放定时器时间值
unsigned long S=0;//用于存放距离的值
bit  flag =0; //量程溢出标志位
bit  turn_right_flag;

//=========================================================================================================================
void Forward(unsigned char Speed_Right,unsigned char Speed_Left)//           前进
{

         L293D_IN1=0;
         L293D_IN2=1;
         L293D_IN3=1;
         L293D_IN4=0;
//     PWM_Set(255-Speed_Right,255-Speed_Left);
}
void Stop(void)        //刹车
{

     L293D_IN1=0;
         L293D_IN2=0;
         L293D_IN3=0;
         L293D_IN4=0;
//         PWM_Set(0,0);
}
void Turn_Right(unsigned char Speed_Right,unsigned char Speed_Left)         //后
{
    L293D_IN1=1;
        L293D_IN2=0;
        L293D_IN3=0;
        L293D_IN4=0;
//        PWM_Set(255-Speed_Right,255-Speed_Left);
}
//=========================================================================================================================
/********距离计算程序***************/
    void Conut(void)
        {
         time=TH1*256+TL1;
         TH1=0;
         TL1=0;
       
         //此时time的时间单位决定于晶振的速度,外接晶振为11.0592MHZ时,
                    //time的值为0.54us*time,单位为微秒
                                //那么1us声波能走多远的距离呢?1s=1000ms=1000000us
                                // 340/1000000=0.00034米
                                //0.00034米/1000=0.34毫米  也就是1us能走0.34毫米
                                //但是,我们现在计算的是从超声波发射到反射接收的双路程,
                                //所以我们将计算的结果除以2才是实际的路程

        S=time*2;//先算出一共的时间是多少微秒。
           S=S*0.17;//此时计算到的结果为毫米,并且是精确到毫米的后两位了,有两个小数点
         if(S<=300)         //
         {       
            if(turn_right_flag!=1)
                {
                    Stop();
                    Delay1ms(5);//发现小车自动复位的时候,可以稍微延长一点这个延时,减少电机反向电压对电路板的冲击。
                }
                turn_right_flag=1;
                P2_3=0;
                Delay1ms(50);
                P2_3=1;
            Turn_Right(120,120);                                 //小于设定距离时电机后退转弯
         }
         else
         {
            turn_right_flag=0;
            Forward(Forward_R_DATA,Forward_L_DATA);                          //前进(大于20-30CM前进)
         }
         //=======================================
         if((S>=5000)||flag==1) //超出测量范围
         {       
          flag=0;
      DisplayListChar(0, 1, table1);
         }
         else
         {
      disbuff[0]=S%10;
          disbuff[1]=S/10%10;
          disbuff[2]=S/100%10;
          disbuff[3]=S/1000;
          DisplayListChar(0, 1, table);
          DisplayOneChar(9, 1, ASCII[disbuff[3]]);
          DisplayOneChar(10, 1, ASCII[disbuff[2]]);       
          DisplayOneChar(11, 1, ASCII[disbuff[1]]);
      DisplayOneChar(12, 1, ASCII[10]);
          DisplayOneChar(13, 1, ASCII[disbuff[0]]);
         }
        }

/********************************************************/
     void zd0() interrupt 3                  //T0中断用来计数器溢出,超过测距范围
  {
    flag=1;                         //中断溢出标志
        RX=0;
  }

/********超声波高电平脉冲宽度计算程序***************/
void Timer_Count(void)
{
                 TR1=1;                            //开启计数
             while(RX);                        //当RX为1计数并等待
             TR1=0;                                //关闭计数
         Conut();                        //计算

}
/********************************************************/
   void  StartModule()                          //启动模块
  {
          TX=1;                                             //启动一次模块
      Delay10us(2);
          TX=0;
  }
/********************************************************/

/*************主程序********************/
void main(void)
{
    unsigned char i;
        unsigned int a;
        cmg88();//关数码管
        Delay1ms(400); //启动等待,等LCM讲入工作状态
        LCMInit(); //LCM初始化
        Delay1ms(5);//延时片刻

        DisplayListChar(0, 0, Range);
        DisplayListChar(0, 1, table);
    TMOD=TMOD|0x10;//设T0为方式1,GATE=1;
    EA=1;                                           //开启总中断
    TH1=0;
    TL1=0;         
    ET1=1;             //允许T0中断

        //===============================
        //PWM_ini();
        //===============================
        turn_right_flag=0;
        //=================================
B:                for(i=0;i<50;i++) //判断K3是否按下
                {
                   Delay1ms(1);        //1ms内判断50次,如果其中有一次被判断到K3没按下,便重新检测
                   if(P3_6!=0 )//当K3按下时,启动小车
                   goto B; //跳转到标号B,重新检测
                }
        //蜂鸣器响一声
        BUZZ=0;        //50次检测K3确认是按下之后,蜂鸣器发出“滴”声响,然后启动小车。
        Delay1ms(50);
        BUZZ=1;//响50ms后关闭蜂鸣器
        //=======================================================================================================================                       
        while(1)
          {
                RX=1;
            StartModule();                                 //启动模块
        for(a=951;a>0;a--)
            {
                  
               if(RX==1)
                   {
           Timer_Count();                 //超声波高电平脉冲宽度计算函数
                   }
             }
           }
}





C51FPS.rar

13.83 KB, 下载次数: 12, 下载积分: 黑币 -5

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:205988 发表于 2017-6-17 17:26 | 只看该作者
  1. #include <at89x51.h>        
  2. #include <intrins.h>
  3. #include "LCD1602display.h"
  4. //#include "STC12C5A60S2_PWM.h"
  5. #define  TX  P2_1
  6. #define  RX  P2_0
  7. sbit DU = P2^6;
  8. sbit WE = P2^7;
  9. #define Forward_L_DATA  20//当前进不能走直线的时候,请调节这两个参数,理想的时候是100,100,最大256,最小0。0的时候最慢,256的时候最快
  10. #define Forward_R_DATA  180        //例如小车前进的时候有点向左拐,说明右边马达转速过快,那可以取一个值大一点,另外一个值小一点,例如 200  190
  11.                             //直流电机因为制造上的误差,同一个脉宽下也不一定速度一致的,需要自己手动调节

  12. //sbit P4_0=0xc0;        //P4口地址

  13. /*****按照原图接线定义******/
  14. sbit L293D_IN1=P1^2;
  15. sbit L293D_IN2=P1^3;
  16. sbit L293D_IN3=P1^6;
  17. sbit L293D_IN4=P1^7;
  18. sbit L293D_EN1=P1^4;
  19. sbit L293D_EN2=P1^5;

  20. sbit BUZZ=P2^3;

  21. void cmg88()//关数码管,点阵函数
  22. {
  23. DU=1;  
  24. P0=0X00;
  25. DU=0;
  26. }

  27. void Delay400Ms(void);//延时400毫秒函数

  28. unsigned char code Range[] ="==Range Finder==";//LCD1602显示格式
  29. unsigned char code ASCII[13] = "0123456789.-M";
  30. unsigned char code table[]="Distance:000.0cm";
  31. unsigned char code table1[]="!!! Out of range";

  32. unsigned char disbuff[4]={0,0,0,0};//用于分别存放距离的值0.1mm、mm、cm和m的值

  33. void Count(void);//距离计算函数
  34.                           
  35. unsigned int  time=0;//用于存放定时器时间值
  36. unsigned long S=0;//用于存放距离的值
  37. bit  flag =0; //量程溢出标志位
  38. bit  turn_right_flag;

  39. //=========================================================================================================================
  40. void Forward(unsigned char Speed_Right,unsigned char Speed_Left)//           前进
  41. {

  42.          L293D_IN1=0;
  43.          L293D_IN2=1;
  44.          L293D_IN3=1;
  45.          L293D_IN4=0;
  46. //     PWM_Set(255-Speed_Right,255-Speed_Left);
  47. }
  48. void Stop(void)        //刹车
  49. {

  50.      L293D_IN1=0;
  51.          L293D_IN2=0;
  52.          L293D_IN3=0;
  53.          L293D_IN4=0;
  54. //         PWM_Set(0,0);
  55. }
  56. void Turn_Right(unsigned char Speed_Right,unsigned char Speed_Left)         //后
  57. {
  58.     L293D_IN1=1;
  59.         L293D_IN2=0;
  60.         L293D_IN3=0;
  61.         L293D_IN4=0;
  62. //        PWM_Set(255-Speed_Right,255-Speed_Left);
  63. }
  64. //=========================================================================================================================
  65. /********距离计算程序***************/
  66.     void Conut(void)
  67.         {
  68.          time=TH1*256+TL1;
  69.          TH1=0;
  70.          TL1=0;
  71.         
  72.          //此时time的时间单位决定于晶振的速度,外接晶振为11.0592MHZ时,
  73.                     //time的值为0.54us*time,单位为微秒
  74.                                 //那么1us声波能走多远的距离呢?1s=1000ms=1000000us
  75.                                 // 340/1000000=0.00034米
  76.                                 //0.00034米/1000=0.34毫米  也就是1us能走0.34毫米
  77.                                 //但是,我们现在计算的是从超声波发射到反射接收的双路程,
  78.                                 //所以我们将计算的结果除以2才是实际的路程

  79.         S=time*2;//先算出一共的时间是多少微秒。
  80.            S=S*0.17;//此时计算到的结果为毫米,并且是精确到毫米的后两位了,有两个小数点
  81.          if(S<=300)         //
  82.          {        
  83.             if(turn_right_flag!=1)
  84.                 {
  85.                     Stop();
  86.                     Delay1ms(5);//发现小车自动复位的时候,可以稍微延长一点这个延时,减少电机反向电压对电路板的冲击。
  87.                 }
  88.                 turn_right_flag=1;
  89.                 P2_3=0;
  90.                 Delay1ms(50);
  91.                 P2_3=1;
  92.             Turn_Right(120,120);                                 //小于设定距离时电机后退转弯
  93.          }
  94.          else
  95.          {
  96.             turn_right_flag=0;
  97.             Forward(Forward_R_DATA,Forward_L_DATA);                          //前进(大于20-30CM前进)
  98.          }
  99.          //=======================================
  100.          if((S>=5000)||flag==1) //超出测量范围
  101.          {        
  102.           flag=0;
  103.       DisplayListChar(0, 1, table1);
  104.          }
  105.          else
  106.          {
  107.       disbuff[0]=S%10;
  108.           disbuff[1]=S/10%10;
  109.           disbuff[2]=S/100%10;
  110.           disbuff[3]=S/1000;
  111.           DisplayListChar(0, 1, table);
  112.           DisplayOneChar(9, 1, ASCII[disbuff[3]]);
  113.           DisplayOneChar(10, 1, ASCII[disbuff[2]]);        
  114.           DisplayOneChar(11, 1, ASCII[disbuff[1]]);
  115.       DisplayOneChar(12, 1, ASCII[10]);
  116.           DisplayOneChar(13, 1, ASCII[disbuff[0]]);
  117.          }
  118.         }

  119. /********************************************************/
  120.      void zd0() interrupt 3                  //T0中断用来计数器溢出,超过测距范围
  121.   {
  122.     flag=1;                         //中断溢出标志
  123.         RX=0;
  124.   }

  125. /********超声波高电平脉冲宽度计算程序***************/
  126. void Timer_Count(void)
  127. {
  128.                  TR1=1;                            //开启计数
  129.              while(RX);                        //当RX为1计数并等待
  130.              TR1=0;                                //关闭计数
  131.          Conut();                        //计算

  132. }
  133. /********************************************************/
  134.    void  StartModule()                          //启动模块
  135.   {
  136.           TX=1;                                             //启动一次模块
  137.       Delay10us(2);
  138.           TX=0;
  139.   }
  140. /********************************************************/

  141. /*************主程序********************/
  142. void main(void)
  143. {
  144.     unsigned char i;
  145.         unsigned int a;
  146.         cmg88();//关数码管
  147.         Delay1ms(400); //启动等待,等LCM讲入工作状态
  148.         LCMInit(); //LCM初始化
  149.         Delay1ms(5);//延时片刻

  150.         DisplayListChar(0, 0, Range);
  151.         DisplayListChar(0, 1, table);
  152.     TMOD=TMOD|0x10;//设T0为方式1,GATE=1;
  153.     EA=1;                                           //开启总中断
  154.     TH1=0;
  155.     TL1=0;         
  156.     ET1=1;             //允许T0中断

  157.         //===============================
  158.         //PWM_ini();
  159.         //===============================
  160.         turn_right_flag=0;
  161.         //=================================
  162. B:                for(i=0;i<50;i++) //判断K3是否按下
  163.                 {
  164.                    Delay1ms(1);        //1ms内判断50次,如果其中有一次被判断到K3没按下,便重新检测
  165.                    if(P3_6!=0 )//当K3按下时,启动小车
  166.                    goto B; //跳转到标号B,重新检测
  167.                 }
  168.         //蜂鸣器响一声
  169.         BUZZ=0;        //50次检测K3确认是按下之后,蜂鸣器发出“滴”声响,然后启动小车。
  170.         Delay1ms(50);
  171.         BUZZ=1;//响50ms后关闭蜂鸣器
  172.         //=======================================================================================================================                        
  173.          while(1)
  174.           {
  175.                 RX=1;
  176.             StartModule();                                 //启动模块
  177.         for(a=951;a>0;a--)
  178.             {
  179.                   
  180.                if(RX==1)
  181.                    {
  182.            Timer_Count();                 //超声波高电平脉冲宽度计算函数
  183.                    }
  184.              }
  185.            }
  186. }



  187.                
复制代码
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表