基于MSP432P401R跟随小车【2022年电赛C题】

news2024/10/7 14:24:20

文章目录

  • 一、赛前准备
    • 1. 硬件清单
    • 2. 工程环境
  • 二、赛题思考
  • 三、软件设计
    • 1. 路程、时间、速度计算
    • 2. 距离测量
    • 3. 双机通信
    • 4. 红外循迹
  • 四、技术交流


一、赛前准备

1. 硬件清单

  • 主控板: MSP432P401R
  • 测距模块: GY56
  • 数据显示: OLED
  • 电机: TT霍尔电机
  • 电池: 18650锂电池
  • 通信: HC-05
  • 巡线: 单路红外
  • 警报: 蜂鸣器
  • 电机驱动: TB6612
  • 其他: 铜柱、螺丝螺母、开关、面包板等。
    在这里插入图片描述

2. 工程环境

  • 编译器: Keil
  • 编程方式: 库函数

二、赛题思考

流程简述:该题简单描述为俩辆车一起围着赛道跑,最后停在终点时俩车距离在20cm左右且速度也要求在一定范围内。

对于该题,我介绍一下我的几种方法:
其中最重要的是巡好线,其次是通信,最后是准确判断好俩车距离。

    1. 巡线
      (1)视觉巡线(OpenMV、K210、CCD等都可)
      (2)传感器(灰度、红外)
      (3)路径规划(路程计算)
    1. 通信
      (1)蓝牙
      (2)LORA
      (3)Zigbee
      (4)WiFi
    1. 测距
      (1)超声波
      (2)红外
      (3)激光
      (4)视觉
      (5)路程

三、软件设计

有设计俩种方案,闭环和开环。
这里我以开环为例展开介绍。
在这里插入图片描述

1. 路程、时间、速度计算

通过在一定时间内捕获电机的脉冲数进行计算。例如:我的电机减速比为1:45(轮子转动一圈电机转动45圈), 电机单相转一圈输出13个脉冲,车轮直径为65mm,这些参数在购买的产品中都有相关介绍,大家自查即可。好,现在得到以上这些信息后怎么计算路程呢,这里我以单相双边沿触发为例进行计算,首先算出车轮的周长:周长Z=2Pir=Pid=3.14159260.065 (单位m),再计算轮子转动一圈电机输出的脉冲数CNT=13245=1170个脉冲,然后得出每个脉冲可以跑多少m,即M=Z/CNT;最后在一定时间内将捕获得到的脉冲数乘以每个脉冲跑的路程=该段时间内跑的路程,即S=CNT*M,V=S/T。

(1)定时器初始化

void TimA1_Int_Init(uint16_t ccr0, uint16_t psc)
{
    // 1.增计数模式初始化
    Timer_A_UpModeConfig upConfig;
    upConfig.clockSource = TIMER_A_CLOCKSOURCE_SMCLK;                                      //时钟源
    upConfig.clockSourceDivider = psc;                                                     //时钟分频 范围1-64
    upConfig.timerPeriod = ccr0;                                                           //自动重装载值(ARR)
    upConfig.timerInterruptEnable_TAIE = TIMER_A_TAIE_INTERRUPT_DISABLE;                   //禁用 tim溢出中断
    upConfig.captureCompareInterruptEnable_CCR0_CCIE = TIMER_A_CCIE_CCR0_INTERRUPT_ENABLE; //启用 ccr0更新中断
    upConfig.timerClear = TIMER_A_DO_CLEAR;                                                // Clear value

    // 2.初始化定时器A
    MAP_Timer_A_configureUpMode(TIMER_A1_BASE, &upConfig);

    // 3.选择模式开始计数
    MAP_Timer_A_startCounter(TIMER_A1_BASE, TIMER_A_UP_MODE);

    // 4.清除比较中断标志位
    MAP_Timer_A_clearCaptureCompareInterrupt(TIMER_A1_BASE, TIMER_A_CAPTURECOMPARE_REGISTER_0);

    // 5.开启串口端口中断
    MAP_Interrupt_enableInterrupt(INT_TA1_0);
}

(2)输入捕获

