0


2022电赛小车开源代码讲解开源

2022电赛小车我认为有主要是几个主要的问题,我将分这几个部分来讲解

2022电赛,双车稳定行驶_哔哩哔哩_bilibili

一、循迹

循迹我们组用的是五路灰度,灰度跟红外对管的作用是差不多的,在淘宝上就能买到,检测到黑线就输入高电平,那么就需要在单片机上捕获到这个IO口的电平就可以知道哪个灰度检测到了黑线。

步骤很简单 初始化IO口->捕获IO口 代码如下:

#ifndef __GRAY_H_
#define __GRAY_H_
//主函数定义
#include "sys.h"
void GRAY_Init(void);
int Gray_values(void);

#endif
#include "gray.h"
void GRAY_Init(void)//初始化IO口
{
     GPIO_InitTypeDef  GPIO_InitStructure;
     RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);     //使能PA,PD端口时钟
        
     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;
     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;                      //上拉输入
     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;          //IO口速度为50MHz
     GPIO_Init(GPIOA, &GPIO_InitStructure);                //根据设定参数初始化
}

u8 Gray_values()//得到IO口的值并返回
{
   static u8 Gray_Value;
   Gray_Value=GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_4);//获得GPIO的值
   return Gray_Value;
}

可以根据自己的需求进行IO口的配置,最后用一个数组来放这几个IO值。

二、蓝牙通信,双车数据传输

首先配对两个小车的蓝牙,将一个蓝牙设置为主一个为从机模式,具体配对方法点击这里。然后就是蓝牙初始化了。初始化比较简单到处都能找得到源码。

#ifndef __USART2_H
#define __USART2_H
#include "sys.h"

#define USART2_MAX_RECV_LEN        37                    //最大接收缓存字节数
#define USART2_MAX_SEND_LEN        3                    //最大发送缓存字节数
#define USART2_RX_EN             1                    //0,不接收;1,接收.

#define    DATA1            12550
#define    DATA2            12806
#define    DATA3            13062

extern u8  USART2_RX_BUF[USART2_MAX_RECV_LEN];         //接收缓冲,最大USART3_MAX_RECV_LEN字节
extern u8  USART2_TX_BUF[USART2_MAX_SEND_LEN];         //发送缓冲,最大USART3_MAX_SEND_LEN字节
extern vu16 USART2_RX_STA;                           //接收数据状态
void dataSend(u8 *sendArry);
void usart2_init(u32 bound);                //串口2初始化
void u2_printf(char* fmt, ...);
#endif
#include "delay.h"
#include "usart2.h"
#include "stdarg.h"          
#include "usart.h"
#include "timer.h"
#include "stdio.h"          
#include "string.h"    

//串口接收缓存区
u8 USART2_RX_BUF[USART2_MAX_RECV_LEN];                 //接收缓冲,最大USART3_MAX_RECV_LEN个字节.
u8 USART2_TX_BUF    [USART2_MAX_SEND_LEN];        //发送缓冲,最大USART3_MAX_SEND_LEN字节

u16 uart2rec;
u8 END_FLAG1;

u8    RECEIVE_FLAG = 0; 

//初始化IO 串口3
//pclk1:PCLK1时钟频率(Mhz)
//bound:波特率
void usart2_init(u32 bound)
{

    NVIC_InitTypeDef NVIC_InitStructure;
    GPIO_InitTypeDef GPIO_InitStructure;
    USART_InitTypeDef USART_InitStructure;
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);    // GPIOB时钟
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE); //串口3时钟使能
    USART_DeInit(USART2);  //复位串口3
    //USART2_TX   PA2
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2; //PB10
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;    //复用推挽输出
    GPIO_Init(GPIOA, &GPIO_InitStructure); //初始化PB10
    //USART2_RX      PA3
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//浮空输入
    GPIO_Init(GPIOA, &GPIO_InitStructure);  //初始化PB11
     //设置中断优先级
    NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 3 ; //抢占优先级3
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;        //子优先级3
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;            //IRQ通道使能
    NVIC_Init(&NVIC_InitStructure);    //根据指定的参数初始化VIC寄存器
    
    USART_InitStructure.USART_BaudRate = bound;//波特率一般设置为9600;
    USART_InitStructure.USART_WordLength = USART_WordLength_8b;//字长为8位数据格式
    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(USART2, &USART_InitStructure); //初始化串口    
    //使能接收中断
    USART_ITConfig(USART2, USART_IT_RXNE, ENABLE);//开启中断
        USART_Cmd(USART2, ENABLE);                    //使能串口
 
}

