|
仿真原理图如下(proteus仿真工程文件可到本帖附件中下载)
大一学生自己编程,供大家参考,仿真在下面
显示效果----------第一行为距离-------第二行为温湿度
注释从keil复制过来的,不知为何变成了问号
单片机源程序如下:
- #include<reg52.h>
- #include <intrins.h>
- #define uint unsigned int
- #define uchar unsigned char
- sbit rs=P3^5; //1602的数据/指令选择控制线
- sbit en=P3^4; //1602的使能控制线
- sbit trig=P0^6; //超声波测距模块Trig
- sbit echo=P0^7; //超声波测距模块Echo
- float distance; //测量所得距离
- uchar code xianshi[]={"Distance: cm"} ;
- uchar code table[]={"0123456789"};
- uchar str1[2]; //存储湿度数组
- uchar str2[2]; //存储温度数组
- sbit DATA = P3^7;//温湿度传感器DHT11数据接入端
- void display2();
- uchar TH_data,TL_data,RH_data,RL_data;
- uchar TH_temp,TL_temp,RH_temp,RL_temp;
- uchar check;
- uchar com_data,untemp,temp;
- uchar respond;
- void delay(uint n) //延时函数
- {
- uint x,y;
- for(x=n;x>0;x--)
- for(y=112;y>0;y--);
- }
- void delay_ms(uchar ms)// 毫秒延时函数
- { uchar i;
- while(ms--)
- {
- for(i = 0; i< 250; i++)
- {
- _nop_();
- _nop_();
- _nop_();
- _nop_(); //4us延时
- }
- }
- }
- void delay_us() //10us延时程序
- {
- uchar i;
- i--;
- i--;
- i--;
- i--;
- i--;
- i--;
- }
- uchar receive() // 把电平信息转化为数据》》高电平持续26-28us为1;持续70us为0
- { uchar i;
- com_data=0;
- for(i=0;i<8;i++)
- { respond=1;
- while((!DATA)&&respond++); //当总线变为高电平时,等待30us检测,若保持则为1;若变为低则为0;
- delay_us();
- delay_us();
- delay_us();
- if(DATA)
- {temp=1;
- respond=1;
- while((DATA)&&respond++);
- }
- else
- temp=0;
- com_data<<=1;
- com_data|=temp; // 将八位二进制的数移位保存在com_data中
- }
- return(com_data); //返回至函数 receive
- }
- void read_DATA()
- {
- DATA=0;
- delay_ms(18);
-
- DATA=1; //主机拉低18ms
-
- delay_us();
- delay_us();
- delay_us();
- delay_us(); //DATA总线由上拉电阻拉高 主机延时20us
- DATA=1;
-
- if(!DATA) //判断从机是否有低电平响应信号,如不响应则跳出,响应则向下运行
- {
- respond=1;
-
- while((!DATA)&& respond++); //判断从机发出 80us 的低电平响应信号是否结束
- respond=1;
-
- while(DATA && respond++); //判断从机是否发出 80us 的高电平,如发出则进入数据接收状态
-
- RH_temp = receive();
- RL_temp = receive();
- TH_temp = receive();
- TL_temp = receive();
- check = receive(); //数据接收状态
- DATA=1;
-
- untemp=(RH_temp+RL_temp+TH_temp+TL_temp);
- if(untemp==check) //数据校验
- {
- RH_data = RH_temp;
- RL_data = RL_temp;
- TH_data = TH_temp;
- TL_data = TL_temp;
- }
- }
- //湿度部分
- str1[0] = RH_data/10;
- str1[1] = RH_data%10;
- //温度部分
- str2[0] =TH_data/10;
- str2[1] =TH_data%10;
-
- }
- void lcd_com(uchar com) //命令函数
- {
- rs=0; //选择指令寄存器
- P2=com; //把命令字送入P0
- delay(5); //延时一小会儿,让1602准备接收数据
- en=1;
- delay(5); //使能线电平变化,命令送入1602的8位数据口,这点非常重要
- en=0;
- }
- void lcd_dat(uchar dat) //数据函数
- {
- rs=1; //选择数据寄存器
- P2=dat; //把要显示的数据送入P0
- delay(5); //延时一小会儿,让1602准备接收数据,也就是检测忙信号,这点非常重要。
- en=1; //使能线电平变化,数据送入1602的8位数据口
- en=0;
- }
- void lcd_init() //1602液晶初始化函数
- {
- lcd_com(0x38); //8位数据,双列,5*7字形 ,用到功能设定指令
- lcd_com(0x0c); //开启显示屏,关光标,光标不闪烁,用到显示开关控制指令
- lcd_com(0x06); //显示地址递增,即写一个数据后,显示位置右移一位,用到了写入模式设置指令
- lcd_com(0x01); //清屏,用到了清屏指令
- }
-
- void lcd_xianshi() //液晶显示函数
- {
- uint i;
- lcd_com(0x80);
- for(i=0;i<10;i++)
- lcd_dat(xianshi[i]);
-
-
- lcd_com(0x80+0x0e);//单位是厘米//
- for(i;i<14;i++)
- lcd_dat(xianshi[i]);
- }
- void measuring() //距离测量函数
- {
- float time;
- time=TH0*256+TL0;//把计时器的的值读取到time
- time*=12/11.0592;
- distance=time *0.016 ;
-
- }
- void display(uint x) // 测量结果显示函数
- {
- uint bai,shi,ge;
- bai=x/100;
- shi=(x/10%10); //或shi=x%100/10
- ge=(x%10);
-
-
- lcd_com(0x80+0x09);
- lcd_dat(table[bai]);
- lcd_dat(table[shi]);
- lcd_dat(table[ge]);
-
-
- TL0=0;
- TH0=0;
- }
- void main()
- {
-
- lcd_init(); //液晶初始化
- TMOD=0x01;
- TL0=0;
- TH0=0;
- EA=1; //定时器初始化
- trig=0;
- echo=1;
-
- while(1)
- {
-
- lcd_xianshi(); //液晶显示特定字符
- trig=1;
- delay(50);
- trig=0;
-
- while(!echo);
- TR0=1; //echo为高电平时打开计时器
- while(echo);
- TR0=0; //echo为低电平时关闭计时器
-
- measuring() ;
- display(distance);
-
- display2();
- delay_ms(60) ;
-
- }
-
- }
- void display2()
- {
- read_DATA();
- lcd_com(0x80+0x40);
- lcd_dat(table[str1[0]]);
- lcd_dat(table[str1[1]]);
- lcd_com(0x80+0x49);
- lcd_dat(table[str2[0]]);
- lcd_dat(table[str2[1]]);
- }
复制代码
所有资料51hei提供下载:
超声波测距与温湿度模块 1602液晶仿真.zip
(86.46 KB, 下载次数: 214)
|
评分
-
查看全部评分
|