void TimA2_Cap_Init(void)
{
	MAP_GPIO_setAsInputPin(GPIO_PORT_P5, GPIO_PIN6);

    /* 定时器配置参数*/
    Timer_A_ContinuousModeConfig continuousModeConfig = {
        TIMER_A_CLOCKSOURCE_SMCLK,      // SMCLK Clock Source
        TIMER_A_CLOCKSOURCE_DIVIDER_48, // SMCLK/48 = 1MHz
        TIMER_A_TAIE_INTERRUPT_DISABLE,  // 关闭定时器溢出中断
        TIMER_A_DO_CLEAR                // Clear Counter
    };
    // 3.将定时器初始化为连续计数模式
    MAP_Timer_A_configureContinuousMode(TIMER_A2_BASE, &continuousModeConfig);
	MAP_GPIO_setAsPeripheralModuleFunctionInputPin(GPIO_PORT_P5, GPIO_PIN6, GPIO_PRIMARY_MODULE_FUNCTION);
	
    // 4.配置捕捉模式结构体 */
    const Timer_A_CaptureModeConfig captureModeConfig_TA2 = {
        TIMER_A_CAPTURECOMPARE_REGISTER_1,                      //在这里改引脚
        TIMER_A_CAPTUREMODE_RISING_AND_FALLING_EDGE, //上升下降沿捕获
        TIMER_A_CAPTURE_INPUTSELECT_CCIxA,           //CCIxA:外部引脚输入  (CCIxB:与内部ACLK连接(手册)
        TIMER_A_CAPTURE_SYNCHRONOUS,                 //同步捕获
        TIMER_A_CAPTURECOMPARE_INTERRUPT_ENABLE,     //开启CCRN捕获中断
        TIMER_A_OUTPUTMODE_OUTBITVALUE               //输出位值
    };
    
    // 5.初始化定时器的捕获模式
    MAP_Timer_A_initCapture(TIMER_A2_BASE, &captureModeConfig_TA2);

    // 6.选择连续模式计数开始计数
    MAP_Timer_A_startCounter(TIMER_A2_BASE, TIMER_A_CONTINUOUS_MODE);

    // 7.清除中断标志位
    MAP_Timer_A_clearInterruptFlag(TIMER_A2_BASE);                                   //清除定时器溢出中断标志位
    MAP_Timer_A_clearCaptureCompareInterrupt(TIMER_A2_BASE, TIMER_A_CAPTURECOMPARE_REGISTER_1); //清除 CCR1 更新中断标志位
	MAP_Timer_A_clearCaptureCompareInterrupt(TIMER_A2_BASE, TIMER_A_CAPTURECOMPARE_REGISTER_2); //清除 CCR1 更新中断标志位
	
    // 8.开启定时器端口中断
    MAP_Interrupt_enableInterrupt(INT_TA2_N); //开启定时器A2端口中断
	
	MAP_Interrupt_enableMaster();
}

(3)中断计算
每10ms进入一次中断进行路程及时间计算。

void TA1_0_IRQHandler(void)
{
    MAP_Timer_A_clearCaptureCompareInterrupt(TIMER_A1_BASE, TIMER_A_CAPTURECOMPARE_REGISTER_0);	
	n++;
	Timer=0.01*n;
	s=(encoder_R+encoder_L)/2*m;
	v=s*100;      // v=s/t   t=10ms=0.01s
	encoder_L=0;
	encoder_R=0;		
}

2. 距离测量

这里我用的是GY56红外激光测距传感器,采用串口通信进行数据采集。

void GY56_Init(void)
{
    //1.配置GPIO复用
    GPIO_setAsPeripheralModuleFunctionInputPin(GPIO_PORT_P3, GPIO_PIN2 | GPIO_PIN3, GPIO_PRIMARY_MODULE_FUNCTION);

    //2.配置UART结构体
#ifdef EUSCI_A_UART_7_BIT_LEN
    //固件库v3_40_01_02
    //默认SMCLK 48MHz 比特率 115200
    const eUSCI_UART_ConfigV1 uartConfig =
        {
            EUSCI_A_UART_CLOCKSOURCE_SMCLK,                // SMCLK Clock Source
            26,                                            // BRDIV = 26
            0,                                             // UCxBRF = 0
            111,                                           // UCxBRS = 111
            EUSCI_A_UART_NO_PARITY,                        // No Parity
            EUSCI_A_UART_LSB_FIRST,                        // MSB First
            EUSCI_A_UART_ONE_STOP_BIT,                     // One stop bit
            EUSCI_A_UART_MODE,                             // UART mode
            EUSCI_A_UART_OVERSAMPLING_BAUDRATE_GENERATION, // Oversampling
            EUSCI_A_UART_8_BIT_LEN                         // 8 bit data length
        };
    eusci_calcBaudDividers((eUSCI_UART_ConfigV1 *)&uartConfig, 115200); //配置波特率

    //3.初始化串口
    UART_initModule(EUSCI_A2_BASE, &uartConfig);

    //4.开启串口模块
    UART_enableModule(EUSCI_A2_BASE);
	
    //5.开启串口相关中断
    UART_enableInterrupt(EUSCI_A2_BASE, EUSCI_A_UART_RECEIVE_INTERRUPT);

    //6.开启串口端口中断
    Interrupt_enableInterrupt(INT_EUSCIA2);

    //7.开启总中断
    Interrupt_enableMaster();
}


