Exploración preliminar del concurso integrado: (3) sensor de distancia ultrasónico externo

Debido a que se usa la función de medición de distancia, es necesario estar familiarizado con el sensor de medición de distancia externo y estudiar su precisión de medición de distancia.

Sugerencia: después de escribir el artículo, la tabla de contenido se puede generar automáticamente. Cómo generarla puede consultar el documento de ayuda a la derecha


prefacio

Para los periféricos, primero debe aprender a usar mounriver studio para agregar bibliotecas de periféricos y escribir funciones relacionadas para completar la función de rango en el programa principal.

1. Sensor ultrasónico HC-SR04

La onda ultrasónica externa es una onda mecánica con una frecuencia de vibración superior a 20 KHZ. Tiene las características de alta frecuencia, longitud de onda corta, pequeño fenómeno de difracción, buena direccionalidad y puede convertirse en rayos y propagación direccional.Es ampliamente utilizado y adecuado para estudiantes universitarios, ingenieros, técnicos y entusiastas de la electrónica.

El rendimiento de la nueva versión HC-SR04 supera con creces al de la versión anterior HC-SRO4 y US-015. Cuando la precisión de rango es mayor que la de la versión anterior HC-SRO4 y US-015, el rango de rango es mayor, hasta 6 metros, superando con creces el módulo de alcance ultrasónico general. Adopte el chip SOC de alcance ultrasónico CS-100A, alto rendimiento, grado industrial, voltaje amplio, precio bajo, solo la mitad del precio del módulo de alcance ultrasónico ordinario, y su rendimiento supera con creces el módulo de alcance ultrasónico ordinario. El rendimiento es el mismo que el US-025, ambos adoptan el chip CS100A y la interfaz es totalmente compatible.
Aquí seleccione el PD10 y PD11 de la interfaz de expansión.

Módulo ultrasónico HC-SR04:
VCC --> VCC
GND --> GND
Trig --> PD10
Echo --> PD11

2. Principio de funcionamiento

El pin Trig (Disparador) se usa para disparar pulsos ultrasónicos.

Eco El pin produce un pulso cuando se recibe una señal reflejada. La longitud del pulso es proporcional al tiempo requerido para detectar la señal transmitida.

Todo comienza cuando se aplica un pulso con una duración de al menos 10 µS (10 microsegundos) al pin del disparador. En respuesta, el sensor emite un pulso de sonido de ocho pulsos a 40 KHz. El patrón de 8 pulsos permite al receptor distinguir el patrón de transmisión del ruido ultrasónico ambiental.

Ocho pulsos ultrasónicos viajan por el aire, alejándose del transmisor. Al mismo tiempo, el pin de eco sube y comienza a formarse el comienzo de la señal de eco.

Si estos pulsos no se reflejan (es decir, cuando no hay ningún obstáculo dentro de la distancia máxima), la señal de eco se interrumpirá después de 38 milisegundos (38 ms) y volverá a ser baja. Por lo tanto, un pulso de 38 ms indica que no hay bloqueo dentro del rango del sensor.
inserte la descripción de la imagen aquí
Si el pulso se refleja de nuevo, el pin Echo bajará después de que se reciba la señal. Esto produce un pulso cuyo ancho varía entre 150 µS y 25 mS, dependiendo del tiempo que tarde en recibir la señal.
Por lo tanto, cuando no hay obstáculo, la duración del pulso de respuesta adquirida es de 38ms, mientras que cuando hay un obstáculo, la duración del pulso de respuesta adquirida varía de 150 µS a 25 mS.
inserte la descripción de la imagen aquí
Resumen: distancia = tiempo de alto nivel * velocidad del sonido (340M/S)/2;

3. MRS agregar archivo de biblioteca

1. Crear nuevos archivos .c y .h

Abra MRS, cree un proyecto CH32V307VCT6, cree una nueva carpeta de hardware en la columna CH32V307VCT6 a la izquierda, haga clic con el botón derecho en nueva carpeta, asígnele el nombre HC-SR04 y luego haga clic con el botón derecho en nuevo archivo de encabezado, archivo de origen.
inserte la descripción de la imagen aquí
Es necesario agregar un nuevo archivo de encabezado a la ruta de direccionamiento del archivo de encabezado. Haga clic en el botón Configuración de la propiedad del proyecto de la barra de menú. En la página emergente, como se muestra en la figura a continuación, haga clic en el signo más verde para agregar el camino.
inserte la descripción de la imagen aquí

