超声波测距

来源:互联网 发布:php短信验证 编辑:程序博客网 时间:2024/04/25 05:55

Push_Objects.c

 

/***********************************
功能:超声波测距已经根据摆度调整小车的角度
说明:机器人的移动(代码比较长)
时间:2012.12.12
附录:脉冲数量:3/0.023=130个(3S)
***********************************/
#include<BoeBot.h>
#include<uart.h>
#include<intrins.h>

extern void LCM_Init(void);
extern void Display_List_Char(unsigned char x, unsigned char y, unsigned char *s);
extern int  US_GetDist();  //通过超声波得到距离
extern int US_GetAverage();
extern void SetDegree(int De);  //给参数0~180,整数

 


void Change_to_char(int dis,char DisChar[3])
{
 DisChar[0] = dis/100 + 0x30;
 DisChar[1] = (dis%100)/10 +0x30;
 DisChar[2] = dis%10 +0x30;
}

 

void main()

    int Distance;
 char DispChar[3];
 LCM_Init(); //LCM 初始化
 while(1)
 { //Distance = US_GetDist(); 
  Distance = US_GetAverage();
  SetDegree(Distance);
  //Change_to_char(Distance,DispChar);
  //Display_List_Char(1, 0,"abc");
  delay_nms(50);
 }
}

 

lcd1602.c

#include <AT89X52.h>
#include<BoeBot.h>

#define LCM_RW P2_1 //定义引脚
#define LCM_RS P2_2
#define LCM_E P2_0
#define LCM_Data P0
#define Busy 0x80 //用于检测LCM 状态字中的Busy 标识


void Read_Status_LCM(void)
{
 unsigned char read=0;
 LCM_RW = 1;
 LCM_RS = 0;
 LCM_E = 1;
 LCM_Data = 0xff;
 do
 {
  read = LCM_Data;
 }
 while(read & Busy);
 LCM_E = 0;
}

/************************************************************
调用: Write_Data_LCM ( )
函数名: 写LCD 数据
************************************************************/
void Write_Data_LCM(unsigned char WDLCM)
{
 Read_Status_LCM(); //检测忙
 LCM_RS = 1;
 LCM_RW = 0;
 LCM_Data &= 0x0f;
 LCM_Data |= WDLCM & 0xf0;
 LCM_E = 1; //若晶振速度太高可以在这后加小的延时
 ; //延时
 LCM_E = 0;
 WDLCM = WDLCM << 4;
 LCM_Data &= 0x0f;
 LCM_Data |= WDLCM & 0xf0;
 LCM_E = 1;
 ; //延时
 LCM_E = 0;
}

/************************************************************
调用: Write_Command_ LCM ( )
函数名: 写LCD 命令
************************************************************/
void Write_Command_LCM(unsigned char WCLCM,BuysC) //BuysC 为0 时忽略忙检测
{
 if (BuysC)
  Read_Status_LCM(); //根据需要检测忙
 LCM_RS = 0;
 LCM_RW = 0;
 LCM_Data &= 0x0f;
 LCM_Data |= WCLCM & 0xf0; //传输高四位
 LCM_E = 1;
 ;
 LCM_E = 0;
 WCLCM = WCLCM << 4; //传输低四位
 LCM_Data &= 0x0f;
 LCM_Data |= WCLCM & 0xf0;
 LCM_E = 1;
 ;
 LCM_E = 0;
}
/************************************************************
调用: LCM_Init()
函数名: LCD 初始化
************************************************************/
void LCM_Init(void)
{
 LCM_Data = 0;
 Write_Command_LCM(0x28,0); //三次显示模式设置,不检测忙信号
 delay_nms(15);
 Write_Command_LCM(0x28,0);
 delay_nms(15);
 Write_Command_LCM(0x28,0);
 delay_nms(15);
 Write_Command_LCM(0x28,1); //显示模式设置,开始要求每次检测忙信号
 Write_Command_LCM(0x08,1); //关闭显示
 Write_Command_LCM(0x01,1); //显示清屏
 Write_Command_LCM(0x06,1); //显示光标移动设置
 Write_Command_LCM(0x0C,1); //显示开及光标设置
}
/************************************************************
调用: Set_xy_LCM ()
函数名:设定显示坐标位置
************************************************************/
void Set_xy_LCM(unsigned char x, unsigned char y)
{
 unsigned char address;
 if( x == 0 )
  address = 0x80+y;
 else
  address = 0xc0+y;
 Write_Command_LCM(address,1);
}
/************************************************************
调用: Display_List_Char()
函数名:按指定位置显示一串字符
************************************************************/
void Display_List_Char(unsigned char x, unsigned char y, unsigned char *s)
{
 Set_xy_LCM(x,y);
 while(*s)
 {
  LCM_Data = *s;
  Write_Data_LCM(*s);
  s++;
 }
}

 

