找回密码
 立即注册

QQ登录

只需一步,快速开始

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

超声波旋转测距LCD1602显示(亲自测试)

[复制链接]
跳转到指定楼层
楼主
ID:272940 发表于 2018-4-26 18:42 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
/******************SL-51B实验开发板例程(超声波测距1602显示)******************

注意:用杜邦线将超声波模块的VCC接开发板5V对外供电接口
      用杜邦线将超声波模块的GND接开发板GND
   用杜邦线将超声波模块的Trig接单片机的P1.5
   用杜邦线将超声波模块的Echo接单片机的P1.6
   舵机黄线 PWM信号输出P2^2   (舵机程序)
/**********************************包含头文件**********************************/
#include <reg51.h>
#define LCD_Data P0
#define Busy 0x80
/************************************宏定义************************************/
#define SPEED_30C 3495                    //30摄氏度时的声速,声速V= 331.5 + 0.6*温度;
#define SPEED_23C 3453                    //23摄氏度时的声速,声速V= 331.5 + 0.6*温度;
/************************************位定义************************************/
sbit ECHO = P1^6;                         //回声接收端口   
sbit TRIG = P1^5;                         //超声触发端口   
sbit BEEP = P2^3;                 //蜂鸣器    
sbit LCD_RS = P1^0;
sbit LCD_RW = P1^1;
sbit LCD_E  = P2^5;
sbit   DU   = P2^0;
sbit   WE   = P2^1;
sbit pwm =P2^2 ;          //黄线 PWM信号输出P0^1     (舵机程序)
sbit jia =P3^0;           //角度增加按键检测IO口  上:k1   (舵机程序)
sbit jan =P3^1;           //角度减少按键检测IO口  下:k2   (舵机程序)
sbit go  =P3^7;           //       开始:k8 (舵机程序)
sbit sp  =P3^6;           //       停止:k7 (舵机程序)
/********************************定义变量和数组********************************/
long int distance = 0;                     //距离变量
unsigned char count;      //0.5ms次数标识(舵机程序)
unsigned char jd;         //角度标识(舵机程序)  
   
unsigned char code table0[] = {"     SL-51A     "};
unsigned char code table1[] = {"    NO  ECHO    "};
unsigned char code table2[] = {"Distance:xxx.xcm"};
unsigned char count;   //同上
unsigned int xh;   //(舵机程序)
void Delay5Ms(void);
void delay(int In,int Out);
void WriteDataLCD(unsigned char WDLCD);
void WriteCommandLCD(unsigned char WCLCD,BuysC);
unsigned char ReadDataLCD(void);
unsigned char ReadStatusLCD(void);
void LCDInit(void);
void DisplayOneChar(unsigned char X, unsigned char Y, unsigned char DData);
void DisplayListChar(unsigned char X, unsigned char Y, unsigned char code *DData);

/******************************************************************************/
/* 函数名称  : Delay_xMs                                                      */
/* 函数描述  : 延时函数                                                       */
/* 输入参数  : x                                                              */
/* 参数描述  : 延时时间                                                       */
/* 返回值    : 无                                                             */
/******************************************************************************/
void Delay_xMs(unsigned int x)
{
unsigned int i,j;
for(i = 0;i < x;i++ )
{
  for(j = 0;j < 3;j++ )
  {;}
}
}

