找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 2693|回复: 3
收起左侧

51单片机超声波车位系统Proteus仿真程序

[复制链接]
ID:262059 发表于 2020-3-1 16:24 | 显示全部楼层 |阅读模式
在proteus中通过3个超声波检测距离实现对车位剩余数量的检测

仿真原理图如下(proteus仿真工程文件可到本帖附件中下载)
ETEHGRHT4(Z{]`C[D)HS%(U.png

单片机源程序如下:
  1. #include <reg52.h>
  2. #include <intrins.h>

  3. #define uchar unsigned char        // 以后unsigned char就可以用uchar代替
  4. #define uint  unsigned int       

  5. uint dis_temp=50;
  6. uint Margin;
  7. uint cwA,cwP,cwS;

  8. sbit LcdRs_P   = P2^7;                // 1602液晶的RS管脚      
  9. sbit LcdRw_P   = P2^6;                // 1602液晶的RW管脚
  10. sbit LcdEn_P   = P2^5;                // 1602液晶的EN管脚
  11. sbit Trig_P    = P2^2;                // 超声波模块的Trig管脚
  12. sbit Echo_P    = P2^3;                // 超声波模块的Echo管脚
  13. sbit Trig_A    = P2^0;                // 超声波模块的Trig管脚
  14. sbit Echo_A    = P2^1;                // 超声波模块的Echo管脚
  15. sbit Trig_S    = P1^6;                // 超声波模块的Trig管脚
  16. sbit Echo_S    = P1^7;                // 超声波模块的Echo管脚


  17. /*********************************************************/
  18. // 毫秒级的延时函数,time是要延时的毫秒数
  19. /*********************************************************/
  20. void DelayMs(uint time)
  21. {
  22.         uint i,j;
  23.         for(i=0;i<time;i++)
  24.                 for(j=0;j<112;j++);
  25. }


  26. /*********************************************************/
  27. // 1602液晶写命令函数,cmd就是要写入的命令
  28. /*********************************************************/
  29. void LcdWriteCmd(uchar cmd)
  30. {
  31.         LcdRs_P = 0;
  32.         LcdRw_P = 0;
  33.         LcdEn_P = 0;
  34.         P0=cmd;
  35.         DelayMs(2);
  36.         LcdEn_P = 1;   
  37.         DelayMs(2);
  38.         LcdEn_P = 0;       
  39. }


  40. /*********************************************************/
  41. // 1602液晶写数据函数,dat就是要写入的数据
  42. /*********************************************************/
  43. void LcdWriteData(uchar dat)
  44. {
  45.         LcdRs_P = 1;
  46.         LcdRw_P = 0;
  47.         LcdEn_P = 0;
  48.         P0=dat;
  49.         DelayMs(2);
  50.         LcdEn_P = 1;   
  51.         DelayMs(2);
  52.         LcdEn_P = 0;
  53. }


  54. /*********************************************************/
  55. // 1602液晶初始化函数
  56. /*********************************************************/
  57. void LcdInit()
  58. {
  59.         LcdWriteCmd(0x38);        // 16*2显示,5*7点阵,8位数据口
  60.         LcdWriteCmd(0x0C);        // 开显示,不显示光标
  61.         LcdWriteCmd(0x06);        // 地址加1,当写入数据后光标右移
  62.         LcdWriteCmd(0x01);        // 清屏
  63. }


  64. /*********************************************************/
  65. // 液晶光标定位函数
  66. /*********************************************************/
  67. void LcdGotoXY(uchar line,uchar column)
  68. {
  69.         // 第一行
  70.         if(line==0)        
  71.                 LcdWriteCmd(0x80+column);
  72.         // 第二行
  73.         if(line==1)        
  74.                 LcdWriteCmd(0x80+0x40+column);
  75. }



  76. /*********************************************************/
  77. // 液晶输出字符串函数
  78. /*********************************************************/
  79. void LcdPrintStr(uchar *str)
  80. {
  81.         while(*str!='\0')
  82.                         LcdWriteData(*str++);
  83. }


  84. /*********************************************************/
  85. // 液晶输出数字
  86. /*********************************************************/
  87. void LcdPrintNum(uint num)
  88. {
  89.         LcdWriteData(num/100+0x30);                                // 百位
  90.         LcdWriteData(num%100/10+0x30);                // 十位
  91.         LcdWriteData(num%10+0x30);                                // 个位
  92. }


  93. /*********************************************************/
  94. // 计算测到的距离
  95. /*********************************************************/
  96. uint GetDistanceP(void)
  97. {
  98.         uint sp;                                        // 用于记录测得的距离

  99.         TH0=0;
  100.         TL0=0;

  101.         Trig_P=1;                                        // 给超声波模块一个开始脉冲
  102.         DelayMs(1);
  103.         Trig_P=0;

  104.         while(!Echo_P);                // 等待超声波模块的返回脉冲
  105.         TR0=1;                                                // 启动定时器,开始计时
  106.         while(Echo_P);                // 等待超声波模块的返回脉冲结束
  107.         TR0=0;                                                // 停止定时器,停止计时

  108.         sp=((TH0*256+TL0)*0.034)/2;                // 距离cm=(时间us * 速度cm/us)/2

  109.         return sp;
  110. }
  111. uint GetDistanceS(void)
  112. {
  113.         uint ss;                                        // 用于记录测得的距离

  114.         TH0=0;
  115.         TL0=0;

  116.         Trig_S=1;                                        // 给超声波模块一个开始脉冲
  117.         DelayMs(1);
  118.         Trig_S=0;

  119.         while(!Echo_S);                // 等待超声波模块的返回脉冲
  120.         TR0=1;                                                // 启动定时器,开始计时
  121.         while(Echo_S);                // 等待超声波模块的返回脉冲结束
  122.         TR0=0;                                                // 停止定时器,停止计时

  123.         ss=((TH0*256+TL0)*0.034)/2;                // 距离cm=(时间us * 速度cm/us)/2

  124.         return ss;
  125. }
  126. uint GetDistanceA(void)
  127. {
  128.         uint sa;                                        // 用于记录测得的距离

  129.         TH0=0;
  130.         TL0=0;

  131.         Trig_A=1;                                        // 给超声波模块一个开始脉冲
  132.         DelayMs(1);
  133.         Trig_A=0;

  134.         while(!Echo_A);                // 等待超声波模块的返回脉冲
  135.         TR0=1;                                                // 启动定时器,开始计时
  136.         while(Echo_A);                // 等待超声波模块的返回脉冲结束
  137.         TR0=0;                                                // 停止定时器,停止计时

  138.         sa=((TH0*256+TL0)*0.034)/2;                // 距离cm=(时间us * 速度cm/us)/2

  139.         return sa;
  140. }
  141. void detection(uint dis,uchar buf)
  142. {
  143. if(dis>=dis_temp)
  144. {
  145. switch(buf)
  146.    {
  147.           case'S':RD = 0;cwS=1;break;     
  148.           case'P':WR = 0;cwP=1;break;
  149.           case'A':T1 = 0;cwA=1;break;                  

  150.    }
  151. }
  152. if(dis<dis_temp)
  153. {
  154.         switch(buf)
  155.    {
  156.           case'S':RD = 1;cwS=0;break;     
  157.           case'P':WR = 1;cwP=0;break;
  158.           case'A':T1 = 1;cwA=0;break;                  

  159.    }
  160. }
  161.   Margin=cwS+cwP+cwA;
  162.   LcdGotoXY(1,13);                                                          // 定位到第1行第11列
  163.         LcdWriteData(Margin%10+0x30);                                // 显示车位余量

  164. }
  165. /*********************************************************/
  166. // 主函数
  167. /*********************************************************/
  168. void main()
  169. {
  170. //        uchar dat1,dat2;
  171.         uint distP,distA,distS;
  172.        
  173.         Trig_P=0;
  174.         Trig_A=0;
  175.         Trig_S=0;
  176.        
  177.         LcdInit();                                                                                                // 执行液晶初始化
  178.         TMOD = 0x01;                                                                                        // 选择定时器0,并且确定是工作方式1(为了超声波模块测量距离计时用的)

  179.         LcdGotoXY(0,0);                                                                    // 定位到第0行第0列
  180.         LcdPrintStr("S=   cm");        // 第0行显示“HC-SR04 System”
  181.         LcdGotoXY(0,9);                                                                    // 定位到第0行第0列
  182.         LcdPrintStr("P=   cm");        // 第0行显示“HC-SR04 System”
  183.         LcdGotoXY(1,0);                                                                    // 定位到第1行第0列
  184.         LcdPrintStr("A=   cm");        // 第1行显示“S=   cm”
  185.         LcdGotoXY(1,9);                                                                    // 定位到第1行第0列
  186.         LcdPrintStr("KY:  /3");        // 第1行显示“S=   cm”



  187.         while(1)
  188.         {
  189.             distS=GetDistanceS();                                                        // 通过超声波模块获取距离
  190.                   LcdGotoXY(0,2);                                                           // 定位到第1行第2列
  191.                   LcdPrintNum(distS);                                                        // 将获取到的距离在液晶上面显示
  192.                   detection(distS,'S');
  193.                
  194.                   distP=GetDistanceP();                                                        // 通过超声波模块获取距离
  195.                   LcdGotoXY(0,11);                                                          // 定位到第1行第11列
  196.                   LcdPrintNum(distP);                                                        // 将获取到的距离在液晶上面显示
  197.                          detection(distP,'P');
  198.                
  199.             distA=GetDistanceA();                                                       
  200.                   LcdGotoXY(1,2);                                                            // 定位到第2行第11列
  201.                   LcdPrintNum(distA);                                                       
  202.                          detection(distA,'A');
  203.                


  204.         }
  205. }
复制代码

所有资料51hei提供下载:
超声波车位检测Y.zip (82.03 KB, 下载次数: 73)

评分

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

查看全部评分

回复

使用道具 举报

ID:89286 发表于 2020-3-3 22:10 | 显示全部楼层
thanks for sharing
回复

使用道具 举报

ID:708403 发表于 2020-3-24 16:46 | 显示全部楼层
这个超声波测距是怎么画出来的,为啥我找不到啊

回复

使用道具 举报

ID:404470 发表于 2020-3-26 14:06 | 显示全部楼层
好资料,51黑有你更精彩!!!
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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