STM32智能小车—跟随小车和摇头避障小车

一、STM32跟随小车

1. 红外壁障模块分析

原理和循迹是一样的,循迹红外观朝下,跟随朝前

2. 跟随小车的原理

  • 左边跟随模块能返回红外,输出低电平,右边不能返回,输出高电平,说明物体在左边,需要左转
  • 右边跟随模块能返回红外,输出低电平,左边不能返回,输出高电平,说明物体在右边,需要右转

3. 跟随小车开发和调试代码

硬件接线

  • B-1A -- PB0
  • B-1B -- PB1
  • A-1A -- PB2
  • A-1B -- PB10
  • 跟随模块(左) -- PB5
  • 跟随模块(右) -- PB6

代码示例:

#define LeftWheel_Value HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_5)
#define RightWheel_Value HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_6)
// main函数里
while (1)
{
    if(LeftWheel_Value == GPIO_PIN_RESET && RightWheel_Value == GPIO_PIN_RESET)
        goForward();
    if(LeftWheel_Value == GPIO_PIN_SET && RightWheel_Value == GPIO_PIN_RESET)
        goRight();
    if(LeftWheel_Value == GPIO_PIN_RESET && RightWheel_Value == GPIO_PIN_SET)
        goLeft();
    if(LeftWheel_Value == GPIO_PIN_SET && RightWheel_Value == GPIO_PIN_SET)
        stop();
}

二、STM32摇头避障小车

1. 超声波模块介绍

使用超声波模块,型号:HC-SR04

  • 怎么让它发送波 Trig ,给Trig端口至少10us的高电平
  • 怎么知道它开始发了 Echo信号,由低电平跳转到高电平,表示开始发送波
  • 怎么知道接收了返回波 Echo,由高电平跳转回低电平,表示波回来了
  • 怎么算时间 Echo引脚维持高电平的时间! 波发出去的那一下,开始启动定时器 波回来的拿一下,我们开始停止定时器,计算出中间经过多少时间
  • 怎么算距离 距离 = 速度 (340m/s)* 时间/2

时序图:

2. 舵机模块介绍

 1. 什么是舵机

如下图所示,最便宜的舵机sg90,常用三根或者四根接线,黄色为PWM信号控制 用处:垃圾桶项目开盖用、智能小车的全比例转向、摄像头云台、机械臂等 常见的有0-90°、0-180°、0-360°

STM32智能小车—跟随小车和摇头避障小车_第1张图片

2. 怎么控制舵机

向黄色信号线“灌入”PWM信号

PWM波的频率不能太高,大约50HZ,即周期=1/频率=1/50=0.02s,20ms左右

确定周期/频率:

STM32智能小车—跟随小车和摇头避障小车_第2张图片

如果周期为20ms,则 PSC=7199,ARR=199

角度控制

0.5ms-------------0度; 2.5% 对应函数中CCRx为5

1.0ms------------45度; 5.0% 对应函数中CCRx为10

1.5ms------------90度; 7.5% 对应函数中CCRx为15

2.0ms-----------135度; 10.0% 对应函数中CCRx为20

2.5ms-----------180度; 12.5% 对应函数中CCRx为25STM32智能小车—跟随小车和摇头避障小车_第3张图片

3. 摇头避障小车开发和调试代码

硬件接线

  • sg90 -- PB9

cubeMX配置STM32智能小车—跟随小车和摇头避障小车_第4张图片

代码实现

sg90.c

#include "sg90.h"
#include "gpio.h"
#include "tim.h"
void initSG90(void)
{
    HAL_TIM_PWM_Start(&htim4,TIM_CHANNEL_4); //启动定时器4
    __HAL_TIM_SetCompare(&htim4, TIM_CHANNEL_4, 17); //将舵机置为90度
}
void sgMiddle(void)
{
    __HAL_TIM_SetCompare(&htim4, TIM_CHANNEL_4, 17); //将舵机置为90度
}
void sgRight(void)
{
    __HAL_TIM_SetCompare(&htim4, TIM_CHANNEL_4, 5); //将舵机置为0度
}
void sgLeft(void)
{
    __HAL_TIM_SetCompare(&htim4, TIM_CHANNEL_4, 25); //将舵机置为180度
}

