超声波模块测试与STONE串口屏

超声波模块简介

Ultrasonic-module-test-with-STONE-lcd-module (3)

超声波测距原理

超声波具有较强的方向性,在介质中的传播距离较远。因此,超声波常用于距离测量,如距离测量仪器和物体高度测量仪器,这些都可以通过超声波实现。超声波检测通常更快、更方便、计算简单、易于实现实时控制,且在测量精度方面能满足工业实际需求,因此在移动机器人领域得到了广泛应用。

超声波测距的原理是超声波发射器发出超声波,基于接收器接收超声波的时间差进行测量,与雷达测距原理相似。超声波发射器向特定方向发送超声波,同时开始计时,超声波在空气中传播,遇到障碍物后立即反射回发射器,超声波接收器接收到反射波后立即停止计时。

(超声波在空气中的传播速度为340m/s。根据计时器记录的时间t(秒),可计算出发射点到障碍物的距离s,即s=340t/2)。

HC-SR04简介

HC-SR04是一款电子爱好者常用于自行实验的超声波发射器和接收器模块。

该模块具有性能稳定、测量距离准确、精度高、盲区小的特点。

主要技术参数:

  • 工作电压:DC– -5V
  • 静态电流:小于2mA
  • 电平输出:高电平5V
  • 电平输出:低电平0V
  • 感应角度:不超过15度
  • 检测范围:2cm-450cm
  • 高精度:最高可达0.2cm

HC-SR04模块原理图

此图为HC-SR04超声波模块的原理图。若对硬件原理感兴趣,可自行查阅相关资料。

Ultrasonic-module-test-with-STONE-lcd-module (3)

Ultrasonic-module-test-with-STONE-lcd-module (3)

T

接线:VCC、TRIG(控制端)、ECHO(接收端)、GND 基本工作原理:

  1. IO 端口 TRIG 用于触发测距并输出至少 10us 的高电平信号;
  2. 模块自动发送 8 个 40kHz 的方波以自动检测是否存在信号返回;
  3. 信号返回后,通过 IO 端口 ECHO 输出高电平。高电平持续时间即为超声波从发射到返回所需的时间。测试距离 = (高电平时间 × 声速 (340m/s)) / 2;

该模块使用方法简单,发送端输出高电平超过10us,接收端即可输出高电平。为实现定时计时,可在发送端平时输入低电平时开启定时器,定时器值可用于计算时间距离。通过不断循环测试,即可获得测量值。

应用场景

  • 机器人避障
  • 物体距离测量
  • 液体液位检测
  • 公共安全
  • 停车场巡检

使用MCU测试HC-SR04

STM32F103RCT6

STM32F103RCT6是一款性能强大的MCU,以下是该MCU的基本参数:

  • 系列:STM32F10X
  • 内核:ARM – CORTEX32
  • 速度:72 MHz
  • 通信接口:CAN、I2C、IrDA、LIN、SPI、UART/USART、USB
  • 外设:DMA、电机控制PWM、PDR、POR、PVD、PWM、温度传感器、WDT
  • 程序存储容量:256KB
  • 程序存储类型:FLASH
  • RAM容量:48K
  • 电压 – 电源供应 (Vcc/Vdd) : 2 V ~ 3.6 V
  • 振荡器: 内部
  • 工作温度: -40°C ~ 85°C
  • 封装/外壳: 64-lqfp

在本项目中,我将使用 STM32F103RCT6 的 UART、GPIO、看门狗和定时器。

以下是本项目的代码开发记录。

STM32 使用 Keil MDK 软件进行开发,关于此软件您应已熟悉,因此不再介绍该软件的安装方法。

STM32 可通过 j-link 或 st-link 等仿真工具进行在线仿真和调试。下图是我使用的 STM32 开发板:

Ultrasonic-module-test-with-STONE-lcd-module (3)

通过串口助手显示测试结果

Trig 和 Echo 端口配置为低电平输出,输出超过 10 微秒的 Trig 引脚高电平脉冲(模块自动发送八个 40 kHz 方波),然后等待,捕获输出 Echo 的上升沿,同时捕获上升沿,启动定时器开始计时, 再次等待捕获回波的下降沿,在捕获下降沿时读取定时器时间,这就是超声波在空气中的传播时间,根据公式 S = (高电平时间 * (340 m/s)) / 2 可计算超声波到障碍物的距离。

基于此,我们可以编写简单的测试代码。

我们可以查看串口返回的测量结果。