void EUSCIA2_IRQHandler(void)
{
    uint32_t status = UART_getEnabledInterruptStatus(EUSCI_A2_BASE);
	static uint8_t i=0,rebuf[20]={0};
	
    if(status & EUSCI_A_UART_RECEIVE_INTERRUPT_FLAG) //接收中断
    {
		rebuf[i++]=MAP_UART_receiveData(EUSCI_A2_BASE);;//读取串口数据,同时清接收标志
		if (rebuf[0]!=0x5a)//帧头不对
			i=0;	
		if ((i==2)&&(rebuf[1]!=0x5a))//帧头不对
			i=0;
	
		if(i>3)//i等于4时,已经接收到数据量字节rebuf[3]
		{
			if(i!=(rebuf[3]+5))//判断是否接收一帧数据完毕
				return;	
			switch(rebuf[2])//接收完毕后处理
			{
				case 0x15:
					if(!Receive_ok)//当数据处理完成后才接收新的数据
					{
						memcpy(re_Buf_Data,rebuf,9);//拷贝接收到的数据
						Receive_ok=1;//接收完成标志
					}
					break;
			
			}
			i=0;//缓存清0
		}
    }

}


int Get_distance(void)
{
	if(Receive_ok)//串口接收完毕
	{
		for(sum1=0,i=0;i<(re_Buf_Data[3]+4);i++)
		sum1+=re_Buf_Data[i];
		if(sum1==re_Buf_Data[i])//校验和判断
		{
			GY56.distance=re_Buf_Data[4]<<8|re_Buf_Data[5];
			GY56.mode=re_Buf_Data[6];
			GY56.temp=re_Buf_Data[7];		
			//printf("%d\r\n",GY56.distance);
		}
		Receive_ok=0;//处理数据完毕标志
	}
	return GY56.distance;
}

3. 双机通信

这里我使用的是HC-05蓝牙 透明传输方式进行通信。

可事先在上位机对俩个蓝牙进行配置,具体配置如下所示:

Tips:先按住蓝牙上的微动开关,然后给蓝牙上电。蓝牙上的红灯慢闪表示进入AT指令模式。

1、打开两个串口调试助手,选好COM口、波特率选38400,数据位为8,停止位为12、恢复两个蓝牙的默认设置(最好选择文本模式发送AT命令):
AT+ORGL/r/n (/r/n代表一个回车,在每一条AT指令之后都要加一个回车)。

3、【(A)主机配置】蓝牙名字配置:AT+NAME=YI(名字任意)

4、【(A)主机配置】蓝牙模式配置:AT+ROLE=1(主机模式)

5、【(A)主机配置】蓝牙密码配置:AT+PSWD=1234(密码任意)

6、【(B)从机配置】蓝牙名字配置:AT+NAME=YI(名字要一致)

7、【(B)从机配置】蓝牙模式配置:AT+ROLE=0(从机模式)

8、【(B)从机配置】蓝牙密码配置:AT+PSWD=1234(密码要一致)

9、蓝牙地址的绑定,通过串口助手查询B蓝牙的地址:AT+ADDR?

10、蓝牙A绑定蓝牙B的地址,给蓝牙A(主蓝牙)发送指令:AT+BIND= (B的地址),注意在绑定地址的时候要把查询到的地址中的冒号换成逗号,例如98d3:51:fd8103,应该换成98d3,51,fd8103。

11、按照相同的方式,查询A的地址,让B绑定A的地址。

12、蓝牙的连接模式配置:AT+CMODE=O(0是指定蓝牙地址连接模式,设置为0才能自动的连接绑定的地址)

13、也可以不绑定地址,一但绑定地址那就只能两个绑定地址的蓝牙连接,其他的设备就不能连接了,所以可以不绑定地址。这样就要改变蓝牙的连接模式: AT+CMODE=1(这样两个蓝牙之间可以连接,手机也可以连接)