Delay.c

/*----------------------------------------------------------------------------------------
                      delay functions us&ms
----------------------------------------------------------------------------------------*/
 /*内嵌汇编的方法:一般格式
   #pragma ASM
     nop  ;
    #pragma ENDASM,*/
void delay_nus(unsigned int i)  //延时:i>=12 ,i的最小延时单12 us
{
  i=i/10;
  while(--i);
}  

void delay_nms(unsigned int n)  //延时n ms
{
  n=n+1;
  while(--n) 
  delay_nus(900);         //延时 1ms,同时进行补偿
}

 

US_dis.c

#include<BoeBot.h>
#include <AT89X52.h>

#define Trig_High()   P3_3=1   //定义触发引脚为P3.3引脚
#define Trig_Low()   P3_3=0
#define Read_Echo()   P3_2      //定义Echo引脚
#define Echo_High()   P3_2=1

void US_init()
{
 //初始化Trig为低,Echo为输入
 Trig_Low();
 Echo_High();
 //开启定时器,工作在16位模式下,最大范围t=65.536ms
 //可测范围s=t*1000/58cm= 1129cm
 TMOD = 0x01;  //GATE=0,定时器受软件控制,定时器模式,16位计数
 TH0 = 0;   //从0开始计数,加满溢出
 TL0 = 0;
}

void US_Trig()
{
 Trig_High();
 delay_nus(15);  //至少10us
 Trig_Low();
}

int US_GetDist()
{ int time,Dis;
 US_init();
 US_Trig();
 while(!Read_Echo());   //等待Echo为高电平
 TR0 = 1;      //启动定时器
 while(Read_Echo());    //等待echo变为低电平
 TR0 = 0;
 time = TH0*256 + TL0;  //us单位
 Dis = time/58;    //cm单位
 TH0 = 0;
 TL0 = 0;
 return Dis;
}

int US_GetAverage()
{
 int i,Distance,Data[5],max,min;
 Data[0]=US_GetDist();
 min=Data[0];
 max=Data[0];
 Distance = min;
 for(i=1;i<5;i++)
 {
  Data[i]=US_GetDist();
  if(min>Data[i]) min=Data[i];
  if(max<Data[i]) max=Data[i];
  Distance = Distance+Data[i];
 }
 Distance = Distance-min-max;
 Distance = Distance/3;
    return(Distance);
}

 

Angle.c

 #include<BoeBot.h>
#include <AT89X52.h>

//P1_2控制角度舵机
#define D_0 400
#define D_180 2400    //500到2500 是逆时针转
#define AngleMotor_0()  P1_2 = 0
#define AngleMotor_1()  P1_2 = 1

void SetDegree(int De)  //给参数0~180,整数
{ int HighTime,Cycle;
 //根据角度得到延时时间
 HighTime = D_0 + (((D_180-D_0)/20)*De)/9;
 Cycle = 20*1000;// - HighTime;
 //输出特定时间的高电平
 AngleMotor_1();
 delay_nus(HighTime);
 //输出20ms的周期
 AngleMotor_0();
 delay_nus(Cycle);
}

 

 

原创粉丝点击