找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 2061|回复: 0
收起左侧

单片机超声波入门学习(新手想学的进来)有仿真

[复制链接]
ID:424598 发表于 2020-10-28 20:52 | 显示全部楼层 |阅读模式
说明: 本贴仿真和源码是使用以下贴子修改而来

单片机超声波测距Proteus仿真与源代码


51hei截图20201028204210544.jpg


在原基础上做了二个版本, 一个是精简版本, 方便理解超声波的相关代码
另一个是自己拓展的思路

无标题.png


  1. /*
  2.         注: 以下代码真实环璄下,STC89C52最小单片机上测试成功
  3.         使用模块:
  4.                 1.最小单片机STC89C52
  5.                 2.超声波HC-SR04
  6.                 3.L298N调速模块+小风扇
  7.         进阶功能(利用超声波检测是否有人存在, 自动启动/停止小风扇):
  8.                 1.超声波对着人坐的位置(根据实际距离自行调整BJZ的值)
  9.                 2.当检测到有人时(S<=BJZ 且 Someone>=5), FengShan置高电平(电扇启动), 并进入循环检测
  10.                 3.当检测到无人时(Unmanned>=10), FengShan置低电平(电扇停止), 并进入循环检测
  11.                 4.当无人时, Unmanned变量+1, Someone变量=0
  12.                 5.当有人时Someone变量+1, Unmanned变量=0
  13. */

  14. /*
  15.         大家可以自行拓展更多实用功能, 如:
  16.                 小便池自动冲水器
  17.                 放门口的来客"欢迎光临"等等
  18. */

  19. //加载配置文件
  20. #include <reg52.H>
  21. #include <intrins.h>

  22. //类型转义
  23. #define uchar unsigned char        
  24. #define uint unsigned int
  25. #define ulong unsigned long

  26. /**********************************************************************************************************/

  27. //超声波接口
  28. sbit RX  = P3^2; //接超声波的echo引脚
  29. sbit TX  = P3^3; //接超声波的trig引脚

  30. //用蜂鸣器或Led二极管模拟测试
  31. sbit FengShan= P2^0; //负极接P2^0,正极接VCC(蜂鸣器最好是用三极管放大)

  32. //变量声明
  33. uint time=0;
  34. uint timer=0;
  35. uchar posit=0;
  36. ulong S=0;        //超声波检查距离CM
  37. ulong BJZ=50; //报警距离CM
  38. uint i; //循环记次数
  39. uint Unmanned=0; //检测到无人的次数
  40. uint Someone=0; //检测到有人的次数

  41. bit Flag_CSB=0; //超声波的中断溢出标志

  42. /**********************************************************************************************************/
  43. //************ 计算 ************
  44. void Conut(void)
  45. {
  46.         time=TH0*256+TL0; //读出T0的计时数值
  47.         TH0=0;TL0=0; //清空计时器
  48.         S=(time*1.7)/100; //算出来是CM
  49.         //声音的速度是340m/s,时间的单位是us,计算到秒需要将时间数据/1000000,
  50.         //长度=速度*时间,340*time/1000000,长度数据单位是m转换成cm需要乘以100得到340*time/10000,
  51.         //小数点都向左移两位得到3.4*time/100,因为超声波是往返了,所以再除以2,得到距离数据(time*1.7)/100
  52.         
  53.         if((S>=700) || Flag_CSB==1) //超出测量范围
  54.         {        
  55.                 FengShan=1; //停止风扇
  56.                 Flag_CSB=0; //中断溢出标志
  57.         }
  58.         else
  59.         {
  60.                 //距离小于报警值
  61.                 if(S<=BJZ)
  62.                 {        
  63.                         Someone+=1; //有人时+1
  64.                         Unmanned=0; //无人时置0
  65.                         if (Someone>=5) //为了判断准确, 连续检测5次有人才会启动风扇
  66.                         {
  67.                                 FengShan=0; //启动风扇
  68.                                 Someone=0;
  69.                         }                        
  70.                 }
  71.                 else  //大于
  72.                 {
  73.                         Unmanned+=1; //无人时+1
  74.                         Someone=0; //有人时置0
  75.                         if (Unmanned>=10) //为了判断准确, 连续检测10次无人才会停止风扇
  76.                         {
  77.                                 FengShan=1;        //停止风扇
  78.                                 Unmanned=0;
  79.                         }                        
  80.                 }
  81.         }
  82. }


  83. /**********************************************************************************************************/
  84. /***********超声波的定时器0初始化***********/
  85. void CSB_Timer0(void)
  86. {
  87.         TMOD=0x11; //设T0为方式1
  88.         TH0=0;
  89.         TL0=0;         
  90.         TH1=0xf8; //2MS定时
  91.         TL1=0x30;
  92.         ET0=1; //允许T0中断
  93.         ET1=1; //允许T1中断
  94.         TR1=1; //开启定时器
  95.         EA=1; //开启总中断
  96. }

  97. //************ 主函数 ************
  98. void main(void)
  99. {  
  100.         CSB_Timer0();        
  101.         FengShan=0; //启动风扇

  102.         while(1)
  103.         {
  104.                 while(!RX); //当上次接收完波后,RX引脚是低电平,取反就是1,此while成立,反复判断RX状态。当RX没有接收到返回波时是高电平,取反就是0,此while不成立,跳出
  105.                 TR0=1; //开启计数
  106.                 while(RX); //当RX没有接收到返回波,此while成立,程序停在这里一直判断RX状态。当RX接收到返回波,RX引脚变为低电平,此while不成立,跳出
  107.                 TR0=0; //停止计数
  108.                 Conut(); //计算
  109.         }
  110. }

  111. /**********************************************************************************************************/
  112. //************ 定时器0处理(超声波) ************
  113. void dsq0() interrupt 1 //T0中断用来计数器溢出,超过测距范围
  114. {
  115.         Flag_CSB=1; //中断溢出标志
  116. }

  117. //************ 定时器1(超声波) ************
  118. void dsq1() interrupt 3 //T1中断用于计800MS启动模块
  119. {
  120.         TH1=0xf8;
  121.         TL1=0x30; //定时2ms
  122.         timer++; //变量加
  123.         if(timer>=400) //400次就是800ms
  124.         {
  125.                 timer=0;
  126.                 TX=1; //800MS  启动一次模块
  127.                 for(i=0;i<21;i++)
  128.                 {
  129.                 _nop_();
  130.                 }
  131.                 TX=0;
  132.         }
  133. }   
复制代码

全部资料51hei下载地址:
51超声波学习.zip (94.74 KB, 下载次数: 22)

评分

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

查看全部评分

回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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