基于51单片机的US-100(超声波模块)1602显示程序
/*****************************************************************************/
Name: LCD1602+US-100+STC89C52
HC-SR04 超声波测距模块串口程序
晶振: 11.0592M
Designed by : 庶野琴风Date:2016/08/11
QQ:397739038
接线:模块TRIG接 P3.1 ECH0 接 P3.0
RS(CS)接P2.0;
RW(SID)接P2.1;
E(SCLK)接P2.2;
BF接P0.7;
/*****************************************************************************/
#include
#include
#define nops {_nop_();_nop_();_nop_();_nop_();}
/******************************引脚及变量的定义****************************/ sbit RS = P2^0; // 寄存器选择位
sbit RW = P2^1; // 读取选择位
sbit E = P2^2;// 使能信号位
sbit BF = P0^7; // 忙碌信号位
unsigned char code Tab[] = {"0123456789"};
unsigned char code string[] = {"range:2cm--4.5m"};
char part,ge,shi,bai;
char idata GLengthLoh[2];// 接收缓冲区
bit success_flag;// 定义测试成功标志位
/*********************************************************/
/********* /********* /*********函数名称: delay1ms(void)
函数功能:延时 1 毫秒
函数参数: void
******************/
******************/
******************/
/*********************************************************/
void delay1ms(void)// 误差-0.651041666667us
{
char a,b;
for(b=102;b>0;b--)
for(a=3;a>0;a--);
}
/*********************************************************/
/*********函数名称: delaynms(char n)******************/
/*********函数功能:延时n 个 1 毫秒******************/ /*********函数参数: n******************/ /*********************************************************/
void delaynms(char n)
{
char a;
for(a = 0;a > n;a--)
delay1ms();
}
/*********************************************************/
/*********函数名称: BusyTest(void)******************/
/*********函数功能:判断液晶模块忙碌状态******************/
/*********函数参数:返回值:result******************/
/*********************************************************/
unsigned char BusyTest()
{
bit result;
RS=0;
RW=1;//RS为低电平,RW 为高电平时,可以读状态
E=1; nops; result = BF; E=0;// 使能为高电平时可读取信息
// 延时 40us,给硬件反应时间
// 将忙碌标志位电平赋给result // 使能 1 到 0:执行指令
return result;
}
/*********************************************************/
/*********函数名称: WriteInstruction(char dictate)*******/
/*********函数功能:将模式设置指令或显示地址写入液晶模块**/ /*********函数参数: dictate******************/
/*********************************************************/
void WriteInstruction(char dictate)
{
while(BusyTest() == 1);// 如果忙碌标志位忙碌则等待
RS=0;
RW=0;//RS/RW 位同时为低电平时可写入指令
E=0;//使能0到 1:写入指令
nops;
P0 = dictate;// 将数据送入 P0 口,写入数据或地址
nops;
E=1;//使能0到 1:写入指令
nops;
E=0;//使能1到 0:执行指令
}
/*********************************************************/
/*********函数名称: WriteAddress(char x)*******/
/*********函数功能:指定字符显示的实际地址***********/
/*********函数参数: x******************/
/*********************************************************/
void WriteAddress(char x)
{
WriteInstruction(x|0x80);// 80H+地址码
}
/*********************************************************/
/*********函数名称: WriteData(char y)*******/
/*********函数功能:将数据(字符的标准ASCII码 )写入液晶模块 */
/*********函数参数: y******************/
/*********************************************************/
void WriteData(char y)
{
while(BusyTest() == 1);// 如果忙碌标志位忙碌则等待
RS=1;
RW = 0;//RS 为高电平, RW 为低电平时,可以写入数据
E=0;
P0 = y;
nops;
E=1;
nops;
E=0;
}
/*********************************************************/
/*********函数名称: LCDInit(void)*******/
/*********函数功能:液晶模块初始化****************/
/*********函数参数: void******************/
/*********************************************************/
void LCDInit(void)
{
delaynms(15);// 延时 15 毫秒,首次写入液晶指令应给反应时间
WriteInstruction(0x38);// 显示模式设置:16× 2 显示, 5× 7 点阵, 8 位数据接口delaynms(5);//延时 5秒,反应时间
WriteInstruction(0x38);
delaynms(5);//延时 5秒,反应时间
WriteInstruction(0x38);
delaynms(5);// 连续三次,确保初始化成功
WriteInstruction(0x0c);// 显示模式设置:显示开,无光标,光标不闪烁
delaynms(5);
WriteInstruction(0x06);// 显示模式设置:显示光标右移,屏幕不移动
delaynms(5);
WriteInstruction(0x01);// 清屏
delaynms(5);
}
/*********************************************************/
/********* /*********函数名称: UART_Send(char dat)
函数功能:串口发送函数
*******/
****************/
/*********函数参数: dat******************/ /*********************************************************/
void UART_Send(char dat)
{
TI=0; SBUF = dat;//清发送标志
//如果 TI为 0等待
while (!TI);// 等待发送数据
}
/*********************************************************/
/*********函数名称: UART_Init()***************/
/*********函数功能:串口初始化函数****************/
/*********函数参数:无******************/
/*********************************************************/
void UART_Init()
{
TH1 = 0xFD;
TL1 = 0xFD;
TMOD = 0x21;// 设置定时器 1 为模式 2;定时器 0 为模式 1 TH0 =(65536-2500)/256;// 约 2.50MS 定时器初值
TL0 =(65536-2500)%256;// 约 2.50MS 定时器初值
ET0 = 1;
TR0 = 1;// 启动定时器
TR1 = 1;// 启动定时器SM0SM1
SM0 = 0;// 串口通信模式设置00 = 0
SM1 = 1;//0 1 = 1
//10 = 2
//1 1 = 3 REN = 1;// 串口允许接收数据
ES = 1;// 开串中断
EA=1;
}
/*********************************************************/
/*********函数名称: UART_ISR(void)***************/
/*********函数功能:串口中断函数****************/
/*********函数参数: void******************/
/*********************************************************/
void UART_ISR(void) interrupt 4
{
char temp,k;
ES=0;
if(RI)
{
// 关中断
RI=0;
temp = SBUF;
// 清接收标志
GLengthLoh[k] = temp;
k++;
if(k == 2) //k= 数据长度
k = 0;
}
ES=1;// 开中断
}
/*********************************************************/
/********* /********* /*********函数名称: timer0()
函数功能:定时器函数
函数参数: void
***************/
****************/
******************/
/*********************************************************/
timer0() interrupt 1//定时器0 中断是 1 号{
TH0 =(65536-2500)/256; // 约TL0 =(65536-2500)%256; // 约2.50MS 定时器初值
2.50MS 定时器初值TH0 = 0xef;TL0 = 0x94;// 写
入定时器0 初始值
}
/*********************************************************/
/*********函数名称: conversion(int8 temp_data)*******/
/*********函数功能:数据转换****************/
/*********函数参数: temp_data******************/
/*********************************************************/
void conversion(int temp_data)
{
char part_data,ge_data,shi_data,bai_data;
bai_data = temp_data / 1000;
shi_data = (temp_data % 1000) / 100;
ge_data = (temp_data % 100) / 10;
part_data = temp_data % 10;
EA=0;
bai = bai_data;
shi = shi_data;
ge = ge_data;
part = part_data;
EA=1;
}
/*********************************************************/
/*********函数名称: main(void)*******/ /*********函数功能:主函数****************/ /*********函数参数: void******************/ /*********************************************************/
void main(void)
{
int k;
long PreLength;
LCDInit();// 调用液晶初始化函数delaynms(10);
UART_Init();
PreLength = 0;
k = 0;
while(1)
{
WriteAddress(0x01);
while(string[k] != '\0')
{
WriteData(string[k]);
k++;
}
UART_Send(0X55);
PreLength = GLengthLoh[0] * 256 + GLengthLoh[1] - 5;
conversion(PreLength);
WriteAddress(0x41); WriteData('J');// 从第 2 行第 6 列开始显示
// 将特定的字符常量写入LCD
WriteData('U');
WriteData('L');
WriteData('I');
WriteData(':');
if(PreLength <= 4500 && PreLength >= 20)
{
WriteData(Tab[bai]);// 将百位数字的字符常量写入LCD WriteData(Tab[shi]);// 将十位数字的字符常量写入LCD WriteData(Tab[ge]);// 将个位数字的字符常量写入LCD WriteData('.');
WriteData(Tab[part]);
}
else
{
WriteData('-');
WriteData('-');
WriteData('-');
WriteData('-');
WriteData('-');
}
WriteData(' ');
WriteData('c');
WriteData('m');
} }