大一新生の作品:简单的寻迹小车

(纯萌新,学习单片机半年了,这是寒假回家的作品,师从江科大,写博客纪录我实现后的经验)(比较粗略)

前言

学习寻迹小车,最最重要的莫过于通过反射式红外传感器读取小车的状态并让小车做出相应的反应以达到快速调整姿态。我的循迹小车用的是三个红外传感器,并不是很智能,但是在速度和过不同种类的弯道都可圈可点。

我大致将学习寻迹小车的思路分为3方面:1.小车本身能不能动 2.如何检测小车此时的状态 3.什么状态给小车的轮子什么速度。

本文默认小车可以动了,所以下文主要针对什么赛道赋什么速度。

赛道如图

赛道部分

赛道一般分为:

直接连接:直线赛道,145度左右直赛道,120度左右赛直道,直角直赛道,锐角直赛道。

圆滑连接:半径大的半圆弧、1/4圆弧赛道,半径小的半圆弧、1/4圆弧赛道,和椭圆弧赛道。

难度:

直接连接中能够攻克120度左右,圆滑连接能够将半径大的圆弧赛道和椭圆赛道攻克便是初级目标。

攻克直角直赛道和半径小的圆弧赛道是附加目标。

锐角直赛道我用我的三个红外反射模块暂时没有思路,无法实现。(四个可以实现,但是本文主要针对3个)

解决思路:

3个红外模块主要可以分为7种情况。(我的三个模块挨得很近,且中间的模块比两边要突出一些(方便过直角弯))

为了方便我将3个红外模块命名为L(左),I(中),R(右)

从最简单的三种说起:只有L,I,R其中一个检测到赛道。

只有L,则全力左转,只有I,则全力直行,只有R,则全力右转。

其次是两种微调:L和I,I和R中一对检测到赛道。

该情况与上面相差不大,只是转弯力度减小即可。

最后是两种特殊情况:全检测到或全没检测到。

这两种情况大多为硬件太弱的问题,所以当出现这两种情况时,建议让其继续执行之前的命令,比如左转,但是转的时候有段时间三个都没检测到,那么继续执行之前的命令,继续左转直到检测到赛道。用该方式可以很好的过部分急转弯。

特殊问题:直角直赛道

直角直赛道时如果三个模块平行,那么会同时检测不到,转弯力度不够,所以我将中间模块稍微突出,在直角赛道最后会有一小段时间只有左右两个模块能够检测到赛道,此时全力转弯即可过弯。

代码部分

代码没什么可以说的,简单的if语句。思路有了,其实代码也不是很重要。

main函数:

#include "stm32f10x.h"
#include "Delay.h"
#include "Motor.h"
#include "XunJi.h"


int main(void)                //电机范围(速度)-100~100        
{
    int State;
    Motor_Init();
    XunJi_Init();
    
    while(1)
    {
        State=Get_XunJi();
        if(State==1)        //左轮后转,右轮前转,即原地左转
        {
            Motor_L_SetSpeed(-50);
            Motor_R_SetSpeed(50);
        }
        if(State==2)        //微调
        {
            Motor_L_SetSpeed(25);
            Motor_R_SetSpeed(50);
        }
        if(State==3)
        {
            Motor_L_SetSpeed(50);        //速度可以自行调整
            Motor_R_SetSpeed(50);
        }
        if(State==4)
        {
            Motor_L_SetSpeed(50);
            Motor_R_SetSpeed(25);
        }
        if(State==5)
        {
            Motor_L_SetSpeed(50);
            Motor_R_SetSpeed(-50);
        }
    }    
}

寻迹函数:

#include "stm32f10x.h"                  // Device header

void XunJi_Init(void)        //从A7到B1分别为右,中,左
{
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
    
    GPIO_InitTypeDef GPIO_InitStructure;            //结构体
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1 | GPIO_Pin_0;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOB, &GPIO_InitStructure);        //GPIOB的初始配置
    
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOA, &GPIO_InitStructure);        //GPIOA的初始配置
}

uint16_t Get_XunJi(void)
{
    static int A;            //A是状态
    if(GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_0)==1)    //中间检测到了
    {
        if(GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_1)==1&&GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_7)==1)//全检测到了,保持状态
        {
            return(A);
        }
        else if(GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_1)==1)    //左边检测到了
        {
            A=2;
            return(2);
        }
        else if(GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_7)==1)    //右边检测到了
        {
            A=4;
            return(4);
        }
        else        //只有中间
        {
            A=3;
            return(3);
        }
    }
    else if(GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_1)==1)    //只有左边检测到了
    {
        A=1;
        return(1);
    }
    else if(GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_7)==1)    //只有右边检测到了
    {
        A=5;
        return(5);
    }
    else         //全没检测到,继续之前的状态
    {
        return(A);
    }
}

电机函数:

#include "stm32f10x.h"                  // Device header
#include "PWM.h"

void Motor_Init(void)
{
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
    
    GPIO_InitTypeDef GPIO_InitStructure;                    //方向GPIO口初始化
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_8;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOA, &GPIO_InitStructure);
    
    PWM_Init();        //初始化PWM
    
}

