说明: 本贴仿真和源码是使用以下贴子修改而来
单片机超声波测距Proteus仿真与源代码
在原基础上做了二个版本, 一个是精简版本, 方便理解超声波的相关代码
另一个是自己拓展的思路
- /*
- 注: 以下代码真实环璄下,STC89C52最小单片机上测试成功
- 使用模块:
- 1.最小单片机STC89C52
- 2.超声波HC-SR04
- 3.L298N调速模块+小风扇
- 进阶功能(利用超声波检测是否有人存在, 自动启动/停止小风扇):
- 1.超声波对着人坐的位置(根据实际距离自行调整BJZ的值)
- 2.当检测到有人时(S<=BJZ 且 Someone>=5), FengShan置高电平(电扇启动), 并进入循环检测
- 3.当检测到无人时(Unmanned>=10), FengShan置低电平(电扇停止), 并进入循环检测
- 4.当无人时, Unmanned变量+1, Someone变量=0
- 5.当有人时Someone变量+1, Unmanned变量=0
- */
- /*
- 大家可以自行拓展更多实用功能, 如:
- 小便池自动冲水器
- 放门口的来客"欢迎光临"等等
- */
- //加载配置文件
- #include <reg52.H>
- #include <intrins.h>
- //类型转义
- #define uchar unsigned char
- #define uint unsigned int
- #define ulong unsigned long
- /**********************************************************************************************************/
- //超声波接口
- sbit RX = P3^2; //接超声波的echo引脚
- sbit TX = P3^3; //接超声波的trig引脚
- //用蜂鸣器或Led二极管模拟测试
- sbit FengShan= P2^0; //负极接P2^0,正极接VCC(蜂鸣器最好是用三极管放大)
- //变量声明
- uint time=0;
- uint timer=0;
- uchar posit=0;
- ulong S=0; //超声波检查距离CM
- ulong BJZ=50; //报警距离CM
- uint i; //循环记次数
- uint Unmanned=0; //检测到无人的次数
- uint Someone=0; //检测到有人的次数
- bit Flag_CSB=0; //超声波的中断溢出标志
- /**********************************************************************************************************/
- //************ 计算 ************
- void Conut(void)
- {
- time=TH0*256+TL0; //读出T0的计时数值
- TH0=0;TL0=0; //清空计时器
- S=(time*1.7)/100; //算出来是CM
- //声音的速度是340m/s,时间的单位是us,计算到秒需要将时间数据/1000000,
- //长度=速度*时间,340*time/1000000,长度数据单位是m转换成cm需要乘以100得到340*time/10000,
- //小数点都向左移两位得到3.4*time/100,因为超声波是往返了,所以再除以2,得到距离数据(time*1.7)/100
-
- if((S>=700) || Flag_CSB==1) //超出测量范围
- {
- FengShan=1; //停止风扇
- Flag_CSB=0; //中断溢出标志
- }
- else
- {
- //距离小于报警值
- if(S<=BJZ)
- {
- Someone+=1; //有人时+1
- Unmanned=0; //无人时置0
- if (Someone>=5) //为了判断准确, 连续检测5次有人才会启动风扇
- {
- FengShan=0; //启动风扇
- Someone=0;
- }
- }
- else //大于
- {
- Unmanned+=1; //无人时+1
- Someone=0; //有人时置0
- if (Unmanned>=10) //为了判断准确, 连续检测10次无人才会停止风扇
- {
- FengShan=1; //停止风扇
- Unmanned=0;
- }
- }
- }
- }
- /**********************************************************************************************************/
- /***********超声波的定时器0初始化***********/
- void CSB_Timer0(void)
- {
- TMOD=0x11; //设T0为方式1
- TH0=0;
- TL0=0;
- TH1=0xf8; //2MS定时
- TL1=0x30;
- ET0=1; //允许T0中断
- ET1=1; //允许T1中断
- TR1=1; //开启定时器
- EA=1; //开启总中断
- }
- //************ 主函数 ************
- void main(void)
- {
- CSB_Timer0();
- FengShan=0; //启动风扇
- while(1)
- {
- while(!RX); //当上次接收完波后,RX引脚是低电平,取反就是1,此while成立,反复判断RX状态。当RX没有接收到返回波时是高电平,取反就是0,此while不成立,跳出
- TR0=1; //开启计数
- while(RX); //当RX没有接收到返回波,此while成立,程序停在这里一直判断RX状态。当RX接收到返回波,RX引脚变为低电平,此while不成立,跳出
- TR0=0; //停止计数
- Conut(); //计算
- }
- }
- /**********************************************************************************************************/
- //************ 定时器0处理(超声波) ************
- void dsq0() interrupt 1 //T0中断用来计数器溢出,超过测距范围
- {
- Flag_CSB=1; //中断溢出标志
- }
- //************ 定时器1(超声波) ************
- void dsq1() interrupt 3 //T1中断用于计800MS启动模块
- {
- TH1=0xf8;
- TL1=0x30; //定时2ms
- timer++; //变量加
- if(timer>=400) //400次就是800ms
- {
- timer=0;
- TX=1; //800MS 启动一次模块
- for(i=0;i<21;i++)
- {
- _nop_();
- }
- TX=0;
- }
- }
复制代码
全部资料51hei下载地址:
51超声波学习.zip
(94.74 KB, 下载次数: 26)
|