14、设置两个蓝牙的波特率:AT+UART=9600,0,0(保证两个蓝牙的波特率相同,在我们初始化之后蓝牙的默认波特率会改变,所以我们要再次设置波特率)
void BlueTooth_Init(void)
{
    //1.配置GPIO复用
    GPIO_setAsPeripheralModuleFunctionInputPin(GPIO_PORT_P2, GPIO_PIN2 | GPIO_PIN3, GPIO_PRIMARY_MODULE_FUNCTION);

    //2.配置UART结构体
#ifdef EUSCI_A_UART_7_BIT_LEN
    //固件库v3_40_01_02
    //默认SMCLK 48MHz 比特率 115200
    const eUSCI_UART_ConfigV1 uartConfig =
        {
            EUSCI_A_UART_CLOCKSOURCE_SMCLK,                // SMCLK Clock Source
            26,                                            // BRDIV = 26
            0,                                             // UCxBRF = 0
            111,                                           // UCxBRS = 111
            EUSCI_A_UART_NO_PARITY,                        // No Parity
            EUSCI_A_UART_LSB_FIRST,                        // MSB First
            EUSCI_A_UART_ONE_STOP_BIT,                     // One stop bit
            EUSCI_A_UART_MODE,                             // UART mode
            EUSCI_A_UART_OVERSAMPLING_BAUDRATE_GENERATION, // Oversampling
            EUSCI_A_UART_8_BIT_LEN                         // 8 bit data length
        };
    eusci_calcBaudDividers((eUSCI_UART_ConfigV1 *)&uartConfig, 115200); //配置波特率

    //3.初始化串口
    UART_initModule(EUSCI_A1_BASE, &uartConfig);

    //4.开启串口模块
    UART_enableModule(EUSCI_A1_BASE);
	
    //5.开启串口相关中断
    UART_enableInterrupt(EUSCI_A1_BASE, EUSCI_A_UART_RECEIVE_INTERRUPT);

    //6.开启串口端口中断
    Interrupt_enableInterrupt(INT_EUSCIA1);

    //7.开启总中断
    Interrupt_enableMaster();
}

4. 红外循迹

这里我使用了10个红外传感器。

(1)初始化为输入模式,且默认为高电平

void HongWai_Init(void)
{
	gpio_init(GPIO_PORT_P5, GPIO_PIN3,1,1);   
	gpio_init(GPIO_PORT_P9, GPIO_PIN3,1,1);
	gpio_init(GPIO_PORT_P6, GPIO_PIN3,1,1);
	gpio_init(GPIO_PORT_P7, GPIO_PIN2,1,1);
	gpio_init(GPIO_PORT_P7, GPIO_PIN0,1,1);
	gpio_init(GPIO_PORT_P9, GPIO_PIN5,1,1);
	gpio_init(GPIO_PORT_P9, GPIO_PIN7,1,1);
	gpio_init(GPIO_PORT_P7, GPIO_PIN5,1,1);
	gpio_init(GPIO_PORT_P7, GPIO_PIN7,1,1);
	gpio_init(GPIO_PORT_P10, GPIO_PIN1,1,1);
}

(2)获取各传感器返回的高低电平

	l1=gpio_get(GPIO_PORT_P5, GPIO_PIN3);
	l2=gpio_get(GPIO_PORT_P9, GPIO_PIN3);
	l3=gpio_get(GPIO_PORT_P6, GPIO_PIN3);
	l4=gpio_get(GPIO_PORT_P7, GPIO_PIN2);
	l5=gpio_get(GPIO_PORT_P7, GPIO_PIN0);
	l6=gpio_get(GPIO_PORT_P9, GPIO_PIN5);
	l7=gpio_get(GPIO_PORT_P9, GPIO_PIN7);
	l8=gpio_get(GPIO_PORT_P7, GPIO_PIN5);
	l9=gpio_get(GPIO_PORT_P7, GPIO_PIN7);
	l10=gpio_get(GPIO_PORT_P10, GPIO_PIN1);

(3)循迹 (0.3m/s 、0.5m/s为例)

