【51单片机使用一个定时器驱动三路HC-SR04超声波测距模块】

51单片机使用一个定时器驱动三路HC-SR04超声波测距模块

  • HC-SR04超声波测距模块简介
  • MCU选择
  • 代码

代码链接为: 项目代码

HC-SR04超声波测距模块简介

HC-SR04 超声波测距模块可提供 2cm-400cm 的非接触式距离感测功能,测距精度可达高到 3mm;模块包括超声波发射器、接收器与控制电路。
基本工作原理:
(1)采用 IO 口 TRIG 触发测距,给最少 10us 的高电平信呈。
(2)模块自动发送 8 个 40khz 的方波,自动检测是否有信号返回;
(3)有信号返回,通过 IO 口 ECHO 输出一个高电平,高电平持续的时间就是超声波从发射到返回的时间。测试距离=(高电平时间*声速(340M/S))/2;
注:1、此模块不宜带电连接,若要带电连接,则先让模块的 GND 端先连接,否则会影响模块的正常工作。
2、测距时,被测物体的面积不少于 0.5 平方米且平面尽量要求平整,否则影响测量的结果【51单片机使用一个定时器驱动三路HC-SR04超声波测距模块】_第1张图片

MCU选择

使用了STC12C5A60S2单片机作为MCU,程序可直接移植到STC89C52/51单片机
具体接线请参考代码

代码

HC-SR04.C

#include"MAIN.h"
#include"HC-SR04.h"
/*
 * 作者:PrairieOne
 * csdn:PrairieOne
 * 邮箱:[email protected]
 * 嵌入式技术交流群:738655377
 */
// 使用超声波器件  ECHO 引脚必须固定为 定时器1 的 P3.6引脚,使用该T1引脚计数功能
sbit HC_SR04_TRIG=P3^5;                     // 超声波模块 输入端口 用来输入启动信号
sbit HC_SR04_ECHO=P3^6;                     // 超声波模块 输出端口 用来声波信号返回

sbit HC_SR04_TRIG_R=P2^6;                     // 超声波模块 输入端口 用来输入启动信号
sbit HC_SR04_ECHO_R=P2^7;                     // 超声波模块 输出端口 用来声波信号返回
sbit HC_SR04_TRIG_L=P0^7;                     // 超声波模块 输入端口 用来输入启动信号
sbit HC_SR04_ECHO_L=P0^6;                     // 超声波模块 输出端口 用来声波信号返回
uint16_t HC_SR04_Distance = 0;   // 测量距离
uint16_t HC_SR04_Distance_R = 0;   // 测量距离
uint16_t HC_SR04_Distance_L = 0;   // 测量距离

//==================================================================================================
//  HC-SR04 获取距离
//==================================================================================================
//void HC_SR04_GetValue(void)
//{
//    uint16_t TimeCount = 0;
//    
//    TMOD = TMOD & 0x0F;                             // 定时器设置T1 模式
//    TMOD = TMOD | 0x10;

