////////////////////////////////////////////////////////////////////////////
// 给力者单片机开发学习系统,开发学习都给力! //
////////////////////////////////////////////////////////////////////////////
// 学习51单片机,其实可以很简单 //
////////////////////////////////////////////////////////////////////////////
// 宁波芯动电子有限公司 www.MovingChip.com //
////////////////////////////////////////////////////////////////////////////
#include <AT89X52.h> //调用51单片机的头文件
#include <intrins.h>
#include <math.h>
//---------------------------------------
//1602液晶相关I/O设置
sbit E=P2^3; //1602液晶的E脚接在P2.3口上
sbit RW=P2^4; //1602液晶的RW脚接在P2.4口上
sbit RS=P2^5; //1602液晶的RS脚接在P2.5口上
//---------------------------------------
//---------------------------------------
//HC-SR04相关I/O设置
sbit TIRG=P3^4; //定义IO口,具体可以去查看原理图
sbit ECHO=P3^2; //定义IO口,具体可以去查看原理图
//---------------------------------------
bit flag =0;
unsigned char k;
//---------------------------------------
//名称:1602液晶用延时函数
//适用:给力者GL9单片机开发学习系统
//公司:宁波芯动电子有限公司
//网址:www.MovingChip.com
//日期:20120916
//---------------------------------------
void Delay1602(unsigned int t)
{
unsigned int k; //定义一个16位寄存器用来做延时用
for(k=0;k<t;k++); //延时
}
//---------------------------------------
//名称:1602液晶忙检测函数
//适用:给力者GL9单片机开发学习系统
//公司:宁波芯动电子有限公司
//网址:www.MovingChip.com
//日期:20120916
//---------------------------------------
void LCD1602_busy(void)
{
P0_7=1; //将P0.7置1,为读状态做准备
RS=0; //RS=0、RW=1、E=1时,忙信号输出到DB7,由P0.7读入
RW=1; //RS=0、RW=1、E=1时,忙信号输出到DB7,由P0.7读入
E=1; //RS=0、RW=1、E=1时,忙信号输出到DB7,由P0.7读入
while(P0_7==1); //由P0.7读入1,表示1602液晶忙,需要等待
E=0; //读完以后,恢复E的电平
}
//---------------------------------------
//名称:1600写命令函数
//适用:给力者GL9单片机开发学习系统
//公司:宁波芯动电子有限公司
//网址:www.MovingChip.com
//日期:20120916
//---------------------------------------
void LCD1602_Write_com(unsigned char combuf)
{
RS=0; //选择指令寄存器
RW=0; //选择写状态
P0=combuf; //将命令字通过P0口送至DB
E=1; //E高电平将命令字写入1602液晶
E=0; //写完以后,恢复E的电平
}
//---------------------------------------
//名称:1602写命令函数(带忙检测)
//适用:给力者GL9单片机开发学习系统
//公司:宁波芯动电子有限公司
//网址:www.MovingChip.com
//日期:20120916
//---------------------------------------
void LCD1602_Write_com_busy(unsigned char combuf)
{
LCD1602_busy(); //调用忙检测函数
LCD1602_Write_com(combuf); //调用忙检测函数
}
//---------------------------------------
//名称:1602写数据函数(带忙检测)
//适用:给力者GL9单片机开发学习系统
//公司:宁波芯动电子有限公司
//网址:www.MovingChip.com
//日期:20120916
//---------------------------------------
void LCD1602_Write_data_busy(unsigned char databuf)
{
LCD1602_busy(); //调用忙检测函数
RS=1; //选择数据寄存器
RW=0; //选择写状态
P0=databuf; //将命令字通过P0口送至DB
E=1; //E高电平将命令字写入1602液晶
E=0; //写完以后,恢复E的电平
}
//---------------------------------------
//名称:1602液晶显示地址写函数
//适用:给力者GL9单片机开发学习系统
//公司:宁波芯动电子有限公司
//网址:www.MovingChip.com
//日期:20120916
//---------------------------------------
void LCD1602_Write_address(unsigned char x,unsigned char y)
{
x&=0x0f; //列地址限制在0-15间
y&=0x01; //行地址限制在0-1间
if(y==0) //如果是第一行
LCD1602_Write_com_busy(x|0x80); //将列地址写入
else //如果是第二行
LCD1602_Write_com_busy((x+0x40)|0x80); //将列地址写入
}
//---------------------------------------
//名称:1602液晶初始化函数
//适用:给力者GL9单片机开发学习系统
//公司:宁波芯动电子有限公司
//网址:www.MovingChip.com
//日期:20120916
//---------------------------------------
void LCD1602_init(void)
{
Delay1602(1500); //调用延时函数
LCD1602_Write_com(0x38); //8位数据总线,两行显示模式,5*7点阵显示
Delay1602(500); //调用延时函数
LCD1602_Write_com(0x38); //8位数据总线,两行显示模式,5*7点阵显示
Delay1602(500); //调用延时函数
LCD1602_Write_com(0x38); //8位数据总线,两行显示模式,5*7点阵显示
LCD1602_Write_com_busy(0x38); //8位数据总线,两行显示模式,5*7点阵显示
LCD1602_Write_com_busy(0x08); //显示功能关,无光标
LCD1602_Write_com_busy(0x01); //清屏
LCD1602_Write_com_busy(0x06); //写入新的数据后,光标右移,显示屏不移动
LCD1602_Write_com_busy(0x0C); //显示功能开,无光标
}
//---------------------------------------
//名称:1602液晶指定地址显示函数
//适用:给力者GL9单片机开发学习系统
//公司:宁波芯动电子有限公司
//网址:www.MovingChip.com
//日期:20120916
//---------------------------------------
void LCD1602_Disp(unsigned char x,unsigned char y,unsigned char buf)
{
LCD1602_Write_address(x,y); //先将地址信息写入
LCD1602_Write_data_busy(buf); //再写入要显示的数据
}
//---------------------------------------
//名称:定时器0中断服务程序
//适用:给力者GL9单片机开发学习系统
//公司:宁波芯动电子有限公司
//网址:www.MovingChip.com
//日期:20120918
//---------------------------------------
void Timer0(void) interrupt 1
{
//***此处用户自行添加定时器T0中断处理程序***
flag=0;
//******************************************
}
//---------------------------------------
//名称: 主函数
//适用:给力者GL9单片机开发学习系统
//公司:宁波芯动电子有限公司
//网址:www.MovingChip.com
//日期:20120916
//---------------------------------------
void main(void) //主函数,单片机开机后就是从这个函数开始运行
{
long S;
unsigned int i;
unsigned int Timeout;
LCD1602_init(); //调用1602液晶初始化函数
//***定时器Timer0初始化***
TMOD&=0xF0; //将TMOD的低4位定时器0控制部分清零
TMOD|=0x01; //设置定时器0为方式1
TMOD=0x01;
TL0=0; //设置定时器0初值低8位
TH0=0; //设置定时器0初值高8位
TR0=0; //停止定时器0
ET0=1; //Timer0中断允许
//**********************
//***开全局中断设置****
//定时器Timer0设置了中断允许,此处要开全局中断
EA=1; //开全局中断
//*********************
while(1)
{
TIRG=1; //发一个脉冲触发信号
i=4; //维持约17US,符合不低于10US的要求
while(i>0) //维持约17US,符合不低于10US的要求
i--; //维持约17US,符合不低于10US的要求
TIRG=0; //撤销触发信号
TR0=0; //关闭定时器
TL0=0; //设置定时器0初值低8位为0
TH0=0; //设置定时器0初值高8位为0
k=0; //清除溢出标志
flag=0;
Timeout=0;
while((ECHO==0)&&((Timeout++)<50000)); //等待回响高电平
TR0=1; //回响高电平来后启动定时器
Timeout=0;
while((ECHO==1)&&((Timeout++)<50000)); //等待回响高电平结束后
TR0=0; //关闭定时器
S=((TH0*256+TL0)*0.5425)/58;
if(flag==1||S>400) //超出测量范围显示“-”
{
LCD1602_Disp(0, 0, '-'); //显示百位-
LCD1602_Disp(1, 0, '-'); //显示十位-
LCD1602_Disp(2, 0, '-'); //显示个位-
LCD1602_Disp(3, 0, 'C'); //显示C
LCD