//  Car1: 0.27~0.33m/s  ( 4.78m - 14.5~17.7s )
void Xunji30(void)
{
	l1=gpio_get(GPIO_PORT_P5, GPIO_PIN3);
	l2=gpio_get(GPIO_PORT_P9, GPIO_PIN3);
	l3=gpio_get(GPIO_PORT_P6, GPIO_PIN3);
	l4=gpio_get(GPIO_PORT_P7, GPIO_PIN2);
	l5=gpio_get(GPIO_PORT_P7, GPIO_PIN0);
	l6=gpio_get(GPIO_PORT_P9, GPIO_PIN5);
	l7=gpio_get(GPIO_PORT_P9, GPIO_PIN7);
	l8=gpio_get(GPIO_PORT_P7, GPIO_PIN5);
	l9=gpio_get(GPIO_PORT_P7, GPIO_PIN7);
	l10=gpio_get(GPIO_PORT_P10, GPIO_PIN1);

	
	if(l1==0 && l2==0 && l3==0 && l4==0 && l5==1 && l6==0 && l7==0 && l8==0 && l9==0 && l10==0)
	{
		Forward();
		target_L=365;
		target_R=365;
	}
	else if(l1==0 && l2==0 && l3==0 && l4==0 && l5==0 && l6==1 && l7==0 && l8==0 && l9==0 && l10==0)
	{
		Forward();
		target_L=365;
		target_R=365;
	}
	else if((l1==1&&l4==1)||(l1==1&&l5==1)||(l2==1&&l5==1)||(l2==1&&l6==1)||(l3==1&&6==1)||(l3==1&&l7==1))
	{
		Forward();
		target_L=365;
		target_R=365;
	}
	
//踩左边	
	else if(l1==0 && l2==0 && l3==0 && l4==1 && l5==0 && l6==0 && l7==0 && l8==0 && l9==0 && l10==0 )
	{
		Forward();
		target_L=355;
		target_R=365;		
	}
	else if(l1==0 && l2==0 && l3==1 && l4==0 && l5==0 && l6==0 && l7==0 && l8==0 && l9==0 && l10==0 )
	{
		Forward();
		target_L=345;
		target_R=365;		
	}
	else if(l1==0 && l2==1 && l3==0 && l4==0 && l5==0 && l6==0 && l7==0 && l8==0 && l9==0 && l10==0 && Timer>=1.8)
	{
		Forward();
		target_L=335;
		target_R=365;		
	}		
	else if(l1==1 && l2==0 && l3==0 && l4==0 && l5==0 && l6==0 && l7==0 && l8==0 && l9==0 && l10==0 && Timer>=1.8)
	{	
		Left();
		target_L=0;
		target_R=300;		
	}
	
	//踩右边
	else if(l1==0 && l2==0 && l3==0 && l4==0 && l5==0 && l6==0 && l7==1 && l8==0 && l9==0 && l10==0 )
	{
		Forward();
		target_L=365;
		target_R=355;		
	}
	else if(l1==0 && l2==0 && l3==0 && l4==0 && l5==0 && l6==0 && l7==0 && l8==1 && l9==0 && l10==0 )
	{
		Forward();
		target_L=365;
		target_R=345;		
	}
	else if(l1==0 && l2==0 && l3==0 && l4==0 && l5==0 && l6==0 && l7==0 && l8==0 && l9==1 && l10==0 )
	{
		Forward();
		target_L=365;
		target_R=335;		
	}
	else if(l1==0 && l2==0 && l3==0 && l4==0 && l5==0 && l6==0 && l7==0 && l8==0 && l9==0 && l10==1 )
	{
		Right();
		target_L=300;
		target_R=0;		
	}

//终点停止
	else if(((l2==1&&l3==1&&l4==1)||(l3==1&&l4==1&&l5==1)||(l4==1&&l5==1&&l6==1)||(l5==1&&l6==1&&l7==1)||(l6==1&&l7==1&&l8==1)||(l7==1&&l8==1&&l9==1)) && Timer>=15)
	{
		UART_transmitData(EUSCI_A1_BASE, 's'); //发送数据
		beep_flag++;
		TimerA1_Disable();

		while(1)
		{
			Stop();	
			target_L=0;
			target_R=0;
			MAP_Timer_A_setCompareValue(TIMER_A0_BASE, TIMER_A_CAPTURECOMPARE_REGISTER_1, target_L);
			MAP_Timer_A_setCompareValue(TIMER_A0_BASE, TIMER_A_CAPTURECOMPARE_REGISTER_2, target_R);
			
			if(beep_flag==1)
			{
				beep_flag=2;
				OLED_ShowNum(47,4,Timer,2,16);
				int t=(int)(Timer*10)%10;
				OLED_ShowNum(63,4,t,3,16);
				int distance1=Get_distance();
				OLED_ShowString(30, 6, (uint8_t *)"Distance:", 16);
				OLED_ShowNum(100,6,distance1,3,16);
				gpio_set(GPIO_PORT_P10, GPIO_PIN4,1);
				delay_ms(500);
				gpio_set(GPIO_PORT_P10, GPIO_PIN4,0);
			}
		}
	}
	MAP_Timer_A_setCompareValue(TIMER_A0_BASE, TIMER_A_CAPTURECOMPARE_REGISTER_1, target_L);
	MAP_Timer_A_setCompareValue(TIMER_A0_BASE, TIMER_A_CAPTURECOMPARE_REGISTER_2, target_R);
}



