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++);
}
}