找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 5786|回复: 4
打印 上一主题 下一主题
收起左侧

单片机超声波测距和DHT11温湿度模块在1602液晶上显示Proteus仿真程序

  [复制链接]
跳转到指定楼层
楼主
仿真原理图如下(proteus仿真工程文件可到本帖附件中下载)



大一学生自己编程,供大家参考,仿真在下面
显示效果----------第一行为距离-------第二行为温湿度


注释从keil复制过来的,不知为何变成了问号

单片机源程序如下:
  1.         #include<reg52.h>   
  2. #include <intrins.h>  
  3. #define uint unsigned int
  4. #define uchar unsigned char
  5. sbit rs=P3^5;            //1602的数据/指令选择控制线
  6. sbit en=P3^4;          //1602的使能控制线
  7. sbit trig=P0^6;      //超声波测距模块Trig
  8. sbit echo=P0^7;     //超声波测距模块Echo
  9. float distance;    //测量所得距离
  10. uchar code xianshi[]={"Distance: cm"} ;
  11. uchar code table[]={"0123456789"};


  12. uchar str1[2];         //存储湿度数组
  13. uchar str2[2];          //存储温度数组
  14. sbit DATA = P3^7;//温湿度传感器DHT11数据接入端
  15. void display2();

  16. uchar TH_data,TL_data,RH_data,RL_data;

  17. uchar TH_temp,TL_temp,RH_temp,RL_temp;

  18. uchar check;

  19. uchar com_data,untemp,temp;

  20. uchar respond;

  21. void delay(uint n)   //延时函数                       
  22. {
  23.     uint x,y;
  24.     for(x=n;x>0;x--)
  25.     for(y=112;y>0;y--);
  26. }



  27. void delay_ms(uchar ms)// 毫秒延时函数

  28. {       uchar i;
  29.    while(ms--)
  30.      {
  31.         for(i = 0; i< 250; i++)
  32.             {
  33.       _nop_();
  34.       _nop_();
  35.       _nop_();
  36.       _nop_();         //4us延时
  37.              }
  38.      }

  39. }

  40. void delay_us()                   //10us延时程序
  41. {
  42.     uchar i;
  43.     i--;
  44.     i--;
  45.     i--;
  46.     i--;
  47.     i--;
  48.     i--;

  49. }               





  50. uchar receive()  // 把电平信息转化为数据》》高电平持续26-28us为1;持续70us为0

  51. {     uchar i;
  52.       com_data=0;
  53.       for(i=0;i<8;i++)   
  54.     {         respond=1;                                         
  55.               while((!DATA)&&respond++);         //当总线变为高电平时,等待30us检测,若保持则为1;若变为低则为0;
  56.                     delay_us();
  57.                     delay_us();
  58.                             delay_us();

  59.                     if(DATA)

  60.                     {temp=1;
  61.                      respond=1;
  62.               while((DATA)&&respond++);

  63.                     }
  64.                     else
  65.                      temp=0;         

  66.                   com_data<<=1;

  67.                  com_data|=temp;          // 将八位二进制的数移位保存在com_data中
  68.       }

  69.           return(com_data);            //返回至函数 receive

  70. }



  71. void read_DATA()                 

  72. {
  73.          DATA=0;

  74.          delay_ms(18);
  75.                                                          
  76.          DATA=1;                   //主机拉低18ms

  77.          
  78.          delay_us();

  79.          delay_us();

  80.          delay_us();

  81.          delay_us();  //DATA总线由上拉电阻拉高 主机延时20us


  82.          DATA=1;

  83.             

  84.          if(!DATA)     //判断从机是否有低电平响应信号,如不响应则跳出,响应则向下运行

  85.          {

  86.                 respond=1;

  87.                

  88.                 while((!DATA)&& respond++);         //判断从机发出 80us 的低电平响应信号是否结束

  89.                 respond=1;

  90.                

  91.                 while(DATA && respond++);   //判断从机是否发出 80us 的高电平,如发出则进入数据接收状态

  92.                

  93.                 RH_temp = receive();

  94.                 RL_temp = receive();

  95.                 TH_temp = receive();

  96.                 TL_temp = receive();

  97.                 check = receive();     //数据接收状态

  98.                 DATA=1;     

  99.                  

  100.                 untemp=(RH_temp+RL_temp+TH_temp+TL_temp);  

  101.                 if(untemp==check)           //数据校验

  102.                 {

  103.                          RH_data = RH_temp;

  104.                          RL_data = RL_temp;

  105.                          TH_data = TH_temp;

  106.                          TL_data = TL_temp;

  107.                 }

  108.         }

  109.         //湿度部分

  110.          str1[0] = RH_data/10;

  111.          str1[1] = RH_data%10;

  112.          //温度部分

  113.          str2[0] =TH_data/10;

  114.          str2[1] =TH_data%10;


  115. }         


  116. void lcd_com(uchar com)     //命令函数      
  117. {
  118.     rs=0;                //选择指令寄存器
  119.     P2=com;            //把命令字送入P0
  120.     delay(5);         //延时一小会儿,让1602准备接收数据
  121.     en=1;
  122.         delay(5);           //使能线电平变化,命令送入1602的8位数据口,这点非常重要
  123.     en=0;
  124. }


  125. void lcd_dat(uchar dat)    //数据函数   
  126. {
  127.     rs=1;             //选择数据寄存器
  128.     P2=dat;         //把要显示的数据送入P0
  129.     delay(5);      //延时一小会儿,让1602准备接收数据,也就是检测忙信号,这点非常重要。
  130.     en=1;         //使能线电平变化,数据送入1602的8位数据口
  131.     en=0;
  132.   }


  133. void lcd_init()         //1602液晶初始化函数   
  134. {
  135.     lcd_com(0x38);       //8位数据,双列,5*7字形  ,用到功能设定指令   
  136.     lcd_com(0x0c);      //开启显示屏,关光标,光标不闪烁,用到显示开关控制指令
  137.     lcd_com(0x06);     //显示地址递增,即写一个数据后,显示位置右移一位,用到了写入模式设置指令
  138.     lcd_com(0x01);    //清屏,用到了清屏指令
  139. }


  140. void lcd_xianshi()       //液晶显示函数      
  141. {
  142.             uint i;
  143.        lcd_com(0x80);
  144.         for(i=0;i<10;i++)
  145.                   lcd_dat(xianshi[i]);

  146.                   
  147.       
  148.         lcd_com(0x80+0x0e);//单位是厘米//
  149.         for(i;i<14;i++)
  150.                  lcd_dat(xianshi[i]);
  151. }





  152. void measuring()   //距离测量函数
  153. {
  154.      float time;
  155.          time=TH0*256+TL0;//把计时器的的值读取到time
  156.          time*=12/11.0592;
  157.          distance=time *0.016 ;

  158.          
  159. }


  160. void display(uint x)        //        测量结果显示函数
  161. {
  162.         uint bai,shi,ge;
  163.         bai=x/100;
  164.         shi=(x/10%10);         //或shi=x%100/10
  165.         ge=(x%10);
  166.                
  167.         
  168.         lcd_com(0x80+0x09);
  169.         lcd_dat(table[bai]);
  170.         lcd_dat(table[shi]);
  171.         lcd_dat(table[ge]);
  172.         
  173.       
  174.                 TL0=0;
  175.         TH0=0;
  176. }

  177. void main()           
  178. {   

  179.    

  180.      lcd_init();          //液晶初始化      
  181.      TMOD=0x01;        
  182.      TL0=0;
  183.      TH0=0;
  184.      EA=1;                 //定时器初始化  
  185.      trig=0;
  186.      echo=1;

  187.          
  188.       while(1)
  189.         {

  190.                  
  191.                 lcd_xianshi();   //液晶显示特定字符        
  192.                 trig=1;
  193.                 delay(50);
  194.                 trig=0;
  195.             
  196.                 while(!echo);                 
  197.                  TR0=1;                     //echo为高电平时打开计时器
  198.                 while(echo);
  199.                 TR0=0;                           //echo为低电平时关闭计时器
  200.         
  201.          measuring() ;
  202.                 display(distance);
  203.                   
  204.                 display2();
  205.                 delay_ms(60) ;

  206.               
  207.         }
  208.                  
  209. }



  210. void display2()

  211. {
  212.                 read_DATA();
  213.         lcd_com(0x80+0x40);
  214.         lcd_dat(table[str1[0]]);
  215.         lcd_dat(table[str1[1]]);
  216.                 lcd_com(0x80+0x49);
  217.         lcd_dat(table[str2[0]]);
  218.                 lcd_dat(table[str2[1]]);



  219. }
复制代码


所有资料51hei提供下载:
超声波测距与温湿度模块 1602液晶仿真.zip (86.46 KB, 下载次数: 214)


评分

参与人数 1黑币 +50 收起 理由
admin + 50 共享资料的黑币奖励!

查看全部评分

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏12 分享淘帖 顶2 踩
回复

使用道具 举报

沙发
ID:495323 发表于 2019-10-14 11:27 来自手机 | 只看该作者
加油,
回复

使用道具 举报

板凳
ID:62865 发表于 2019-10-14 14:41 | 只看该作者
注释从keil复制过来的,变成了问号,,,->设置KEIL的字体为简体中文就可以了
回复

使用道具 举报

地板
ID:484435 发表于 2019-10-16 15:16 | 只看该作者
谢谢分享
回复

使用道具 举报

5#
ID:648485 发表于 2019-11-24 17:38 | 只看该作者
为什么仿真图中用的是AT89C51,而程序中定义的却是reg52.h呢?
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表