void Xunji50(void)
{
	l1=gpio_get(GPIO_PORT_P5, GPIO_PIN3);
	l2=gpio_get(GPIO_PORT_P9, GPIO_PIN3);
	l3=gpio_get(GPIO_PORT_P6, GPIO_PIN3);
	l4=gpio_get(GPIO_PORT_P7, GPIO_PIN2);
	l5=gpio_get(GPIO_PORT_P7, GPIO_PIN0);
	l6=gpio_get(GPIO_PORT_P9, GPIO_PIN5);
	l7=gpio_get(GPIO_PORT_P9, GPIO_PIN7);
	l8=gpio_get(GPIO_PORT_P7, GPIO_PIN5);
	l9=gpio_get(GPIO_PORT_P7, GPIO_PIN7);
	l10=gpio_get(GPIO_PORT_P10, GPIO_PIN1);

	
	if(l1==0 && l2==0 && l3==0 && l4==0 && l5==1 && l6==0 && l7==0 && l8==0 && l9==0 && l10==0)
	{
		Forward();
		target_L=500;
		target_R=510;
	}
	else if(l1==0 && l2==0 && l3==0 && l4==0 && l5==0 && l6==1 && l7==0 && l8==0 && l9==0 && l10==0)
	{
		Forward();
		target_L=500;
		target_R=510;
	}
	else if(((l1==1&&l4==1)||(l1==1&&l5==1)||(l2==1&&l5==1)||(l2==1&&l6==1)||(l3==1&&6==1)||(l3==1&&l7==1)|| (l3==1&&l2==1)||(l3==1&&l4==1)||(l3==1&&l5==1)||(l4==1&&l5==1)||(l4==1&&l6==1)||(l5==1&&l6==1)||(l5==1&&l7==1)) &&(Timer<=9))
	{
		Forward();
		target_L=500;
		target_R=510;
	}
	
//踩左边	
	else if(l1==0 && l2==0 && l3==0 && l4==1 && l5==0 && l6==0 && l7==0 && l8==0 && l9==0 && l10==0 )
	{
		Forward();
		target_L=500;
		target_R=510;		
	}
	else if(l1==0 && l2==0 && l3==1 && l4==0 && l5==0 && l6==0 && l7==0 && l8==0 && l9==0 && l10==0 )
	{
		Forward();
		target_L=495;
		target_R=510;		
	}
	else if(l1==0 && l2==1 && l3==0 && l4==0 && l5==0 && l6==0 && l7==0 && l8==0 && l9==0 && l10==0 && Timer>=1)
	{
		Forward();
		target_L=490;
		target_R=510;		
	}		
	else if(l1==1 && l2==0 && l3==0 && l4==0 && l5==0 && l6==0 && l7==0 && l8==0 && l9==0 && l10==0 && Timer>=1)
	{	
		Left();
		target_L=0;
		target_R=430;
	}
	
	//踩右边
	else if(l1==0 && l2==0 && l3==0 && l4==0 && l5==0 && l6==0 && l7==1 && l8==0 && l9==0 && l10==0 )
	{
		Forward();
		target_L=500;
		target_R=505;	
	}
	else if(l1==0 && l2==0 && l3==0 && l4==0 && l5==0 && l6==0 && l7==0 && l8==1 && l9==0 && l10==0 )
	{
		Forward();
		target_L=500;
		target_R=500;		
	}
	else if(l1==0 && l2==0 && l3==0 && l4==0 && l5==0 && l6==0 && l7==0 && l8==0 && l9==1 && l10==0 )
	{
		Forward();
		target_L=500;
		target_R=495;		
	}
	else if(l1==0 && l2==0 && l3==0 && l4==0 && l5==0 && l6==0 && l7==0 && l8==0 && l9==0 && l10==1 )
	{
		Right();
		target_L=430;
		target_R=0;		
	}

//终点停止
	else if(((l2==1&&l3==1&&l4==1)||(l3==1&&l4==1&&l5==1)||(l4==1&&l5==1&&l6==1)||(l5==1&&l6==1&&l7==1)||(l6==1&&l7==1&&l8==1)||(l7==1&&l8==1&&l9==1)) && Timer>=12)
	{
		UART_transmitData(EUSCI_A1_BASE, 's'); //发送数据
		beep_flag++;
		TimerA1_Disable();

		while(1)
		{
			Stop();	
			target_L=0;
			target_R=0;
			MAP_Timer_A_setCompareValue(TIMER_A0_BASE, TIMER_A_CAPTURECOMPARE_REGISTER_1, target_L);
			MAP_Timer_A_setCompareValue(TIMER_A0_BASE, TIMER_A_CAPTURECOMPARE_REGISTER_2, target_R);
			
			if(beep_flag==1)
			{
				beep_flag=2;
				OLED_ShowNum(47,4,Timer,2,16);
				int t=(int)(Timer*10)%10;
				OLED_ShowNum(63,4,t,3,16);
				int distance1=Get_distance();
				OLED_ShowString(30, 6, (uint8_t *)"Distance:", 16);
				OLED_ShowNum(100,6,distance1,3,16);
				gpio_set(GPIO_PORT_P10, GPIO_PIN4,1);
				delay_ms(500);
				gpio_set(GPIO_PORT_P10, GPIO_PIN4,0);
			}
		}
	}
	MAP_Timer_A_setCompareValue(TIMER_A0_BASE, TIMER_A_CAPTURECOMPARE_REGISTER_1, target_L);
	MAP_Timer_A_setCompareValue(TIMER_A0_BASE, TIMER_A_CAPTURECOMPARE_REGISTER_2, target_R);
}