2. Escribir la función .c

La idea específica es: solo necesita configurar un puerto IO como salida push-pull como Trig, y un puerto IO como entrada desplegable como Echo, porque cuando Echo recibe una señal de eco, se configurará desde un nivel bajo. nivel a un nivel alto, por lo que la configuración predeterminada de Echo es baja potencia. Distancia = tiempo de alto nivel * velocidad del sonido (340 M/S)/2;
primero use el software SysTick para retrasar y controlar Trig para enviar un nivel alto, luego espere la señal de eco, cuando Echo reciba la señal, iniciará el temporizador, pero nuestro programa es Los que se ejecutan en el temporizador usan el mismo temporizador TIM2, y el temporizador debe borrarse después de recibir la señal. Luego obtenga la duración del nivel, calcule la distancia y reinicie el temporizador nuevamente, e inicie el temporizador, la próxima interrupción del temporizador se puede activar normalmente.
(1) Escriba el
código de función del temporizador de la siguiente manera:

#include "debug.h"                  // Device header
//初始化定时器,采用基本定时器6,
void Timer_Init(void)
{
    
    
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM6, ENABLE);        //启用TIM3时钟

    TIM_InternalClockConfig(TIM6);                              //设置TIM3使用内部时钟

    TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;          //定义结构体,配置定时器
    TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1; //设置1分频(不分频)
    TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up; //设置计数模式为向上计数
    TIM_TimeBaseInitStructure.TIM_Period = 10 - 1;          //设置最大计数值,达到最大值触发更新事件,因为从0开始计数,所以计数10次是10-1,每10微秒触发一次
    TIM_TimeBaseInitStructure.TIM_Prescaler = 72 - 1;           //设置时钟预分频,72-1就是每 时钟频率(72Mhz)/72=1000000 个时钟周期计数器加1,每1微秒+1
    TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0;        //重复计数器(高级定时器才有,所以设置0)
    TIM_TimeBaseInit(TIM6, &TIM_TimeBaseInitStructure);         //初始化TIM6定时器

    TIM_ClearFlag(TIM6, TIM_FLAG_Update);           //清除更新中断标志位
    TIM_ITConfig(TIM6, TIM_IT_Update, ENABLE);      //开启更新中断

    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);             //设置中断优先级分组

    NVIC_InitTypeDef NVIC_InitStructure;                        //定义结构体,配置中断优先级
    NVIC_InitStructure.NVIC_IRQChannel = TIM6_IRQn;             //指定中断通道
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;             //中断使能
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;   //设置抢占优先级
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;          //设置响应优先级
    NVIC_Init(&NVIC_InitStructure);                             // https://blog.zeruns.tech

    TIM_Cmd(TIM6, ENABLE);                          //开启定时器
}

/*
void TIM3_IRQHandler(void)          //更新中断函数
{
    if (TIM_GetITStatus(TIM3, TIM_IT_Update) == SET)        //获取TIM3定时器的更新中断标志位
    {

        TIM_ClearITPendingBit(TIM3, TIM_IT_Update);         //清除更新中断标志位
    }
}*/


#ifndef __TIMER_H
#define __TIMER_H

void Timer_Init(void);

#endif

(2) Escribir funciones de inicialización y rango de HC-SR04

#include "debug.h"
#include "stdio.h"
#include "ch32v30x.h"

#define Echo GPIO_Pin_10   //HC-SR04模块的Echo脚接GPIOD10
#define Trig GPIO_Pin_11    //HC-SR04模块的Trig脚接GPIOD11

uint64_t time=0;            //声明变量,用来计时
uint64_t time_end=0;        //声明变量,存储回波信号时间

