基于MSP432P401R跟随小车(一)【2022年电赛】

文章目录

  • 一、赛前准备
    • 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即可👇👇👇。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

7.5 SpringBoot 拦截器Interceptor实战 统一角色权限校验

文章目录 前言一、定义注解annotation二、拦截角色注解1. 在拦截器哪里拦截&#xff1f;2. 如何拦截角色注解&#xff1f;3. 角色如何读取?4. 最后做角色校验 三、应用&#xff1a;给管理员操作接口加注解四、PostMan测试最后 前言 在【7.1】管理员图书录入和修改API&#xf…

原生js实现将图片内容复制到剪贴板

核心代码 /*复制图片*/ copyImg(dom) {/* 警告&#xff1a;dom不能是img标签&#xff0c;建议用DIV标签包裹img标签&#xff0c;否者会报错&#xff01;不支持复制背景图&#xff01; */dom.style.userSelect auto;let selection getSelection(), range document.createRan…

支持向量机(SVM)的超参数调整 C 和 Gamma 参数

作者:CSDN @ _养乐多_ 支持向量机(Support Vector Machine,SVM)是一种广泛应用的监督式机器学习算法。它主要用于分类任务,但也适用于回归任务。在本文中,我们将深入探讨支持向量机的两个重要参数:C和gamma。在阅读本文前,我假设您对该算法有基本的了解,并专注于这些…

从网络安全行业人才需求讲讲【个人规划】

如果你是一名正在找工作的网络安全方向大学生&#xff0c;或者是刚刚踏入网络安全领域的新手&#xff0c;这篇文章很适合你&#xff0c;如果你是一名老网安人&#xff0c;看看有哪些你中招了。 当你打开BOSS直聘、拉钩等招聘类网站后&#xff0c;在首页的快速导航页面很难找到关…

微信小程序安装和使用 Vant Weapp 组件库

微信小程序安装和使用 Vant Weapp 组件库 1. Vant Weapp 介绍2. Vant Weapp 的 安装2.1. 通过npm安装2.2. 构建npm2.3. 修改 app.json2.4. 修改 project.congfig.json2.5. 测试一下&#xff0c;使用Vant Weapp提供的组件 1. Vant Weapp 介绍 Vant 是一个轻量、可靠的移动端组件…

《遗留系统现代化》读书笔记(基础篇)

你现在所写的每一行代码&#xff0c;都是未来的遗留系统 为什么要对遗留系统进行现代化&#xff1f; 什么是遗留系统&#xff1f; 判断遗留系统的几个维度&#xff1a;代码、架构、测试、DevOps 以及技术和工具。时间长短并不是衡量遗留系统的标准。代码质量差、架构混乱、没…

【深度学习笔记】正则化与 Dropout

本专栏是网易云课堂人工智能课程《神经网络与深度学习》的学习笔记&#xff0c;视频由网易云课堂与 deeplearning.ai 联合出品&#xff0c;主讲人是吴恩达 Andrew Ng 教授。感兴趣的网友可以观看网易云课堂的视频进行深入学习&#xff0c;视频的链接如下&#xff1a; 神经网络和…

Django实现简单的音乐播放器 4

在原有音乐播放器功能基础上&#xff0c;增加上传音乐功能。 效果&#xff1a; 目录 配置上传路径 配置路由 视图处理歌曲 引入类库 保存歌曲文件 模板上传 设置菜单列表 设置菜单列表样式 脚本设置 上传效果 1.显示菜单列表 2.点击上传歌曲 3.上传完成 4.查看保…

GEE:计算每个对象的面积、标准差、周长、宽度、高度

作者:CSDN @ _养乐多_ 本文记录了面对对对象分割,以及计算每个对象的面积、标准差、周长、宽度、高度的代码。 文章目录 一、代码一、代码 // 设置种子 var seeds = ee.Algorithms.Image.Segmentation.seedGrid(20)

如何通过 CrossOver 在 Mac 苹果电脑上安装使用 windows 应用程序?

首先我们可以先了解一下什么是 crossOver &#xff0c;CrossOver 是 Mac 和 Windows 系统之间的兼容工具。使 Mac 操作系统的用户可以运行 Windows 系统的应用&#xff0c;从办公软件、实用工具、游戏到设计软件&#xff0c; 您都可以在 Mac 程序和 Windows 程序之间随意切换。…

18.Lucas-Kanade光流及OpenCV中的calcOpticalFlowPyrLK

文章目录 光流法介绍OpenCV中calcOpticalFlowPyrLK函数补充reference 欢迎访问个人网络日志&#x1f339;&#x1f339;知行空间&#x1f339;&#x1f339; 光流法介绍 光流描述了像素在图像中的运动&#xff0c;就像彗星☄划过天空中流动图像。同一个像素&#xff0c;随着时…

MacOS触控板缩放暂时失灵问题解决

我的系统版本为Monterey 12.5.1&#xff0c;亲测有效 直接创建脚本xxx.sh&#xff0c;并在终端执行脚本bash xxx.sh即可解决此问题&#xff0c;脚本内容如下&#xff1a; #!/bin/bashkillall Finder #kill Finder如不需要可以删除 killall Dock #kill Dock 如不需要可以删…

【Maven】Maven下载,配置以及基本概念

文章目录 1. Maven简介2. Maven下载3. Maven环境配置4.Maven的基本概念4.1 仓库4.2 坐标4.3 仓库配置(修改IDEA默认Maven库) 1. Maven简介 Maven是一个Java项目管理工具和构建工具&#xff0c;用于管理项目的依赖关系、构建过程以及项目的部署。它是Apache软件基金会的开源项目…

『表面』在平面模型上提取凸(凹)多边形

原始点云 直通滤波,z轴0~1.1 分割模型为平面&#xff0c;分割结果进行投影 提取多边形 代码: #include <pcl/ModelCoefficients.h> // 模型系数的数据结构&#xff0c;如平面、圆的系数 #include <pcl/io/pcd_io.h>#include <pcl/point_types.h> // 点云数据…

nginx uwsgi配置django

uwsgi文件 [uwsgi] # 服务端口号&#xff0c;这里没有设置IP值&#xff0c;默认是加载服务器的IP地址 #http :5000 socket:8000 # flask项目地址 chdir /pyprogram/electric # wsgi文件 /home/flask_project/mange.py #module app:app wsgi-file/pyprogram/electric/electr…

手搓一台简单的网络损伤仪——弱网测试

1、介绍 支持对链路带宽、传输时延、丢包率和无码率的手动设置&#xff1b; 1.1、网络损伤仪在使用时&#xff0c;网络拓扑连接 1.2、网络损伤仪管理页面展示 2、使用的设备及相关技术栈 一台Intel 赛扬 J1900的迷你主机【拥有4个千兆网口】&#xff1b;ubuntu-18.04.5-live…

【机器学习】了解 AUC - ROC 曲线

一、说明 在机器学习中&#xff0c;性能测量是一项基本任务。因此&#xff0c;当涉及到分类问题时&#xff0c;我们可以依靠AUC - ROC曲线。当我们需要检查或可视化多类分类问题的性能时&#xff0c;我们使用AUC&#xff08;曲线下面积&#xff09;ROC&#xff08;接收器工作特…

Coggle 30 Days of ML(23年7月)任务六:训练FastText、Word2Vec词向量

Coggle 30 Days of ML&#xff08;23年7月&#xff09;任务六&#xff1a;训练FastText、Word2Vec词向量 任务六&#xff1a;学会训练FastText、Word2Vec词向量 说明&#xff1a;在这个任务中&#xff0c;你将学习如何训练FastText和Word2Vec词向量模型&#xff0c;这些词向量…

Linux地盘上AMD处理器称王了

近日资讯&#xff0c;尽管从全局来看&#xff0c;Linux系统份额远不及Windows&#xff0c;但在程序员、开发者、硬核玩家圈子&#xff0c;Linux则备受推崇。 来自Steam的最新数据显示&#xff0c;在Linux游戏用户中&#xff0c;AMD处理器的份额占据绝对优势&#xff0c;达到了…

ts学习(一):基础篇1

旨在记录&#xff01; 这篇人都学废了&#xff0c;本想记录常用类型&#xff0c;越学越多&#xff0c;每一个都很重要… 一、string: 字符串类型二、number: 数字类型三、boolean: 布尔值四、array:数组五、tuple: 元组六、字面量七、object:对象八、any: 任意类型九、unknown:…