LCD1602display.h
#ifndef _LCD1602DISPLAY_H_
#define _LCD1602DISPLAY_H_
#include<reg52.h>
#include<intrins.h>
typedef unsigned char uchar;
typedef unsigned int uint;
typedef unsigned long ulong;
//************************LCD引腳定義
sbit LCM_RS=P2^5;
sbit LCM_RW=P2^6;
sbit LCM_E=P2^7;
//**************************延時(shí)
void delay();
//**************************初始化
void InitLCM();
//****************************讀狀態(tài)
uchar ReadStatusLCM();
//******************************讀數(shù)據(jù)
//uchar ResdDataLCM();
//***************************寫指令
void WriteCommandLCM(uchar WCLCM, Busy);
//***************************寫數(shù)據(jù)
void WriteDataLCM(uchar WDLCM);
//******************************顯示1個(gè)字符
void DisplayOneChar(uchar X,uchar Y,uchar DData);
//******************************顯示字符串
void DisplayListChar(uchar X,uchar Y,uchar code *DData);
#endif
LCD1602display.c
#include "LCD1602display.h"
//********************延時(shí)
void delay(uchar z)
{
uchar i,j;
for(i=z;i>0;i--)
for(j=110;j>0;j--);
}
//**********************LCM初始化
void InitLCM()
{
WriteCommandLCM(0x38,0); //三次顯示模式設(shè)置,不檢測(cè)忙信號(hào)
delay(1);
WriteCommandLCM(0x38,0);
delay(1);
WriteCommandLCM(0x38,0);
delay(1);
WriteCommandLCM(0x38,1); //顯示模式設(shè)置:16×2顯示,5×7點(diǎn)陣,8位數(shù)據(jù)接口
WriteCommandLCM(0x0c,1); //顯示模式設(shè)置:顯示開(kāi),無(wú)光標(biāo)
WriteCommandLCM(0x06,1); //顯示模式設(shè)置:光標(biāo)右移,字符不移
WriteCommandLCM(0x01,1); //清屏幕指令,將以前的顯示內(nèi)容清除
}
//*********************讀狀態(tài)
uchar ReadStatusLCM()
{
P0 = 0x80;
LCM_RS = 0;
LCM_RW = 1;
LCM_E = 1;
while (P0 & 0x80); //檢測(cè)忙信號(hào)
return(0);
}
//***********************讀數(shù)據(jù)
/*uchar ResdDataLCM()
{
LCM_RS=1;
LCM_RW=1;
LCM_E=1;
return(0);
} */
//**********************寫指令
void WriteCommandLCM(uchar WCLCM, Busy)
{
if(Busy) ReadStatusLCM();
P0=WCLCM;
LCM_RS=0;
LCM_RW=0;
LCM_E=0;
LCM_E=1;
}
//***********************寫數(shù)據(jù)
void WriteDataLCM(uchar WDLCM)
{
ReadStatusLCM();
P0=WDLCM;
LCM_RS=1;
LCM_RW=0;
LCM_E=0;
LCM_E=1;
}
//*************************顯示字符
void DisplayOneChar(uchar X,uchar Y,uchar DData)
{
if(Y) X|=0X40; //Y=1顯示第二行,Y=0顯示第一行
X|=0X80;
WriteCommandLCM(X,1); //X用來(lái)選擇哪一位,1是用來(lái)忙檢測(cè)
WriteDataLCM(DData); //DData用來(lái)寫數(shù)據(jù)
}
//**************************顯示字符串
void DisplayListChar(uchar X,uchar Y,uchar code *DData)
{
uchar ListLength;
ListLength=0;
while(DData[ListLength]!='\0')
{
if(X<=15)
{
DisplayOneChar( X,Y,DData[ListLength]);
ListLength++;
X++;
}
}
}
main.c
#include<reg52.h>
#include<intrins.h>
#include"LCD1602display.h"
sbit TX=P2^1;
sbit RX=P2^0;
uint time=0; //存放定時(shí)器的值
ulong S=0; //距離值
bit flag=0; //量程溢出標(biāo)志位
uchar code range[]="==Range Finder==";
uchar code ASCII[]="0123456789.";
uchar code table0[]="Distance:000.0cm";
uchar code table1[]="Out of range !!!";
uchar distance[4]={0,0,0,0}; //用于分別存放距離的值0.1mm、mm、cm和m的值
//*************************************啟動(dòng)模塊
void StartModule()
{
TX=1; //啟動(dòng)超聲波模塊
_nop_(); //一個(gè)機(jī)器周期
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_(); //共15機(jī)器周期,約15us
TX=0; //關(guān)閉模塊
}
//***************************距離計(jì)算程序
void Count()
{
time=TH0*256+TL0;
TH0=0;
TL0=0;
S=(time*1.7)/10; //單位mm,us
if(S>5000||flag==1) //超出測(cè)量范圍或者定時(shí)器計(jì)數(shù)滿后溢出但沒(méi)收到回波
{
flag=0;
DisplayListChar(0,1,table1);
}
else
{
distance[3]=S/1000; //m
distance[2]=S%1000/100; //cm
distance[1]=S%100/10; //mm
distance[0]=S%10; //0.1mm
DisplayListChar(0, 1, table0);
DisplayOneChar(9, 1, ASCII[distance[3]]);
DisplayOneChar(10, 1, ASCII[distance[2]]);
DisplayOneChar(11, 1, ASCII[distance[1]]);
DisplayOneChar(12, 1, ASCII[10]);
DisplayOneChar(13, 1, ASCII[distance[0]]);
}
}
//**********************************超聲波高電平脈沖寬計(jì)算程序
void Timer_Count()
{
TR0=1; //啟動(dòng)定時(shí)器0
while(RX); //當(dāng)Echo管腳為高電平一直計(jì)數(shù)
TR0=0; //當(dāng)Echo管腳變?yōu)殡娖綍r(shí)停止計(jì)數(shù)
Count();
}
//*******************************主函數(shù)
void main()
{
uint a;
InitLCM();
DisplayListChar(0,0,range);
DisplayListChar(0,1,table0);
TMOD=0x01; //設(shè)置定時(shí)器0為工作方式1
TH0=0;
TL0=0;
EA=1; //開(kāi)總中斷
ET0=1; //開(kāi)定時(shí)器中斷
while(1)
{
RX=0; //剛剛開(kāi)始Echo腳為低電平(未收到回波)
StartModule();
for(a=8000;a>0;a--) //此for語(yǔ)句用來(lái)顯示延時(shí),使數(shù)據(jù)變化不那么快
{
if(RX==1) Timer_Count(); //如果收到回波則開(kāi)始計(jì)算高電平脈寬及其顯示
}
}
}
//**********************************中斷函數(shù)
void Timer0 () interrupt 1
{
TH0=0;
TL0=0;
flag=1; //中斷溢出標(biāo)志
RX=0; //Echo腳置為低電平
}