/******************************************************************************/
/* 函数名称  : delayt                                                         */
/* 函数描述  : 延时函数                                                       */
/* 输入参数  : x                                                              */
/* 参数描述  : 延时时间数据                                                   */
/* 返回值    : 无                                                             */
/******************************************************************************/
void delayt(unsigned int x)
{
unsigned char j;
while(x-- > 0)
{
  for(j = 0;j < 125;j++)
  {;}
}
}
/*************************5ms延时函数***************************/
void Delay5Ms(void)
{
unsigned int TempCyc = 3552;
while(TempCyc--);
}
/**************************延迟函数*****************************/
void delay(int In,int Out)                                                                              
{
int i,j;
for( i = 0;i < In;i++ )
{
  for( j = 0;j < Out;j++ )
  {;}
}
}
/******************************************************************************/
/* 函数名称  : Alarm                                                          */
/* 函数描述  : 蜂鸣器发声函数                                                 */
/* 输入参数  : t                                                              */
/* 参数描述  : 发声的次数                                                     */
/* 返回值    : 无                                                             */
/******************************************************************************/
void Alarm(unsigned char t)
{
unsigned char i;
for(i = 0;i < t;i++)
{
  BEEP = 0;
  delay(10,1000);
  BEEP = 1;
  delay(10,1000);  
}
}
/******************************************************************************/
/* 函数名称  : Init_timer                                                       */
/* 函数描述  : 初始化单片机函数                                               */
/* 输入参数  : 无                                                             */
/* 参数描述  : 无                                                             */
/* 返回值    : 无                                                             */
/******************************************************************************/
void Init_timer(void)
{
TMOD = 0x01;       //定时器2初始化,设置为16位自动重装模式   
TL0  = 0x66;
TH0  = 0xfc;       //1ms   
ET0  = 1;           //开定时器2   
EA   = 1;        //总中断使能     
}
/******************************************************************************/
/* 函数名称  : Init_Parameter                                                 */
/* 函数描述  : 初始化参数和IO口函数                                           */
/* 输入参数  : 无                                                             */
/* 参数描述  : 无                                                             */
/* 返回值    : 无                                                             */
/******************************************************************************/
void Init_Parameter(void)
{
TRIG     = 1;
ECHO     = 1;
count    = 0;
distance = 0;
}
/******************************************************************************/
/* 函数名称  : display                                                        */
/* 函数描述  : 显示数字                                                       */
/* 输入参数  : number,address                                                */
/* 参数描述  : number写入的数据                                               */
/* 返回值    : 无                                                             */
/******************************************************************************/
void display(int number)
{
unsigned char b,c,d,e;
b = (number/1000);
c = (number/100)%10;
d = (number/10)%10;
e = number%10;
DisplayOneChar(9,1,(0x30+b));
DisplayOneChar(10,1,(0x30+c));
DisplayOneChar(11,1,(0x30+d));
DisplayOneChar(13,1,(0x30+e));
}
/******************************************************************************/
/* 函数名称  : Trig_SuperSonic                                                */
/* 函数描述  : 发出声波函数                                                   */
/* 输入参数  : 无                                                             */
/* 参数描述  : 无                                                             */
/* 返回值    : 无                                                             */
/******************************************************************************/
void Trig_SuperSonic(void)//出发声波
{
TRIG = 1;
delayt(1);
TRIG = 0;
}
/******************************************************************************/
/* 函数名称  : Measure_Distance                                               */
/* 函数描述  : 计算距离函数                                                   */
/* 输入参数  : 无                                                             */
/* 参数描述  : 无                                                             */
/* 返回值    : 无                                                             */
/******************************************************************************/
void Measure_Distance(void)
{
unsigned char l;
unsigned int h,y;
TR0 = 1;
while(ECHO)
{
  ;
}
TR0 = 0;
l = TL0;
h = TH0;
y = (h << 8) + l;
y = y - 0xfc66;               //us部分   
distance = y + 1000 * count;  //计算总时间     
TL0 = 0x66;
TH0 = 0xfc;
delayt(30);
distance = SPEED_30C * distance / 20000;
}
/**************************写数据函数***************************/
void WriteDataLCD(unsigned char WDLCD)
{
ReadStatusLCD();                                             //检测忙
LCD_Data = WDLCD;
LCD_RS = 1;
LCD_RW = 0;
LCD_E = 0;                                                   //若晶振速度太高可以在这后加小的延时   
LCD_E = 0;                                                   //延时
LCD_E = 1;
}
/*************************写指令函数****************************/
void WriteCommandLCD(unsigned char WCLCD,BuysC)            //BuysC为0时忽略忙检测     
{
if (BuysC) ReadStatusLCD();                                 //根据需要检测忙  
LCD_Data = WCLCD;
LCD_RS = 0;
LCD_RW = 0;
LCD_E = 0;
LCD_E = 0;
LCD_E = 1;
}
/**************************读数据函数***************************/
unsigned char ReadDataLCD(void)
{
LCD_RS = 1;
LCD_RW = 1;
LCD_E = 0;
LCD_E = 0;
LCD_E = 1;
return(LCD_Data);
}
/**************************读状态函数***************************/
unsigned char ReadStatusLCD(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);
}
/***************************LCD初始化***************************/
void LCDInit(void)                                //LCD初始化
{
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 LCD_Clear(void)
{
  WriteCommandLCD(0x01,1);
  Delay5Ms();
}
/**********************按指定位置显示一个字符*********************/
void DisplayOneChar(unsigned char X, unsigned char Y, unsigned char DData)
{
Y &= 0x1;
X &= 0xF;                                   //限制X不能大于15,Y不能大于1     
if (Y) X |= 0x40;                           //当要显示第二行时地址码+0x40;
X |= 0x80;                                  //算出指令码  
WriteCommandLCD(X, 0);                      //这里不检测忙信号,发送地址码   
WriteDataLCD(DData);
}
/***********************按指定位置显示一串字符********************/
void DisplayListChar(unsigned char X, unsigned char Y, unsigned char code *DData)
{
unsigned char ListLength;
ListLength = 0;
Y &= 0x1;
X &= 0xF;                                       //限制X不能大于15,Y不能大于1  
while (DData[ListLength]>=0x20)                 //若到达字串尾则退出   
{
  if (X <= 0xF)                                  //X坐标应小于0xF  
  {
   DisplayOneChar(X, Y, DData[ListLength]);      //显示单个字符  
   ListLength++;
   X++;
  }
}
}


/***********************舵机函数*******************************************************/
void Time0_Init()          //定时器初始化
{
TMOD = 0x01;           //定时器0工作在方式1   
IE   = 0x82;
TH0  = 0xfe;
TL0  = 0x33;     //11.0592MZ晶振,0.5ms
    TR0=1;                 //定时器开始
}
void Time0_Int() interrupt 1 //中断程序
{
TH0  = 0xfe;             //重新赋值
TL0  = 0x33;
    if(count< jd)              //判断0.5ms次数是否小于角度标识
      pwm=1;                  //确实小于,PWM输出高电平
    else
      pwm=0;                  //大于则输出低电平
    count=(count+1);          //0.5ms次数加1
    count=count%40;     //次数始终保持为40 即保持周期为20ms
}
void keyscan()              //按键扫描
{
   if(jia==0)               //角度增加按键是否按下
  {
    delay(10);              //按下延时,消抖
    if(jia==0)              //确实按下
     {
      jd++;                 //角度标识加1
      count=0;              //按键按下 则20ms周期从新开始
      if(jd==6)
        jd=5;               //已经是180度,则保持
      while(jia==0);        //等待按键放开
     }
  }
  if(jan==0)                //角度减小按键是否按下
  {
    delay(10);
    if(jan==0)
     {
      jd--;                 //角度标识减1
      count=0;
      if(jd==0)
        jd=1;               //已经是0度,则保持
      while(jan==0);
     }
  }
}

void xhcan()
{
if(go==0)               //  按键是否按下
  {
    delay(10);              //按下延时,消抖
    if(go==0)              //确实按下
     {
      xh=1;                 //
                  
      while(go==0);        //等待按键放开
     }
  }
  if(sp==0)               //  按键是否按下
  {
    delay(10);              //按下延时,消抖
    if(sp==0)              //确实按下
     {
      xh=0;                 //
                  
      while(sp==0);        //等待按键放开
     }
  }
}


/******************************************************************************/
/* 函数名称  : main                                                           */
/* 函数描述  : 主函数                                                         */
/* 输入参数  : 无                                                             */
/* 参数描述  : 无                                                             */
/* 返回值    : 无                                                             */
/******************************************************************************/     
void main(void)
{

DU=1;
P0=0x00;
DU=0;
BEEP=0;
delay(50,100);
BEEP=1;
delay(50,100);
BEEP=0;
delay(50,100);
BEEP=1;
LCDInit();  
Init_timer();
Init_Parameter();
Alarm(5);
DisplayListChar(0,0,table0);  
DisplayListChar(0,1,table1);
jd=0;    //(舵机程序)
count=0;   //(舵机程序)
Time0_Init();  //(舵机程序)
while(1)
{
  Trig_SuperSonic();         //触发超声波发射  
  while(ECHO == 0)          //等待回声   
  {
   ;
  }
  Measure_Distance();        //计算脉宽并转换为距离
  DisplayListChar(0,1,table2);
  display(distance);         //显示距离   
  Init_Parameter();          // 参数重新初始化
  delayt(100);               //延时,两次发射之间要至少有10ms间隔
  keyscan();               //按键扫描
  xhcan();       //(舵机程序)
   while(xh)      //(舵机程序)
   {
     jd=4;
delay(100,100);
     jd=3;
delay(100,100);
  jd=2;
delay(100,100);
  jd=1;
delay(100,100);
  jd=2;
delay(100,100);
  jd=3;
delay(100,100);
  jd=4;
delay(100,100);
     jd=5;
delay(100,100);
     jd=6;
xhcan();
   }
}
}
/******************************************************************************/
/* 函数名称  : timer0                                                         */
/* 函数描述  : T0中断处理函数                                                 */
/* 输入参数  : 无                                                             */
/* 参数描述  : 无                                                             */
/* 返回值    : 无                                                             */
/******************************************************************************/
void timer0 (void) interrupt 1
{
TF0 = 0;
TL0 = 0x66;
TH0 = 0xfc;
count++;
if(count == 18)//超声波回声脉宽最多18ms   
{
  TR0 =0;
  TL0 = 0x66;
  TH0 = 0xfc;
  count = 0;
}
}
/******************************************************************************/

评分

参与人数 1黑币 +5 收起 理由
20180426 + 5 赞一个!

查看全部评分

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

使用道具 举报

沙发
ID:474896 发表于 2019-2-4 14:54 | 只看该作者
别吧,楼主直接粘贴复制各模块资料的吧。。还亲测有效,写两个time0中断处理是啥意思。。
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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