51单片机 超声波模块测距显示在LCD1602液晶显示屏上

main.c文件中

#include "reg52.h"             
#include "lcd.h"
#include "intrins.h"

typedef unsigned int u16;      
typedef unsigned char u8;
typedef unsigned long u32;

sbit Echo = P2^4;
sbit Trig = P2^5;

u8 di[]="Distance";
u8 code ASCII[13] = {'0','1','2','3','4','5','6','7','8','9','.','-','M'};
                  
u16 time = 0;
u16 s = 0;
bit flag = 0;
u8 disbuff[4] = { 0,0,0,0,};


void StartModule();
void t0();
void Conut(void);


/*******************************************************************************
* 函 数 名         : main
* 函数功能           : 主函数
* 输    入         : 无
* 输    出         : 无
*******************************************************************************/
void main(void)
{    
    TMOD=0x01;           //设T0为方式1
    TH0=0;
    TL0=0;          
    ET0=1;             //允许T0中断
    EA=1;               //开启总中断
    LcdInit();
    LcdShowStr(4,0,di);
    while(1)
    {
         StartModule();
         while(!Echo);        //当RX为零时等待
         TR0=1;                //开启
         while(Echo);        //当RX为定时并等待
         TR0=0;                //关闭
         Conut();            //计算
         Lcd1602_Delay1ms(100);//使用LCD中的函数延时
    }
}
void StartModule()     //启动模块
{
      Trig=1; //启动一次模块
      _nop_(); _nop_(); _nop_(); _nop_(); 
      _nop_(); _nop_(); _nop_(); _nop_(); 
      _nop_(); _nop_(); _nop_(); _nop_(); 
      _nop_(); _nop_(); _nop_(); _nop_(); 
      _nop_(); _nop_(); _nop_(); _nop_(); 
      _nop_(); _nop_(); _nop_(); _nop_();
      Trig=0;
}
void t0() interrupt 1 //T0中断用来计数器溢出,超过测距范围
{
    flag=1;            //中断溢出标志
}
void Conut(void)
{
     time=TH0*0x100+TL0;
     TH0=0;
     TL0=0;
    
     s=(time/58.0/100.0)*1000;     
     if((s>=4000)||flag==1) //超出测量范围显示“-”
     {     
      flag=0;
     
      DisplayOneChar(4, 1, ASCII[11]);
      DisplayOneChar(5, 1, ASCII[10]);    //显示点
      DisplayOneChar(6, 1, ASCII[11]);
      DisplayOneChar(7, 1, ASCII[11]);
      DisplayOneChar(8, 1, ASCII[11]);
      DisplayOneChar(9, 1, ASCII[12]);    //显示M
     }
     else
     {
      disbuff[0]=s/1000%10;
      disbuff[1]=s/100%10;
      disbuff[2]=s/10%10;
      disbuff[3]=s/1%10;
      DisplayOneChar(4, 1, ASCII[disbuff[0]]);
      DisplayOneChar(5, 1, ASCII[10]);//显示点
      DisplayOneChar(6, 1, ASCII[disbuff[1]]);
      DisplayOneChar(7, 1, ASCII[disbuff[2]]);
      DisplayOneChar(8, 1, ASCII[disbuff[3]]);
      DisplayOneChar(9, 1, ASCII[12]);    //显示M
     }
}

INTRINS.H文件中

/*--------------------------------------------------------------------------
INTRINS.H

Intrinsic functions for C51.
Copyright (c) 1988-2004 Keil Elektronik GmbH and Keil Software, Inc.
All rights reserved.
--------------------------------------------------------------------------*/

#ifndef __INTRINS_H__    //函数库里的函数
#define __INTRINS_H__

extern void          _nop_     (void);
extern bit           _testbit_ (bit);
extern unsigned char _cror_    (unsigned char, unsigned char);
extern unsigned int  _iror_    (unsigned int,  unsigned char);
extern unsigned long _lror_    (unsigned long, unsigned char);
extern unsigned char _crol_    (unsigned char, unsigned char);
extern unsigned int  _irol_    (unsigned int,  unsigned char);
extern unsigned long _lrol_    (unsigned long, unsigned char);
extern unsigned char _chkfloat_(float);
extern void          _push_    (unsigned char _sfr);
extern void          _pop_     (unsigned char _sfr);

#endif

LCD.H中

#ifndef __LCD_H_
#define __LCD_H_

/**********************************
包含头文件
**********************************/
#include<reg52.h>
#include"intrins.h"

//---重定义关键词---//
#ifndef uchar
#define uchar unsigned char
#endif

#ifndef uint 
#define uint unsigned int
#endif

/**********************************
PIN口定义
**********************************/
#define LCD1602_DATAPINS P0
sbit LCD1602_E=P2^7;
sbit LCD1602_RW=P2^5;
sbit LCD1602_RS=P2^6;