void dataSend(u8 *sendArry) {//发送数据函数,注意这里发的是一个数组,3位数组,第一个与第三个用于判断
    int i;
   for(i=0;i<3;i++)           
   {
       USART_SendData(USART2,sendArry[i]);
     while((USART2->SR&0x40)==0);
    }

}

void USART2_IRQHandler(void)//接收数据中断
{
static  u8 i = 0;
    u8 res;
    if(USART_GetITStatus(USART2, USART_IT_RXNE) != RESET)
    {
        
      res = USART_ReceiveData(USART2);
            if(res == 0x01 )//帧头判断
            {
                i = 0;
            }
            USART2_RX_BUF[i] = res;//将接收到的数据放在数组中
            i++;
            if(i == 2 && USART2_RX_BUF[2] == 0x06)//帧尾判断
            {
                uart2rec = (u16)((u16)USART2_RX_BUF[1]<<8 | (u16)USART2_RX_BUF[2]);//将接收到的数据进行移位操作
        
         }
    }

}

//串口2,printf 函数
//确保一次发送数据不超过USART3_MAX_SEND_LEN字节
void u2_printf(char* fmt, ...)
{
    u16 i, j;
    va_list ap;
    va_start(ap, fmt);
    vsprintf((char*)USART2_TX_BUF, fmt, ap);
    va_end(ap);
    i = strlen((const char*)USART2_TX_BUF);        //此次发送数据的长度

    for(j = 0; j < i; j++)                            //循环发送数据
    {
        USART_SendData(USART2, USART2_TX_BUF[j]);

        while(USART_GetFlagStatus(USART2, USART_FLAG_TC) == RESET); //循环发送,直到发送完毕

       

    }
}

主要是用好发送函数和接收中断,移位操作是将后两位16进制转换为10进制,

列:发送数组data[3]={0x01,0x31,0x06} 则0x31,0x06->12550 uart2rec=12550

通过改变中间的值改变uartrec的值,判断走哪个问。

三、起始路口的识别

根据灰度的的亮灭则可判断,经过停车位置时,中间三个灯灭,则让其做出指令。

四、分叉路口的识别

在这里有很多种方法,我们用的方法是根据起始的三个灯灭来判断,如果三个灯灭了,若走外圈则利用延时向前冲一段,还有可以利用最外边的灰度进行判断。说起来很抽象,还是直接上代码吧。

五、源码

用了很多标志位导致阅读感很不舒服。大家见谅,主要这代码是一个月前的了我也不想再去改了,主要给大家提供一个思路,欢迎评论区讨论学习。

链接: https://pan.baidu.com/s/1X8O7z_afGnofAl8y89iRAQ?pwd=1234 提取码: 1234

#include "test.h"
#include "control.h"
#include "gray.h"
#include "tb6612.h"
#include "led.h"
#include "usart2.h"
#include "test.h"
#include "encoder.h"
u8 TRACE_FLAG = 1,STOP_FLAG ,START_FLAG = 1;

u8 send_data5[3] = {0x01,0x35,0x06};//13574
u8 send_data6[3] = {0x01,0x36,0x06};//13574
u8 Instruction_Flag;
int cross_num;
void test1()
{
    Basic_Speed = 2600;                //2400   0.3
    Gray_values();
    Encoder4();
    if(START_FLAG)
    {
        trace(Basic_Speed);
        if(TURN_FLAG == 1)
        {
            Direction(10,10,0,1);            //0  外圈
        }
        if(Gray_Number >= 3  && Gray_Number < 5 && TURN_FLAG == 0)
        {
            TURN_FLAG = 1;
            Qingling = 0;
        }
        if(cross_num == 2)
        {
            START_FLAG = 0;
            END_FLAG = 1;
        }
    }
            //停止行进标志位
    if(END_FLAG == 1)
    {
        LED0 = 1;
        STOP;    
        dataSend(send_data5);
        if(delay(40))
        {
            LED0 = 0;
            END_FLAG = 0;
            START_FLAG = 0;
            TRACE_FLAG = 0;
        }
    }
}