void HC_SR04_Init(void)
{
    
      
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD,ENABLE);    //启用GPIOB的外设时钟
    GPIO_InitTypeDef GPIO_InitStructure;                    //定义结构体
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;        //设置GPIO口为推挽输出
    GPIO_InitStructure.GPIO_Pin = Trig;                     //设置GPIO口5
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;       //设置GPIO口速度50Mhz
    GPIO_Init(GPIOD,&GPIO_InitStructure);                   //初始化GPIOB

    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD;           //设置GPIO口为下拉输入模式
    GPIO_InitStructure.GPIO_Pin = Echo;                     //设置GPIO口6
    GPIO_Init(GPIOD,&GPIO_InitStructure);                   //初始化GPIOB
    GPIO_WriteBit(GPIOD,GPIO_Pin_10,0);                      //输出低电平,让回应信号先保持低电平状态
    Delay_Us(15); //延时15微秒
}

int16_t sonar_mm(void)                                  //测距并返回单位为毫米的距离结果
{
    
    
    uint32_t Distance,Distance_mm = 0;
    GPIO_WriteBit(GPIOB,Trig,1);                        //输出高电平
    Delay_Us(15);                                       //延时15微秒
    GPIO_WriteBit(GPIOB,Trig,0);                        //输出低电平
    while(GPIO_ReadInputDataBit(GPIOB,Echo)==0);        //等待低电平结束
    time=0;                                             //计时清零
    while(GPIO_ReadInputDataBit(GPIOB,Echo)==1);        //等待高电平结束
    time_end=time;                                      //记录结束时的时间
    if(time_end/100<38)                                 //判断是否小于38毫秒,大于38毫秒的就是超时,直接调到下面返回0
    {
    
    
        Distance=(time_end*346)/2;                      //计算距离,25°C空气中的音速为346m/s
        Distance_mm=Distance/100;                       //因为上面的time_end的单位是10微秒,所以要得出单位为毫米的距离结果,还得除以100
    }
    return Distance_mm;                                 //返回测距结果
}

float sonar(void)                                       //测距并返回单位为米的距离结果
{
    
    
    uint32_t Distance,Distance_mm = 0;
    float Distance_m=0;
    GPIO_WriteBit(GPIOB,Trig,1);                    //输出高电平
    Delay_Us(15);
    GPIO_WriteBit(GPIOB,Trig,0);                    //输出低电平
    while(GPIO_ReadInputDataBit(GPIOB,Echo)==0);
    time=0;
    while(GPIO_ReadInputDataBit(GPIOB,Echo)==1);
    time_end=time;
    if(time_end/100<38)
    {
    
    
        Distance=(time_end*346)/2;
        Distance_mm=Distance/100;
        Distance_m=Distance_mm/1000;
    }
    return Distance_m;
}

void TIM3_IRQHandler(void)          //更新中断函数,用来计时,每10微秒变量time加1
{
    
    
    if (TIM_GetITStatus(TIM3, TIM_IT_Update) == SET)        //获取TIM3定时器的更新中断标志位
    {
    
    
        time++;
        TIM_ClearITPendingBit(TIM3, TIM_IT_Update);         //清除更新中断标志位
    }
}

#ifndef __HCSR04_H
#define __HCSR04_H

void HC_SR04_Init(void);
int16_t sonar_mm(void);
float sonar(void);

#endif

(3) Escribiendo el programa principal
Lo que se debe realizar aquí es usar milímetros como unidad y usar el puerto serie para imprimir la distancia medida.

#include "debug.h"
#include "timer_6.h"
#include "HC-SR04.h"
/* Global typedef */

/* Global define */

/* Global Variable */


/*********************************************************************
 * @fn      main
 *
 * @brief   Main program.
 *
 * @return  none
 */
int main(void)
{
    
    
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
	SystemCoreClockUpdate();
	Delay_Init();
	USART_Printf_Init(115200);	


	Timer_Init();
	HC_SR04_Init();
	//printf( "ChipID:%08x\r\n", DBGMCU_GetCHIPID() );
	//printf("This is printf example\r\n");

	while(1)
    {
    
    
	float distance = sonar_mm();
	printf("distance:%f\r\n",distance);

	}
}

Resumir

Actualmente, debido a que el proyecto necesita usar un esquema de rango más complejo, este artículo solo brinda los ejemplos de aplicación más básicos al referirse a la biblioteca HC-SR04 de otros grandes nombres.

Supongo que te gusta

Origin blog.csdn.net/qq_53092944/article/details/130122806
Recomendado
Clasificación