标题:
超声波测距+1602显示 单片机程序
[打印本页]
作者:
记得好好学习
时间:
2019-7-20 09:30
标题:
超声波测距+1602显示 单片机程序
本人亲自看视频一手敲出来的 实测能用 代码比较规范好看点
单片机源程序如下:
#include <reg52.h>
#include <intrins.h>
#define uint unsigned int
#define uchar unsigned char
sbit in=P1^1; //超声波接收 就是ECHO
sbit out=P1^0; // 发射 就是TRIG
//lcd1602端口定义
sbit RS= P3^5; //寄存器选择位
sbit RW = P3^6; //读写选择位
sbit E = P3^4; //使能
sbit BF=P0^7; //忙碌标志
#define LCD1602data P0
uint time; //无符号整型
unsigned long s=0; //无符号长整型
bit flag; //超声波超出量程标志位
uint s1,s2,s3;
// 1602模块语句
//延时一毫秒
void delay1ms()
{
unsigned char i,j;
for(i=0;i<10;i++)
for(j=0;j<33;j++);
}
//延时若干毫秒 入口参数N
void delay(unsigned int n)
{
unsigned int i;
for(i=0;i<n;i++)
delay1ms();
}
//判断液晶忙碌状态
// 返回值 result result=1 忙碌 result=0 不忙
bit BusyTest(void)
{
bit result; //为位类型 长度0或1
RS=0;
RW=1; ///RS=0 RW=1 读状态
E=1; // e=1 允许读写
_nop_(); // kong操作
_nop_();
_nop_();
_nop_();
result=BF; //将忙碌电平给RESULT
E=0;
return result;
}
// 将模式指令 显示地址写入液晶
// 入口参数 dictate
void Write_com (unsigned char dictate) //写命令字 lcd_w_cmd
{
while(BusyTest()==1); //忙碌等待
RS=0; //RS RW同时为0 才能写入指令
RW=0;
E=0; //先置零 01跳变
_nop_();
_nop_(); //空操作 硬件反应
LCD1602data=dictate; //将数据送入P0口 写入指令或地址
_nop_();
_nop_();
_nop_();
_nop_();
E=1;
_nop_();
_nop_();
_nop_();
_nop_();
E=0;
}
//指定字符显示实际地址 入口参数x
void WriteAddress(unsigned char x)
{
Write_com(x|0x80); //显示位置确定为80+地址码X
}
//将字符写入液晶 入口参数Y
void WriteData(unsigned char y) //lcd_w_dat
{
while (BusyTest()==1);
RS=1;
RW=0;
E=0;
LCD1602data=y; // 将数据送入P0口 即将数据写入液晶模块
_nop_();
_nop_();
_nop_();
_nop_();
E=1;
_nop_();
_nop_();
_nop_();
_nop_();
E=0; //液晶模块执行命令
}
// LCD初始化
void LcdInt(void)
{
delay(15);
Write_com(0x38); //显示模式设置 16*2 5*7点阵 8位数据口
delay(5);
Write_com(0x38);
delay(5);
Write_com(0x38);
delay(5); //3次写设置模式
//write_com(0x0f); 显示模式设置 显示开 有光标 光标闪烁
// delay(5);
Write_com(0x0c); // 显示开 不显示光标
delay(5);
Write_com(0x06); // 显示模式设置 光标右移 字符不移
delay(5);
Write_com(0x01); // 清屏指令 以前内容清楚
delay(5);
}
// ADD为显示字符位置 在第二行显示 X为显示字符
// 调用函数注意 函数为显示数字 display(10,9); display(10,a)
//分别表示第二行第十位显示数字9和A代表的数字
// 如果想把此函数改写成显示字母的
// 只需把最writedata(0x30+x)中的0x30+去掉
display(unsigned char add , unsigned char x)
{
WriteAddress(0x00);
delay(5);
Write_com(0x80+0x40+add) ;
WriteData(0x30+x);
return 0;
}
LCD1602()//1602初显示
{
LcdInt();
delay(10);
Write_com(0x01); //清屏
delay(5);
WriteAddress(0x00); //设置显示地址为第一行第一个字 可以不写 默认也是第一行第一个字
delay(5);
//第一行显示 DISTANCE
WriteData('D');
WriteData('i');
WriteData('s');
WriteData('t');
WriteData('a');
WriteData('n');
WriteData('c');
WriteData('e');
WriteData(':');
return 0;
}
//以上1602模块语句
void FS() // 发送超声波
{
out=1;
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
out=0;
}
void count(void)// 计算并显示超声波测到距离
{
time=TH0*256+TL0;
TH0=0;
TL0=0;
s=(time*1.7)/100; //算出来单位为CM
if ((s>700)||flag==1) //超出测量范围显示ERROR
{
flag=0;
Write_com(0x80+0x40+11);
WriteData('E'); delay(5);
WriteData('R'); delay(5);
WriteData('R'); delay(5);
WriteData('O') ; delay(5);
WriteData('R') ; delay(5);
delay(500);
}
else
{
s1=s%1000/100;
s2=s%1000%100/10;
s3=s%1000%10%10;
display(11,s1); //s1 为上面的X 11为上面的Y
WriteData('.');
display(13,s2);
display(14,s3);
WriteData('m');
delay(500);
}
}
void zd0() interrupt 1 //t0中断用来计数器溢出 超过测量范围
{
flag=1;
}
int main()
{
LCD1602();
//while (1)
TMOD=0X01; //设置T0为方式1 GATE=0;
TH0=0;
TL0=0;
ET0=1; // 允许T0中断
EA=1;
while(1)
{
FS();
while(!in);
TR0=1;
while (in);
TR0=0;
count();
}
}
复制代码
所有资料51hei提供下载:
超声波测距22.zip
(45.26 KB, 下载次数: 90)
2019-7-20 09:29 上传
点击文件名下载附件
下载积分: 黑币 -5
作者:
嘟嘟胖子
时间:
2019-7-23 12:44
谢谢楼主。
作者:
单片机老司机
时间:
2019-11-29 20:31
好评,看的很清楚,能不能给加个报警器,求程序
欢迎光临 (http://www.51hei.com/bbs/)
Powered by Discuz! X3.1