/**********************************
函数声明
**********************************/

/*在51单片机12MHZ时钟下的延时函数*/
void Lcd1602_Delay1ms(uint c);

void Busy(void);//忙检测函数

/*LCD1602写入8位命令子函数*/
void LcdWriteCom(uchar com);

/*LCD1602写入8位数据子函数*/    
void LcdWriteData(uchar dat);

/*LCD1602初始化子程序*/        
void LcdInit();

void LcdSetCursor(uchar x,uchar y);
void DisplayOneChar(uchar X, uchar Y, uchar DData);
void LcdShowStr(uchar x,uchar y,uchar *str);                          

#endif

LCD.c中

#include "lcd.h"

/*******************************************************************************
* 函 数 名         : Lcd1602_Delay1ms
* 函数功能           : 延时函数,延时1ms
* 输    入         : c
* 输    出         : 无
* 说    名         : 该函数是在12MHZ晶振下,12分频单片机的延时。
*******************************************************************************/
void Lcd1602_Delay1ms(uint c)   
{
    uchar a,b;
    for (; c>0; c--)
    {
         for (b=199;b>0;b--)
         {
              for(a=1;a>0;a--);
         }      
    }
        
}
/*******************************************************************************
* 函 数 名         : Busy
* 函数功能           : 忙检查函数
* 输    入         : 无
* 输    出         : 无
*******************************************************************************/
void Busy(void)
{
   uchar temp=0;
   do{
       LCD1602_RW = 1;
       LCD1602_RS = 0;
       LCD1602_E = 0;     //使能
       _nop_();
       LCD1602_E = 1;
       _nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();//一个机器周期1us,大于150ns即可
       _nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();//为了仿真出来,延长脉宽,28us
       _nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();
       LCD1602_E = 0;
       temp=LCD1602_DATAPINS;
     }while(temp&0x80);
}
/*******************************************************************************
* 函 数 名         : LcdWriteCom
* 函数功能           : 向LCD写入一个字节的命令
* 输    入         : com
* 输    出         : 无
*******************************************************************************/
void LcdWriteCom(uchar com)      //写入命令
{
    LCD1602_DATAPINS = com;     //放入命令
    LCD1602_E = 0;     //使能
    LCD1602_RS = 0;       //选择发送命令
    LCD1602_RW = 0;       //选择写入
    _nop_();//一个机器周期1us,大于30ns即可
    LCD1602_E = 1;              //写入时序
    Lcd1602_Delay1ms(1);
    LCD1602_E = 0;
}
/*******************************************************************************
* 函 数 名         : LcdWriteData
* 函数功能           : 向LCD写入一个字节的数据
* 输    入         : dat
* 输    出         : 无
*******************************************************************************/                      
void LcdWriteData(uchar dat)            //写入数据
{
    LCD1602_DATAPINS = dat; //写入数据
    LCD1602_E = 0;     //使能
    LCD1602_RS = 1;       //选择发送数据
    LCD1602_RW = 0;       //选择写入
    _nop_();//一个机器周期1us,大于30ns即可
    LCD1602_E = 1;              //写入时序
    Lcd1602_Delay1ms(1);
    LCD1602_E = 0;
}
/*******************************************************************************
* 函 数 名       : LcdInit()
* 函数功能         : 初始化LCD屏
* 输    入       : 无
* 输    出       : 无
*******************************************************************************/           
void LcdInit()                          //LCD初始化子程序
{
    Lcd1602_Delay1ms(1);
     LcdWriteCom(0x38);  //设置功能,8位,两行,5X7
    Busy();
    LcdWriteCom(0x0c);   //开显示不显示光标
    Busy();
    LcdWriteCom(0x06);  //写一个AC指针加1
    Busy();
    LcdWriteCom(0x01);  //清屏
    Busy();
    LcdWriteCom(0x80);  //设置数据指针起点
}
//指定坐标
void LcdSetCursor(uchar x,uchar y) 
{
    uchar addr;
    y &= 0x01;
    x &= 0x0F; //限制X不能大于15,Y不能大于1
    if(y == 0)
        addr = 0x00 + x;
    else
        addr = 0x40 + x;
    
    LcdWriteCom(addr|0x80);
}

//按指定位置显示一个字符
void DisplayOneChar(uchar x, uchar y, uchar DData)
{
    LcdSetCursor(x,y);   //当前字符的坐标
    LcdWriteData(DData); //发数据
}

//显示字符串
void LcdShowStr(uchar x,uchar y,uchar *str)   
{
    LcdSetCursor(x,y); //当前字符的坐标
    while(*str != '\0')
    {
        LcdWriteData(*str++);
    }
}

  • 8
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值