//    TH1 = 0;                                        // 定时器初值设定为0
//    TL1 = 0;                                        // 定时器初值设定为0
//    TR1 = 0;
//    TF0 = 0;
//    ET1 = 0;
//    HC_SR04_TRIG = 0;                               // 拉低 HC_SR04_TRIG
//    DELAY_nMS(1);                                   // 延时一段时间
//    HC_SR04_ECHO = 1;                               // 拉高 HC_SR04_ECHO
//    HC_SR04_TRIG = 1;                               // 拉高 HC_SR04_TRIG
//    DELAY_nMS(1);                                   // 延时一段时间
//    HC_SR04_TRIG = 0;                               // 拉低 HC_SR04_TRIG
//    while(HC_SR04_ECHO == 0);                       // 等待HC_SR04_ECHO低电平
//    TR1 = 1;                                        // 定时器0开启
//    while(HC_SR04_ECHO == 1)                        // 等待HC_SR04_ECHO高电平
//    {
//        if(TH1 >= 0x80)                             // 计数超过一定值,视为采集失败
//        {
//            TR1 = 0;                                // 关闭定时器0中断
//            return;
//        }
//    }
//    TR1 = 0;                                        // 关闭定时器0中断
//    TimeCount= TH1*256 + TL1;                       // 计算出所花时钟数
//    DELAY_nMS(10);                                  // 防止发射信号对回传信号的影响,进行延时
//    HC_SR04_Distance = (uint32_t)TimeCount *17 / 10000;        // 转化为距离,单位CM
//}
void HC_SR04_GetValue(uint8_t channel)
{
    uint16_t TimeCount = 0;
    uint16_t TimeCount_R = 0;
    uint16_t TimeCount_L = 0;
    //TMOD = TMOD & 0xf0;                             // 定时器设置T1 模式
    TMOD = TMOD | 0x01;

    TH0 = 0;                                        // 定时器初值设定为0
    TL0 = 0;                                        // 定时器初值设定为0
    TR0 = 0;
    TF0 = 0;//
    ET0 = 0;
	if(channel==1)
	{
		HC_SR04_TRIG = 0;                               // 拉低 HC_SR04_TRIG
		DELAY_nMS(1);                                   // 延时一段时间
		HC_SR04_ECHO = 1;                               // 拉高 HC_SR04_ECHO
		HC_SR04_TRIG = 1;                               // 拉高 HC_SR04_TRIG
		DELAY_nMS(1);                                   // 延时一段时间
		HC_SR04_TRIG = 0;                               // 拉低 HC_SR04_TRIG
		while(HC_SR04_ECHO == 0);                       // 等待HC_SR04_ECHO低电平
		TR0 = 1;                                        // 定时器0开启
		while(HC_SR04_ECHO == 1)                        // 等待HC_SR04_ECHO高电平
		{
			if(TH0 >= 0x80)                             // 计数超过一定值,视为采集失败
			{
				TR0 = 0;                                // 关闭定时器0中断
				return;
			}
		}
		TR0 = 0;                                        // 关闭定时器0中断
		TimeCount= TH0*256 + TL0;                       // 计算出所花时钟数
		DELAY_nMS(10);                                  // 防止发射信号对回传信号的影响,进行延时
		HC_SR04_Distance = (uint32_t)TimeCount *17 / 1000;        // 转化为距离,单位CM
	}
	else if(channel==2)
	{
		HC_SR04_TRIG_R = 0;                               // 拉低 HC_SR04_TRIG
		DELAY_nMS(1);                                   // 延时一段时间
		HC_SR04_ECHO_R = 1;                               // 拉高 HC_SR04_ECHO
		HC_SR04_TRIG_R = 1;                               // 拉高 HC_SR04_TRIG
		DELAY_nMS(1);                                   // 延时一段时间
		HC_SR04_TRIG_R = 0;                               // 拉低 HC_SR04_TRIG
		while(HC_SR04_ECHO_R == 0);                       // 等待HC_SR04_ECHO低电平
		TR0 = 1;                                        // 定时器0开启
		while(HC_SR04_ECHO_R == 1)                        // 等待HC_SR04_ECHO高电平
		{
			if(TH0 >= 0x80)                             // 计数超过一定值,视为采集失败
			{
				TR0 = 0;                                // 关闭定时器0中断
				return;
			}
		}
		TR0 = 0;                                        // 关闭定时器0中断
		TimeCount_R= TH0*256 + TL0;                       // 计算出所花时钟数
		DELAY_nMS(10);                                  // 防止发射信号对回传信号的影响,进行延时
		HC_SR04_Distance_R = (uint32_t)TimeCount_R *17 / 1000;        // 转化为距离,单位CM
	}
	else if(channel==3)
	{
		HC_SR04_TRIG_L = 0;                               // 拉低 HC_SR04_TRIG
		DELAY_nMS(1);                                   // 延时一段时间
		HC_SR04_ECHO_L = 1;                               // 拉高 HC_SR04_ECHO
		HC_SR04_TRIG_L = 1;                               // 拉高 HC_SR04_TRIG
		DELAY_nMS(1);                                   // 延时一段时间
		HC_SR04_TRIG_L = 0;                               // 拉低 HC_SR04_TRIG
		while(HC_SR04_ECHO_L == 0);                       // 等待HC_SR04_ECHO低电平
		TR0 = 1;                                        // 定时器0开启
		while(HC_SR04_ECHO_L == 1)                        // 等待HC_SR04_ECHO高电平
		{
			if(TH0 >= 0x80)                             // 计数超过一定值,视为采集失败
			{
				TR0 = 0;                                // 关闭定时器0中断
				return;
			}
		}
		TR0 = 0;                                        // 关闭定时器0中断
		TimeCount_L= TH0*256 + TL0;                       // 计算出所花时钟数
		DELAY_nMS(10);                                  // 防止发射信号对回传信号的影响,进行延时
		HC_SR04_Distance_L = (uint32_t)TimeCount_L *17 / 1000;        // 转化为距离,单位CM
	}
	
}

HC-SR04.H

#ifndef __HC_SR04_H__
#define __HC_SR04_H__

extern uint16_t HC_SR04_Distance;   // 测量距离
extern uint16_t HC_SR04_Distance_R;   // 测量距离
extern uint16_t HC_SR04_Distance_L;   // 测量距离
//void HC_SR04_GetValue(void);
//void HC_SR04_GetR_Value(void);
void HC_SR04_GetValue(uint8_t channel);
#endif

在一个定时器里面运行三个超声波传感器,可以极大的节约引脚资源,也解决了51单片机定时器较少的问题。

遇事不决,可问春风

你可能感兴趣的:(8051单片机,传感器模块,51单片机,嵌入式硬件,单片机)