sg90.h

#ifndef __SG90_H__
#define __SG90_H__

void initSG90(void);
void sgMiddle(void);
void sgRight(void);
void sgLeft(void);

#endif

main.c

initSG90();
HAL_Delay(1000);

while (1)
{
    sgLeft();
    HAL_Delay(1000);
    sgMiddle();
    HAL_Delay(1000);
    sgRight();
    HAL_Delay(1000);
    sgMiddle();
    HAL_Delay(1000);
}

封装超声波传感器

超声波模块接线:

  • Trig       --    PB7
  • Echo     -- PB8

cubeMX配置

STM32智能小车—跟随小车和摇头避障小车_第5张图片STM32智能小车—跟随小车和摇头避障小车_第6张图片

代码实现

sr04.c

#include "sr04.h"
#include "gpio.h"
#include "tim.h"

//使用TIM2来做us级延时函数
void TIM2_Delay_us(uint16_t n_us)
{
    /* 使能定时器2计数 */
    __HAL_TIM_ENABLE(&htim2);
    __HAL_TIM_SetCounter(&htim2, 0);
    while(__HAL_TIM_GetCounter(&htim2) < ((1 * n_us)-1) );
    /* 关闭定时器2计数 */
    __HAL_TIM_DISABLE(&htim2);
}

double get_distance(void)
{
    int cnt=0;
    //1. Trig ,给Trig端口至少10us的高电平
    HAL_GPIO_WritePin(GPIOB, GPIO_PIN_7, GPIO_PIN_SET);//拉高
    TIM2_Delay_us(20);
    HAL_GPIO_WritePin(GPIOB, GPIO_PIN_7, GPIO_PIN_RESET);//拉低

    //2. echo由低电平跳转到高电平,表示开始发送波
    //波发出去的那一下,开始启动定时器
    while(HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_8) == GPIO_PIN_RESET);//等待输入电平拉高
    HAL_TIM_Base_Start(&htim2);
    __HAL_TIM_SetCounter(&htim2,0);

    //3. 由高电平跳转回低电平,表示波回来了
    while(HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_8) == GPIO_PIN_SET);//等待输入电平变低
    //波回来的那一下,我们开始停止定时器
    HAL_TIM_Base_Stop(&htim2);

    //4. 计算出中间经过多少时间
    cnt = __HAL_TIM_GetCounter(&htim2);

    //5. 距离 = 速度 (340m/s)* 时间/2(计数1次表示1us)
    return (cnt*340/2*0.000001*100); //单位:cm
}

sr04.h

#ifndef __SR04_H__
#define __SR04_H__

double get_distance(void);

#endif

main.c

while (1)
{
    if(dir != MIDDLE){
        sgMiddle();
        dir = MIDDLE;
        HAL_Delay(300);
    }
    disMiddle = get_distance();

    if(disMiddle > 35){
    //前进
    }
    else
    {
        //停止
        //测左边距离
        sgLeft();

        HAL_Delay(300);
        disLeft = get_distance();

        sgMiddle();
        HAL_Delay(300);

        sgRight();
        dir = RIGHT;
        HAL_Delay(300);
        disRight = get_distance();
    }
}

封装电机驱动

代码实现:

while (1)
{
    if(dir != MIDDLE){
        sgMiddle();
        dir = MIDDLE;
        HAL_Delay(300);
    }
    disMiddle = get_distance();

    if(disMiddle > 35){
        //前进
        goForward();
    }else if(disMiddle < 10){
        goBack();
    }else
    {
        //停止
        stop();
        //测左边距离
        sgLeft();
        HAL_Delay(300);
        disLeft = get_distance();

        sgMiddle();
        HAL_Delay(300);

        sgRight();
        dir = RIGHT;
        HAL_Delay(300);
        disRight = get_distance();

        if(disLeft < disRight){
            goRight();
            HAL_Delay(150);
            stop();
        }
        if(disRight < disLeft){
            goLeft();
            HAL_Delay(150);
        stop();
        }
    }
    HAL_Delay(50);
}

你可能感兴趣的:(51跟32单片机,stm32,嵌入式硬件,单片机)