四、技术交流

疑难解答或技术交流 联系下方wx即可👇👇👇。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/771296.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

实现本地缓存-caffeine

目录 实现caffeine cache CacheManager Caffeine配置说明 创建自定义配置类 配置缓存管理器 编写自动提示配置文件 测试使用 创建测试配置实体类 创建测试配置类 创建注解扫描的测试实体 创建单元测试类进行测试 实现caffeine cache CacheManager SimpleCacheManag…

HttpClient使用MultipartEntityBuilder上传文件时乱码问题解决

HttpClient使用MultipartEntityBuilder是常用的上传文件的组件&#xff0c;但是上传的文件名称是乱码&#xff0c;一直输出一堆的问号&#xff1a; 如何解决呢&#xff1f;废话少说&#xff0c;先直接上代码&#xff1a; public static String doPostWithFiles(HttpClient http…

git使用问题记录-权限

注意点&#xff1a; 1、在远程仓库中直接创建项目时&#xff0c;默认分支为main 2、git push报错 原因&#xff1a;即使是项目文件的创建者&#xff0c;但上层目录的权限为developer&#xff0c;无法push项目&#xff0c;找上层管理员修改权限为maintainer或owner可push代码…

File格式转换MultipartFile格式的例子

首先&#xff1a;需要先引入依赖包 <dependency> <groupId>org.springframework</groupId> <artifactId>spring-test</artifactId> <version>5.3.9</version> </dependency> 1.Multipartfile转File类型 //创建一…

函数(function)py

具有名称的&#xff0c;是为了解决某一问题&#xff0c;功能代码的集合 目录 一.定义函数 二.函数的分类 三.局部变量和全局变量 1.局部变量(local variable) 2.全局变量(global variable) 四.函数调用的内存分析 五.函数的参数 1.默认值参数 2.可变参数(不定长参数)…

基于timegan扩增技术,进行多维度数据扩增(Python编程,数据集为瓦斯浓度气体数据集)

1.数据集介绍 瓦斯是被预测气体&#xff0c;其它列为特征列,原始数据一共有472行数据&#xff0c;因为原始数据比较少&#xff0c;所以要对原始数据&#xff08;总共8列数据&#xff09;进行扩增。 开始数据截图 截止数据截图 2. 文件夹介绍 lstm.py是对未扩增的数据进行训练…

1186. 删除一次得到子数组最大和;1711. 大餐计数;1834. 单线程 CPU

1186. 删除一次得到子数组最大和 解题思路&#xff1a;如果没做过还不是很好想&#xff0c;当时自己第一反应是双指针&#xff0c;结果是个动态规划的题。 核心就是dp的定义&#xff0c;dp[i][k]表示以arr[i]结尾删除k次的最大和。看到这里其实就有一点思路了 dp[i][0]表示以…

KGAT: Knowledge Graph Attention Network for Recommendation

[1905.07854] KGAT: Knowledge Graph Attention Network for Recommendation (arxiv.org) LunaBlack/KGAT-pytorch (github.com) 目录 1、背景 2、任务定义 3、模型 3.1 Embedding layer 3.2 Attentive Embedding Propagation Layers 3.3 Model Prediction 3.4 Optimi…

docker容器引擎(一)