void Motor_TwoSetSpeed(int8_t Speed)
{
    if(Speed>=0)
    {
        PWM_SetCompare1(Speed);    
        PWM_SetCompare2(Speed);
    }
    if(Speed<=0)
    {
        PWM_SetCompare1(-Speed);
        PWM_SetCompare2(-Speed);
    }
}
void Motor_L_SetSpeed(int8_t Speed)        //左轮控制
{
    if(Speed>=0)
    {    
        GPIO_SetBits(GPIOA,GPIO_Pin_4);
        GPIO_ResetBits(GPIOA,GPIO_Pin_6);
        PWM_SetCompare1(Speed);
    }
    if(Speed<=0)
    {
        GPIO_SetBits(GPIOA,GPIO_Pin_6);
        GPIO_ResetBits(GPIOA,GPIO_Pin_4);
        PWM_SetCompare1(-Speed);
    }
}
void Motor_R_SetSpeed(int8_t Speed)        //右轮控制
{
    if(Speed>=0)
    {    
        GPIO_SetBits(GPIOA,GPIO_Pin_5);
        GPIO_ResetBits(GPIOA,GPIO_Pin_8);
        PWM_SetCompare2(Speed);
    }
    if(Speed<=0)
    {
        GPIO_SetBits(GPIOA,GPIO_Pin_8);
        GPIO_ResetBits(GPIOA,GPIO_Pin_5);
        PWM_SetCompare2(-Speed);
    }
}
void Motor_Stop(void)
{
    PWM_SetCompare1(0);
    PWM_SetCompare2(0);
}
void Motor_Retreat()
{
    GPIO_SetBits(GPIOA,GPIO_Pin_8);
    GPIO_SetBits(GPIOA,GPIO_Pin_6);
    GPIO_ResetBits(GPIOA,GPIO_Pin_5);
    GPIO_ResetBits(GPIOA,GPIO_Pin_4);
}
void Motor_Go()
{
    GPIO_SetBits(GPIOA,GPIO_Pin_4);
    GPIO_SetBits(GPIOA,GPIO_Pin_5);
    GPIO_ResetBits(GPIOA,GPIO_Pin_6);
    GPIO_ResetBits(GPIOA,GPIO_Pin_8);
}

总结:

多调试,多实验,多总结。

  • 24
    点赞
  • 166
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 12
    评论
### 回答1: 简单stm51寻迹小车所用材料主要包括以下几项: 1. STM51开发板:作为控制核心,使用STM51系列单片机,具有丰富的外设模块和强大的计算能力,用于控制小车的运动和判断线路状态。 2. 电机驱动模块:用于控制小车的驱动电机,通常采用直流电机驱动模块,可以实现正反转和速度调节功能。 3. 寻迹传感器:用于感知线路状态,通常采用红外线传感器,能够检测到黑线与白地的反差,从而判断小车当前位置。 4. 轮子和底盘:用于支撑和运动,通常采用四个小车轮子和一个底盘结构,可以使小车在地面上平稳行驶。 5. 电源供应模块:用于为整个系统提供电源,通常采用锂电池或者电池盒,确保小车能够长时间运行。 6. 连接线和焊接工具:用于连接各个部件,并进行必要的焊接和固定。 7. 软件开发工具:需要使用相关的编程软件,如KEIL C等,进行程序编写和烧录调试,以实现小车的控制功能。 除了以上主要材料,还可以根据实际需求进行扩展和升级,如增加避障模块、蓝牙通信模块等,以增加小车的功能和交互性。总之,简单stm51寻迹小车所用材料主要是以STM51开发板、电机驱动模块、寻迹传感器、轮子和底盘、电源供应模块等为主要组成部分,通过软件开发工具进行编程控制实现。 ### 回答2: 简单stm51寻迹小车所用的材料主要包括以下几种: 1. stm51单片机:stm51单片机是一种高性能、低功耗的集成电路芯片,具有强大的处理能力和丰富的外设资源,适用于嵌入式系统的开发。在寻迹小车中,stm51单片机可以作为控制中心,接收并处理传感器的信号,控制小车的行走方向。 2. 红外线传感器:红外线传感器是一种能够检测和接收红外线信号的设备,常用于避障和寻迹的应用中。在寻迹小车中,红外线传感器可以用来检测地面上的黑线,从而控制小车的行走方向。 3. 电机驱动模块:电机驱动模块是一种用于控制电机运动的电路模块,能够提供足够的电流和电压给电机,控制电机的转速和方向。在寻迹小车中,电机驱动模块可以连接到stm51单片机上,通过控制信号来控制小车的左右轮电机。 4. 电源模块:电源模块为寻迹小车提供工作电压,一般可以选择使用锂电池或者干电池。合适的电源模块可以为寻迹小车提供稳定的电源供应,保证其正常运行。 除了上述主要材料外,还需要一些连接线、面包板等辅助材料,以及相应的开发软件和编程环境来进行stm51单片机程序编写和调试。同时,如果需要增加其他功能模块如蓝牙通信模块、超声波传感器等,还需要相应的硬件设备及其附属材料。总的来说,简单的stm51寻迹小车所用的材料主要以上述几种为主,开发时还需要根据具体需求做适当调整。 ### 回答3: 简单STM51寻迹小车的材料主要包括以下几种: 1. STM32F103C8T6开发板:作为主控芯片,具有强大的计算和控制能力。 2. L298N双全桥驱动模块:用于控制小车的电机,能够提供足够的电流和电压给电机驱动。 3. 红外传感器:用于接收小车移动过程中所遇到的黑线信号,实现自动寻迹功能。 4. 电机:小车的驱动部件,将电能转化为机械能,使小车能够运动。 5. 电池:为小车提供电源,常用的是锂电池,具有较大的电容量和较低的自放电率。 6. 电池盒和电池座:用来固定电池,防止意外摔落和短路等情况发生。 7. 悬挂装置:将电机和车体连接起来,使电机能够带动整个小车运动。 8. 轮子:用于支撑和平稳地行驶,常常采用橡胶材质,具有较好的抓地力。 9. 连接线和杜邦线:用于连接各个模块和元件,保证它们之间的正常通信和工作。 10. 车体结构:通常采用固定和支撑电路板和元件的结构,在材料方面可以选择塑料、金属等。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 12
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

西南胶带の池上桜

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值