51智能循迹车(二)

在上面一节中,我们介绍了小车的避障逻辑和实现代码,那么这一节中我们将继续来学习介绍小车的避障系统。

一、硬件选型

避障系统功能实现是基于超声波测距模块来实现的,型号为HC-SR04,模块的芯片手册链接:hc-sr04超声波模块icon-default.png?t=O83Ahttps://akizukidenshi.com/goodsaffix/hc-sr04_v20.pdf#:~:text=2020%20%E6%AC%BE%20H

超声波测距模块共有两个GPIO引脚:TRIG和ECHO,它们的具体工作模式如下:

经过 我们实验计算,当我们在循环中插入三个nop()时, 一个循环的延时大概是11.8us,此时的距离大概为2mm。

二、避障代码设计与实现 

Int_Range.h

#ifndef __RANGE_H__
#define __RANGE_H__
#include <INTRINS.H>
#include "Dri_GPIO.h"
#include "Dri_Timer0.h"
#include "Util.h"

#define RANGE_MS 100 // 超声波探测周期

/**
 * @brief 初始化超声波模块
 * 
 */
void Int_Range_Init();

/**
 * @brief 获取超声波测距距离
 *
 * @return 距离,单位为mm
 */
u16 Int_Range_GetRange();

#endif

 Int_Range.c

#include "Int_Range.h"

#define RANGE_INTERVAL 100

// 标志位:该标志位为距离上次测距的ms时间间隔
static u8 s_get_range_flag;

static u16 s_range;

static void Int_Range_TimerCallback()
{
    if (s_get_range_flag < RANGE_INTERVAL)
    {
        s_get_range_flag++;
    }
}

void Int_Range_Init()
{
    s_get_range_flag = RANGE_INTERVAL;

    TRIG = 0;
    ECHO = 1;
    Dri_Timer0_RegisterCallback(Int_Range_TimerCallback);
}

u16 Int_Range_GetRange()
{
    u8 count;
    if (s_get_range_flag == RANGE_INTERVAL)
    {
        s_get_range_flag = 0;
        // 测距
        // TRIG引脚发一个10us的脉冲
        TRIG = 1;
        Delay10us();
        TRIG = 0;

                count = 0;
        while (!ECHO)
        {
            count++;
            Delay10us();
            if (count >= 25)
            {
                return s_range;
            }
        }
        EA      = 0;
        s_range = 0;
        // 说明ECHO引脚拉高了
        while (s_range < 1000 && ECHO)
        {
            _nop_();
            _nop_();
            P15 = ~P15;
            s_range++;
        }
        EA = 1;

        // 返回最终结果
        s_range *= 2;
    }

    return s_range;
    // 返回上一次结果
}

三、测试

在Main.c文件中写入以下内容

#include "Int_LCD1602.h"
#include "Int_Range.h"
#include "Dri_Timer0.h"
#include <STDIO.H>

void main()
{
    // 定义变量,用于接收测距结果
    u16 distance;

    // 定义字符串,用于在LCD展示测距结果
    u8 str[17];

    // 初始化定时器
    Dri_Timer0_Init();

    // 打开中断总开关
    EA = 1;

    // 初始化LCD1602
    Int_LCD1602_Init();

    // 初始化超声波测距模块
    Int_Range_Init();

    while (1)
    {
        // 调用方法测距并记录结果
        distance = Int_Range_GetRange();

        // 为所有distance末尾添加空格,覆盖之前的测距结果
        sprintf(str, "%d    ", distance);

        // 通过LCD1602的液晶屏显示测距结果
        Int_LCD1602_ShowStr(0, 0, str);
    }
}

四、编译烧录

打开烧录软件,相关配置如下

我选用的单片机引脚图如下,如果你是自己定义,需在程序中更改为你自己定义的引脚即可 。

 这里要注意:ALE/P4.5引脚为复用引脚,既可作为GPIO引脚使用,又可作为控制信号引脚使用(ALE即Address Latch Enable,用于使能或禁用地址锁存器)。此处我将其作为GPIO引脚使用,因此,在烧录时要勾选“ALE脚用作P4.5口”。

五、效果展示

至此,就完成了智能小车的循迹和避障功能了,大家赶快动手学习起来吧! 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值