STC8H系列—16.GPIO方式驱动HC-SR04超声波模块教程

一、概述:

      超声波模块HC-SR04使用Arduino驱动的例程比较多,驱动起来也是比较的简单,自然不在本文的讨论的范围。本文在C51内核的高性能芯片STC8H系列的平台上驱动HC-SR04超声波模块,驱动方式有三种,传统的方式采用GPIO方式,第二种为串口方式,第三种为I2C方式,由于硬件的限制本文使用传统的GPIO方式驱动模块【可以在模块背面R4、R5两个电阻位分别安装一个10K的电阻即可实现方式二与方式三的驱动,驱动方法不在本文的探讨范围】。

      如下的例程实现超声波模块超声波束的发射与采集,通过回声来确定探测距离,然后单片机将返回的数据量化、计算,然后将距离数据显示在OLED屏上。

      超声波模块的驱动方法,单片机向TR端发射一个10us的脉冲信号,当模块接收到触发信号后,模块开始工作,模块向被测物体发射一束超声波信号,声波信号的返回时间与距离成正比,模块自波束发射完成起向单片机输出一个高电平脉冲,当模块接收到波束信号高电平脉冲信号结束。当单片机INTO接收到上升沿时,定时器(12T)开始计时【每一个计数脉冲用时1us】,当下降沿到达时,定时器结束计时,然后将计时时间转换成距离。

二、知识链接:

   1、工作时序:

单片机P20端口给模块Trig脚一个大于 10uS的高电平脉冲;模块的Echo给单片机INTO端(P32),会给出一个与距离等比的高电平脉冲信号,可根据脉宽时间“T”【注:定时器输出值为us,必须换成s】算出【C=340m/s】:

距离=T*C/2

2、引脚介绍:

3、模式转换:

三、实验平台搭建:

   1、MCU:STC-打狗棒系列核心实验板 V2.3

   2、实验板平台:德飞莱LY-51s

   3、显示:SSD1306 0.96寸白色OLED屏(4脚IIC接口)

   4、硬件连接表:

      0.96寸4脚OLED接线图硬I2C接线表

         SDL---------->P24

         CLK---------->P25

         VCC---------->+5V

         GND---------->GND

      超声波模块HC-SR04接线图

        VCC---------->+5V

        Trig---------->P20(触发信号)

        Echo---------->P32(接收信号)

四、测试源代码:

#include <STC8H.h>
#include <stdio.h>
#include "intrins.h"
#include "oledfont.h"

#define uint8_t unsigned char
#define u8 unsigned char
#define u16  unsigned int
#define uint32_t unsigned long

#define SIZE 16
#define XLevelL		0x00
#define XLevelH		0x10
#define Max_Column	128
#define Max_Row		64
#define	Brightness	0xFF 
#define X_WIDTH 	128
#define Y_WIDTH 	64	
		     
#define OLED_CMD  0	//写命令
#define OLED_DATA 1	//写数据
 unsigned int a0=0;//测量的距离值
void init_IO();//初始化IO
//超声波
void init_Ultra();
void start_Ultra();
void Delay10us();		//@12.000MHz
void Delay1ms(unsigned char x);		//@12.000MHz 
//硬件IIC
void init_IIC();//初始化硬IIC
void IIC_wait();//执行等待
void IIC_SendData(unsigned char dat);//发送数据
void IIC_RevAck();//接收ACK信号
void IIC_STOP();//停止信号
//OLED控制用函数	
void OLED_Init(void);
void OLED_WR_Byte(unsigned char dat,unsigned char cmd);
void OLED_ShowChar(uint8_t x,uint8_t y,uint8_t chr);
void OLED_ShowString(uint8_t x,uint8_t y, uint8_t *p);	 
void OLED_Set_Pos(unsigned char x, unsigned char y);
void OLED_Clear(void);
void main()
{
		uint8_t  oledBuf[16];	 
	  P_SW2 |= 0x80;  //扩展寄存器XFR访问使能	
		init_IO();	//初始化IO
    init_IIC();//初始化硬IIC
	  OLED_Init();//初始化OLED
	  init_Ultra();
	  OLED_ShowString(0,0,"Ultrasonic Test");
	  OLED_ShowString(0,4,"by lizhipeng!");
	  OLED_ShowString(0,6," 2023/08/18");
	  sprintf((char *)oledBuf ,"Length:%d mm",a0);//格式化输出
	  OLED_ShowString(0,2,oledBuf);
	while(1)
	{
	   start_Ultra();//开始测距
		//清空显示
		sprintf((char *)oledBuf ,"Length:         ");//格式化输出
	  OLED_ShowString(0,2,oledBuf);
		//显示数值
		Delay1ms(10);		
		sprintf((char *)oledBuf ,"Length:%d mm",a0);//格式化输出
	  OLED_ShowString(0,2,oledBuf);		
	}
}


void init_IO()
{
	RSTCFG=0x50;  //开启RST键进入ISP模式
	P0M1 = 0x00;   P0M0 = 0x00;   //设置P0口为准双向口
	P2M1 = 0x00;   P2M0 = 0x00;   //设置P1口为准双向口
	P3M1 = 0x00;   P3M0 = 0x00;   //设置P3口为准双向口	
}

/***************************超声波部分**********************************/
//初始化超声波
void init_Ultra()
{
  //开启INT0中断 
	IT0=0;//INT0边缘触发
	IE0=0;//清空标志位
	EX0=1;//开启INT0中断
	EA=1;//开总中断
	PX0=1;//PX0提高INT0的优先级
	IPH|=0x01;//设置PX0H=1

	AUXR &= 0x7F;		//定时器时钟12T模式
	TMOD &= 0xF0;		//设置定时器模式
	TMOD |= 0x01;		//设置定时器模式模式一16位不重装
	TL0 = 0x00;		//设置定时初始值
	TH0 = 0x00;		//设置定时初始值
	TF0 = 0;		//清除TF0标志
	TR0 = 0;		//定时器0开始计时
  ET0=0;//不中断只计时
  P20=0;	
}

//开始测距
void start_Ultra()
{
	 unsigned int temp=0;	
  	//产生10us脉冲
		P20=1;
		Delay10us();
		P20=0;		
	  Delay1ms(200);	
	  //读取高电平的值
	  temp=TH0;
		temp=temp<<8;
		temp+=TL0;
		//计算距离,单位为mm
	  a0=temp*34;
		a0=a0/200; 
}


//INT0中断接收
void INT0_isr() interrupt 0//INT0中断入口
{
	
	if(P32==1)//上升沿
	{
	TL0 = 0x00;		//设置定时初始值
	TH0 = 0x00;		//设置定时初始值
	TF0 = 0;		//清除TF0标志	
	TR0 = 1;		//定时器0开始计时	
	}
	else//下降沿
	{
	  TR0=0; 	//停止计时	
	}
	IE0=0;//清空中断标志位
}

void Delay10us()		//@12.000MHz
{
	unsigned char i;
	i = 38;
	while (--i);
}

void Delay1ms(unsigned char x)		//@12.000MHz 
{
	unsigned char i, j;
	while(x--)
	{
		i = 16;
	  j = 147;
		do
		{
			while (--j);
		} while (--i);
	}	
}

/***************OLED函数部分已省略*************/

 

猜你喜欢

转载自blog.csdn.net/qq_21082985/article/details/132357057