Ultrasonic-module-test-with-STONE-lcd-module (3)

Ultrasonic-module-test-with-STONE-lcd-module (3)

通过串口助手显示测试结果

Trig 和 Echo 端口配置为低电平输出,输出超过 10 微秒的 Trig 引脚高电平脉冲(模块自动发送八个 40 kHz 方波),然后等待,捕获输出 Echo 的上升沿,同时捕获上升沿,启动定时器开始计时, 再次等待捕获回波的下降沿,在捕获下降沿时读取定时器时间,这就是超声波在空气中的传播时间,根据公式 S = (高电平时间 * (340 m/s)) / 2 可计算超声波到障碍物的距离。

基于此,我们可以编写简单的测试代码。

我们可以查看串口返回的测量结果。

STONE串口屏的工作原理

智能串口屏通过命令(十六进制代码)与客户的MCU通信,MCU根据接收的命令控制连接的设备工作。

Ultrasonic-module-test-with-STONE-lcd-module (3)

3步开发STONE串口屏

使用STONE的TFT-串口屏只需3步:

  1. 设计一套美观的人机交互界面。
  2. 通过RS232、RS485或TTL直接连接至客户的MCU。即插即用。
  3. 编写简单程序,通过MCU命令控制TFT-串口屏。(十六进制代码)

TFT 串口屏串行命令帧由5个数据块组成,所有串行命令或数据均以十六进制格式表示。数据传输

采用MSB方式。例如,对于0x1234,首先发送0x12,然后发送0x34。

STONE串口屏的9个常见应用场景

常见应用场景已在STONE的官方网站上详细描述。

STONE显示屏广泛应用于各类工业领域

  • 医疗美容设备
  • 建筑机械及车辆设备
  • 电子仪器
  • 工业控制系统
  • 电力行业
  • 民用电子设备
  • 自动化设备
  • 交通行业

关于STONE TOOL软件的使用

目前,STONE提供的最新版本STONE TOOL软件为TOOL2019。打开软件创建新项目,然后导入之前设计的UI显示图片,并添加自定义按钮、文本显示框等。STONE官方网站提供了该软件使用的详细教程。感兴趣的朋友可点击以下链接:

STONE 串口屏的UI图形设计

您可以使用Photoshop或其他图像设计软件设置UI界面。我设计的界面如下:

Ultrasonic-module-test-with-STONE-lcd-module (3)

使用TOOL2019软件生成STONE 串口屏配置文件

点击箭头所示按钮生成配置文件,然后将配置文件下载到显示模块中,即可显示我们设计的UI界面。

Ultrasonic-module-test-with-STONE-lcd-module (3)

这部分内容和教程我不再详细展开,您可以前往STONE官网下载非常详细的教程。

STM32 LCD项目实现过程(使用UART TTL)

该演示功能相对简单,主要包括以下两点:

显示超声波模块测量的距离

通过显示屏上的“+”和“-”按钮更改刷新时间

STONE LCD项目硬件连接的可靠性

硬件接线非常简单,可参考以下连接示意图:

Ultrasonic-module-test-with-STONE-lcd-module (3)

STM32微控制器驱动STONE串口屏程序

STM32微控制器驱动HC-SR04的程序可从网络下载,此处也使用用户提供的示例程序进行修改。

外设资源使用

MCU外设仅使用两个GPIO引脚(trig、echo)和一个定时器。此外,需通过UART与STONE显示器进行通信。

void EXTI9_5_IRQHandler(void)

{

static u8 flag_Sta = 0;

if(EXTI_GetITStatus(EXTI_Line5) != RESET)

{

EXTI_ClearITPendingBit(EXTI_Line5);

if(GPIO_ReadInputDataBit(GPIOC,GPIO_Pin_5)==1)

{

TIM_SetCounter(TIM6,0);

flag_Sta=1;

TIM_Cmd(TIM6, ENABLE);

}

else

{

TIM_Cmd(TIM6, DISABLE);

if(flag_Sta)

{

Distance = TIM_GetCounter(TIM6);

Distance = Distance /29;

if(Distance > 300)

Distance = 300;

Done = 1;

}

flag_Sta=0;

}

}

}

Trig 和 echo 端口配置为低电平输出。首先向 Trig 输出至少 10 微秒的高电平脉冲(模块会自动发送八个 40 kHz 方波),然后等待,捕获输出 echo 的上升沿,同时捕获上升沿,开启定时器并开始计时,再次等待捕获 echo 的下降沿,在捕获下降沿时读取定时器时间, 这是超声波在空气中的传播时间,根据S = (高电平时间 * (340 m/s)) / 2可计算超声波到障碍物的距离。