void test2()
{
    Basic_Speed = 3300;                //3100   0.5    
    Gray_values();
    Encoder4();
    if(START_FLAG)
    {
        trace(Basic_Speed);
        if(TURN_FLAG == 1)
        {
            Direction(10,10,0,1);
        }
        if(Gray_Number >= 3 && Gray_Number < 5 && TURN_FLAG == 0 )
        {
            TURN_FLAG = 1;
            Qingling = 0;
        }

        if(cross_num == 3)
        {
            START_FLAG = 0;
            END_FLAG = 1;
        }
    }
    
    if(END_FLAG == 1)/结束
    {
        dataSend(send_data5);
        LED0 = 1;
        BACKWORD;    
        PWM_L = 0;
        PWM_R = 0;
        if(delay(30))
        {
            START_FLAG = 0;
            LED0 = 0;
            END_FLAG = 0;
            DELAY_FLAG = 1;
        }
    }
}

void test3()
{
    Basic_Speed = 2600;
    Gray_values();
    Encoder4();
    if(START_FLAG)
    {
        trace(Basic_Speed);
        if(TURN_FLAG == 1)
        {
            switch(cross_num)
            {
                case 0:
                             Direction(10,10,0,1);     break;
                case 1:
                             Direction(10,10,0,1);     break;
                case 2:
                             Direction(10,10,0,1);     break;
                case 3:
                             Direction(10,10,1,1);     
                                LED1 = 1;                                 break;
                case 4:
                             Direction(10,10,1,1);     break;
            }
        }
        if(Gray_Number >= 3 && Gray_Number < 5 && TURN_FLAG == 0)
        {
            TURN_FLAG = 1;
            Qingling = 0;
        }
        if(cross_num == 4)
        {
            START_FLAG = 0;
            END_FLAG = 1;
        }
    }
    if(END_FLAG == 1)/结束
    {
        dataSend(send_data5);
        LED0 = 1;
        BACKWORD;    
        PWM_L = 0;
        PWM_R = 0;
        if(delay(30))
        {
            START_FLAG = 0;
            LED0 = 0;
            END_FLAG = 0;
            DELAY_FLAG = 0;
        }
    }
}

void test4()
{
    Basic_Speed = 4000;
    Gray_values();
    Encoder4();
    if(START_FLAG)
    {
        if(Instruction_Flag == 0  && Gray_Number >= 3 && TURN_FLAG == 0)
        {
            TURN_FLAG = 1;
        }
        if(TURN_FLAG == 1)
        {
            if(delay(20))
            {
                Instruction_Flag  = 1;
                TURN_FLAG = 2;
                DELAY_FLAG = 0;
            }
        }

        if(Instruction_Flag  == 1 && TURN_FLAG == 2 && Gray_Number >= 3)
        {
            TURN_FLAG = 3;
        }
        if(TURN_FLAG == 3)
        {
                BACKWORD;
                PWM_L = 0;
                PWM_R = 0;
                Instruction_Flag  = 2;
                if(delay(150))
                {
                    TURN_FLAG = 4;
                    Instruction_Flag  = 3;
                    FORWARD;
                    DELAY_FLAG = 0;
                    TIM_SetCounter(TIM2,0);
                }    
        }
            
        if(Instruction_Flag == 3 && Gray_Number >= 3 && Read_Encoder(2) > 1000)
        {
            START_FLAG = 0;
            END_FLAG = 1;
        }
        if(Instruction_Flag != 2)
        {
            trace(Basic_Speed);
        }
    }

    if(END_FLAG)
    {
        START_FLAG = 0;
        BACKWORD;
        PWM_L = 0;
        PWM_R = 0;    
        LED0 = 1;
        dataSend(send_data5);
        if(delay(50))
        {
            LED0 = 0;
            END_FLAG = 0;
            START_FLAG = 0;
            TRACE_FLAG = 0;
            DELAY_FLAG = 0;
        }
    }
    
}
    

本文转载自: https://blog.csdn.net/qq_62392385/article/details/130000308
版权归原作者 点灯大侠 所有, 如有侵权,请联系我们删除。

“2022电赛小车开源代码讲解开源”的评论:

还没有评论