docker 一、docker的理论部分docker的概述容器受欢迎的原因容器与虚拟机的区别docker核心概念 二、安装docker三、docker镜像操作四、docker容器操作 一、docker的理论部分 docker的概述 一个开源的应用容器引擎&#xff0c;基于go语言开发并遵循了apache2.0协议开源再Linux容…

ThreeJS打造自己的人物

hello&#xff0c;大家好&#xff0c;我是better&#xff0c;今天为大家分享如何使用Three打造属于自己的3D人物模型。 人物建模 当下有很多人物建模的网站&#xff0c;这里给大家分享的 Ready Player Me - Create a Full-Body 3D Avatar From a Photo 前往这个网址&#xff…

AI销售工具:驱动销售团队效率和个性化服务的未来

在数字化时代&#xff0c;AI销售工具成为推动销售行业发展的重要力量。这些创新工具融合了人工智能技术和销售流程&#xff0c;以提高销售团队的效率和提供个性化服务为目标。随着科技的不断进步&#xff0c;AI销售工具正引领着销售行业走向一个更加智能和高效的未来。 AI驱动的…

专题-【哈希函数】

14年三-3&#xff09; 20年三-2&#xff09; 哈希表&#xff1a; 查找成功&#xff1a; ASL(12113144)/817/8&#xff1b; 查找失败&#xff08;模为7&#xff0c;0-6不成功次数进行计算&#xff09;&#xff1a; ASL(3217654)/74。

Qgis3.16ltr+VS2017二次开发环境搭建(保姆级教程)

1.二次开发环境搭建 下载osgeo4w-setup.exeDownload QGIShttps://www.qgis.org/en/site/forusers/download.html 点击OSGeo4W Network Installer 点击下载 OSGeo4W Installer 运行程序 osgeo4w-setup.exe&#xff0c;出现以下界面&#xff0c;点击下一页。 选中install from i…

【全方位解析】如何写好技术文章

前言 为何而写 技术成长&#xff1a;相对于庞大的计算机领域的知识体系&#xff0c;人的记忆还是太有限了&#xff0c;而且随着年龄的增大&#xff0c;记忆同样也会逐渐衰退&#xff0c;正如俗话所说“好记性不如烂笔头”。并且在分享博客的过程中&#xff0c;我们也可以和大…

小白带你学习Linux的rsync的基本操作(二十四)

目录 前言 一、概述 二、特性 1、快速 2、安全 三、应用场景 四、数据的同步方式 五、rsync传输模式 六、rsync应用 七、rsync命令 1、格式 2、选项 3、举例 4、配置文件 5、练习 八、rsyncinotfy实时同步 1、服务器端 2、开发客户端 前言 Rsync是一个开源的…

光线追踪计算加速:包围盒

包围盒&#xff08;Bounding box&#xff09;是加速光线追踪&#xff08;Ray Tracing&#xff09;的最简单方法&#xff0c;不一定将其视为加速结构&#xff0c;但这无疑是减少渲染时间的最简单方法。 推荐&#xff1a;用 NSDT设计器 快速搭建可编程3D场景。 使用包围盒来加速光…

椒图——靶场模拟

先查看ip&#xff0c;10.12.13.232模拟的外网ip&#xff0c;其他的模拟内网ip&#xff0c;服务里面搭建好的漏洞环境。 #第一个测试项目&#xff0c;web风险发现 新建&#xff0c;下发任务&#xff0c;点威胁检测&#xff0c;webshell&#xff0c;点扫描任务&#xff0c;点新…

迅镭激光赋能工程机械,客户连续复购激光加工设备达双赢!

工程机械是装备制造业的重要组成部分&#xff0c;当前&#xff0c;我国已成为门类齐全、规模庞大、基础坚实、竞争力强的工程机械设备制造大国。 随着工程机械产业正在全面向智能化、绿色化转型&#xff0c;激光加工成为推动工程机械产业转型升级的重要工具&#xff0c;越来越多…

一道SQL题

有个搞数仓的朋友不知道从哪儿弄了个题。。。 做了做体验了一下。。。 记录记录。 分析 要保证每天都要做新题 5天必须都做题&#xff0c;不然GG 最后一天必须做新题&#xff0c;如果最后一天做新题了&#xff0c;前面那几天没做新题&#xff0c;做的是老题 最后一天&#…

初识mysql之理解索引

目录 一、 primary key对索引的影响 1. 主键数据有序问题 2. mysql中的page 3. 主键排序问题 二、理解多个page 1. 数据在page中的保存 2. 页目录 3. 单页情况 4. 多页情况 5. 为什么除了叶子节点外的其他节点不保存数据&#xff0c;只保存目录 6. 为什么叶子节点全…