Main. c

#include "usart1.h"

#include "Sonic.h"

#include "SysTick.h"

#define DISPLYER_ADDR           0x05

#define CHANGE_TIME_ADDR        0x10

u8 data_send[8]=  {0xA5, 0x5A, 0x05, 0x82, 0x00, 0x00, 0x00,0x00};

extern u16  Distance;

extern u8  USART_RX_BUF[10];

extern u8 USART_RX_END;

extern u16 USART_RX_STA;

void UART1_Send_Array(u8 send_array[],unsigned char num)

{

u8 i=0;

while(i<num)< span=""></num)<>

{

USART_SendData(USART1,send_array[i]);

while( USART_GetFlagStatus(USART1,USART_FLAG_TC)!= SET);

i++;

}

}

/*

* Function£ºmain

*/

int main(void)

{

u8 time=0,time_set=100;

SysTick_Init();

USART1_Config(115200); /* USART1 INIT*/

TIM6_Init(); //TIM6 Init

Sonic_Init(); //Sonic_Init

// printf("STM32F103VET6_Sonic Test!\r\n");

// printf("2017-04-14 9:00\r\n\r\n");

while(1)

{

Delay_ms(10);

time++;

if(time>=time_set)

{

time=0;

data_send[5]=DISPLYER_ADDR;

data_send[6] = Distance >> 8;//hight

data_send[7] = Distance & 0x00ff;//low

UART1_Send_Array(data_send,8);

// printf("The Distance is: %d centimetre\r\n",Distance);

}

if(USART_RX_END)

{

// UART1_Send_Array(USART_RX_BUF,8);

switch (USART_RX_BUF[5])

{

case CHANGE_TIME_ADDR:

time_set=USART_RX_BUF[7]*10;

break;

default:

USART_RX_END=0;

USART_RX_STA=0;

break;

}

USART_RX_END=0;

USART_RX_STA=0;

}

}

}

/******************* (C) COPYRIGHT 2017 *****END OF FILE************/

Sonic.c

#include "Sonic.h"

/*******************************************************************************

* Sonic  Init

*******************************************************************************/

u32  Distance = 0;

u8   Done;

u32 __IO time_1ms = 0;

void TIM6_Init(void)

{

TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;

//NVIC_InitTypeDef    NVIC_InitStructure;

/* TIM6 clock enable */

RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM6, ENABLE);

/* Time base configuration */

TIM_TimeBaseStructure.TIM_Period = 0xFFFF;

TIM_TimeBaseStructure.TIM_Prescaler = 142;          //144£¬500K

TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;

TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;

TIM_TimeBaseInit(TIM6, &TIM_TimeBaseStructure);

TIM_ITConfig(TIM6, TIM_IT_Update, DISABLE);

TIM_Cmd(TIM6, DISABLE);

}

void Sonic_Init(void)

{

NVIC_InitTypeDef NVIC_InitStructure;

EXTI_InitTypeDef EXTI_InitStructure;

GPIO_InitTypeDef GPIO_InitStructure;

RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOC| RCC_APB2Periph_AFIO,ENABLE);

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;

GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4; //PC4 Trig

GPIO_Init(GPIOC,&GPIO_InitStructure);

GPIO_InitStructure.GPIO_Mode= GPIO_Mode_IPD;

GPIO_InitStructure.GPIO_Pin=GPIO_Pin_5;            //PC5 Echo

GPIO_Init(GPIOC,&GPIO_InitStructure);

GPIO_WriteBit(GPIOC,GPIO_Pin_4,(BitAction)0); //trig

//EXTI_DeInit();

EXTI_ClearITPendingBit(EXTI_Line5);

GPIO_EXTILineConfig(GPIO_PortSourceGPIOC,GPIO_PinSource5);

EXTI_InitStructure.EXTI_Line= EXTI_Line5;

EXTI_InitStructure.EXTI_Mode= EXTI_Mode_Interrupt;

EXTI_InitStructure.EXTI_Trigger= EXTI_Trigger_Rising_Falling;

EXTI_InitStructure.EXTI_LineCmd=ENABLE;

EXTI_Init(&EXTI_InitStructure);

NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);

NVIC_InitStructure.NVIC_IRQChannel = EXTI9_5_IRQn;

NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority= 0;

NVIC_InitStructure.NVIC_IRQChannelSubPriority= 0;

NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;

NVIC_Init(&NVIC_InitStructure);

Distance = 0;

Done = 1;

}

void Sonic_Trig(void)

{

u16 i = 0;

if((Done == 1)&&(time_1ms > 100))

{

time_1ms = 0;

GPIO_WriteBit(GPIOC,GPIO_Pin_4,(BitAction)1);

for(i=0;i<0xf0;i++);

GPIO_WriteBit(GPIOC,GPIO_Pin_4,(BitAction)0);

Done = 0;

}

}

void EXTI9_5_IRQHandler(void)

{

static u8 flag_Sta = 0;

if(EXTI_GetITStatus(EXTI_Line5) != RESET)

{

EXTI_ClearITPendingBit(EXTI_Line5);

if(GPIO_ReadInputDataBit(GPIOC,GPIO_Pin_5)==1)

{

TIM_SetCounter(TIM6,0);

flag_Sta=1;

TIM_Cmd(TIM6, ENABLE);

}

else

{

TIM_Cmd(TIM6, DISABLE);

if(flag_Sta)

{

Distance = TIM_GetCounter(TIM6);

Distance = Distance /29;

if(Distance > 300)

Distance = 300;

Done = 1;

}

flag_Sta=0;

}

}

}

/*******************      (C) COPYRIGHT 2017       *END OF FILE************/

Uart

#include "usart1.h"

void USART1_Config(uint32_t uBaud)

{

USART1_Configuration(uBaud);

USART1_NVIC_Configuration();

}

void USART1_Configuration(uint32_t uBaud)

{

GPIO_InitTypeDef GPIO_InitStructure;

USART_InitTypeDef USART_InitStructure;

/* config USART1 clock */

RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1 | RCC_APB2Periph_GPIOA, ENABLE);

/* USART1 GPIO config */

/* Configure USART1 Tx (PA.09) as alternate function push-pull */

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;

GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

GPIO_Init(GPIOA, &GPIO_InitStructure);

/* Configure USART1 Rx (PA.10) as input floating */

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;

GPIO_Init(GPIOA, &GPIO_InitStructure);

/* USART1 mode config */

USART_InitStructure.USART_BaudRate = uBaud;

USART_InitStructure.USART_WordLength = USART_WordLength_8b;

USART_InitStructure.USART_StopBits = USART_StopBits_1;

USART_InitStructure.USART_Parity = USART_Parity_No ;

USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;

USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;

USART_Init(USART1, &USART_InitStructure);

USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);

USART_Cmd(USART1, ENABLE);

}

void USART1_NVIC_Configuration(void)

{

NVIC_InitTypeDef NVIC_InitStructure;

/* Configure the NVIC Preemption Priority Bits */

NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);

/* Enable the USARTy Interrupt */

NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;

NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;

NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;

NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

NVIC_Init(&NVIC_InitStructure);

}

int fputc(int ch, FILE *f)

{

USART_SendData(USART1, (unsigned char) ch);

while (!(USART1->SR & USART_FLAG_TXE));

//while( USART_GetFlagStatus(USART1,USART_FLAG_TC)!= SET);

return (ch);

}

u16 USART_RX_STA=0;

u8 USART_RX_END=0;

u8 USART_RX_BUF[10];

void USART1_IRQHandler(void)

{

u8 Res;

if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)

{

Res =USART_ReceiveData(USART1);

//printf("%x",USART_ReceiveData(USART1));

// USART_SendData(USART1,Res);

if(USART_RX_END==0)

{

USART_RX_BUF[USART_RX_STA]=Res ;

USART_RX_STA++;

if(USART_RX_STA>=8)

{

USART_RX_END=1;

}

}

}

}

Sys_tick

void SysTick_Handler(void)

{

time_1ms++;

time_120ms++;

if(time_120ms>=80)

{

Sonic_Trig(); //50ms Trig Sonic

time_120ms=0;

}

TimingDelay_Decrement();

}

超声波模块与STONE 串口屏效果测试

在硬件连接无误的情况下,将代码下载至STM32开发板,超声波模块测得的距离可在STONE串口屏上查看。此外,可通过电机显示模块上方的“+”和“-”按钮调整距离刷新时间。

Ultrasonic-module-test-with-STONE-lcd-module (3)

Ultrasonic-module-test-with-STONE-lcd-module (3)

滚动至顶部