×
单片机 > 单片机程序设计 > 详情

LCD1602液晶显示模版+超声波测距(C51)

发布时间:2020-08-21 发布时间:
|





LCD1602display.h
#ifndef _LCD1602DISPLAY_H_
#define _LCD1602DISPLAY_H_
#include
#include
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;
//**************************延时
void delay();
//**************************初始化
void InitLCM();
//****************************读状态
uchar ReadStatusLCM();
//******************************读数据
//uchar ResdDataLCM();
//***************************写指令
void WriteCommandLCM(uchar WCLCM, Busy);
//***************************写数据
void WriteDataLCM(uchar WDLCM);
//******************************显示1个字符
void DisplayOneChar(uchar X,uchar Y,uchar DData);
//******************************显示字符串
void DisplayListChar(uchar X,uchar Y,uchar code  *DData);
#endif
 
LCD1602display.c
#include "LCD1602display.h"
//********************延时
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);  //三次显示模式设置,不检测忙信号
 delay(1);
 WriteCommandLCM(0x38,0);
 delay(1);
 WriteCommandLCM(0x38,0);
 delay(1);
 WriteCommandLCM(0x38,1);  //显示模式设置:16×2显示,5×7点阵,8位数据接口
 WriteCommandLCM(0x0c,1);  //显示模式设置:显示开,无光标
 WriteCommandLCM(0x06,1);  //显示模式设置:光标右移,字符不移
 WriteCommandLCM(0x01,1);  //清屏幕指令,将以前的显示内容清除
}
//*********************读状态
uchar ReadStatusLCM()
{
 P0 = 0x80;
 LCM_RS = 0;
 LCM_RW = 1;
 LCM_E = 1;
 while (P0 & 0x80); //检测忙信号
 return(0);
}
//***********************读数据
/*uchar ResdDataLCM()
{
 LCM_RS=1;
 LCM_RW=1;
 LCM_E=1;
 return(0);
} */
//**********************写指令[page]
void WriteCommandLCM(uchar WCLCM, Busy)
{
 if(Busy) ReadStatusLCM();
 P0=WCLCM;
 LCM_RS=0;
 LCM_RW=0;
 LCM_E=0;
 LCM_E=1;
}
//***********************写数据
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用来选择哪一位,1是用来忙检测
 WriteDataLCM(DData); //DData用来写数据
}
//**************************显示字符串
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
#include
#include"LCD1602display.h"
sbit TX=P2^1;
sbit RX=P2^0;
uint time=0; //存放定时器的值
ulong S=0;  //距离值
bit flag=0;  //量程溢出标志位
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的值
//*************************************启动模块
void StartModule()
{
 TX=1;    //启动超声波模块
 _nop_();  //一个机器周期
 _nop_();
 _nop_();
 _nop_();
 _nop_();
 _nop_();
 _nop_();
 _nop_();
 _nop_();
 _nop_();
 _nop_();
 _nop_();
 _nop_();
 _nop_();
 _nop_();  //共15机器周期,约15us
 TX=0;   //关闭模块
}
//***************************距离计算程序
void Count()
{
 time=TH0*256+TL0;
 TH0=0;
 TL0=0;
 S=(time*1.7)/10;    //单位mm,us
 if(S>5000||flag==1)  //超出测量范围或者定时器计数满后溢出但没收到回波
 {
  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]]);
 }
}
//**********************************超声波高电平脉冲宽计算程序
void Timer_Count()
{
 TR0=1;   //启动定时器0
 while(RX);  //当Echo管脚为高电平一直计数
 TR0=0;   //当Echo管脚变为电平时停止计数
 Count();
}
//*******************************主函数
void main()
{
 uint a;
 InitLCM();
 DisplayListChar(0,0,range);
 DisplayListChar(0,1,table0);
 TMOD=0x01;  //设置定时器0为工作方式1
 TH0=0;
 TL0=0;
 EA=1;   //开总中断
 ET0=1;   //开定时器中断
 while(1)
 {
  RX=0;  //刚刚开始Echo脚为低电平(未收到回波)
  StartModule();
  for(a=8000;a>0;a--)    //此for语句用来显示延时,使数据变化不那么快
  {
   if(RX==1) Timer_Count();   //如果收到回波则开始计算高电平脉宽及其显示
  } 
 }
}
//**********************************中断函数
void Timer0 () interrupt 1
{
 TH0=0;
 TL0=0;
 flag=1;    //中断溢出标志
 RX=0;   //Echo脚置为低电平
}
 

关键字:LCD1602  液晶显示  超声波测距

『本文转载自网络,版权归原作者所有,如有侵权请联系删除』

热门文章 更多
浅谈AVR中定时器几种工作模式