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

文章目录

  • 一、赛前准备
    • 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/40592.html

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

相关文章

基于单片机智能台灯坐姿矫正器视力保护器的设计与实现

功能介绍 以51单片机作为主控系统&#xff1b;LCD1602液晶显示当前当前光线强度、台灯灯光强度、当前时间、坐姿距离等&#xff1b;按键设置当前时间&#xff0c;闹钟、提醒时间、坐姿最小距离&#xff1b;通过超声波检测坐姿&#xff0c;当坐姿不正容易对眼睛和身体腰部等造成…

Git 使用笔记

Git使用笔记 1 版本控制 1.1 什么是版本控制 ​ 版本控制&#xff08;Revision control&#xff09;是一种在开发的过程中用于管理我们对文件、目录或工程等内容的修改历史&#xff0c;方便查看更改历史记录&#xff0c;备份以便恢复以前的版本的软件工程技术。简单说就是用…

大模型开发(六):OpenAI Completions模型详解并实现多轮对话机器人

全文共8500余字&#xff0c;预计阅读时间约17~30分钟 | 满满干货(附代码)&#xff0c;建议收藏&#xff01; 代码下载点这里 一、 Completions与Chat Completions基本概念 经过海量文本数据训练的大模型会在全量语义空间内学习语法关系和表达风格&#xff0c;并通过某些微调过…

postgresql部署及优化

目录 一、postgresql概念 二、PostgreSQL 特征 三、postgres安装与登录 3.1、postgres安装 3.2、postgres使用 3.3.1、postgres登录 3.3.2、修改postgres用户密码 四、PostgreSQL 命令 4.1、PostgreSQL 创建数据库 4.2、删除数据库 4.3、创建表格 4.4、删除表格 一、…

Python爬虫学习笔记(一)————网页基础

目录 1.网页的组成 2.HTML &#xff08;1&#xff09;标签 &#xff08;2&#xff09;比较重要且常用的标签&#xff1a; ①列表标签 ②超链接标签 &#xff08;a标签&#xff09; ③img标签&#xff1a;用于渲染&#xff0c;图片资源的标签 ④div标签和span标签 &…

【MySQL】MySQL在Centos7环境下安装

目录 一、卸载不要的环境 1.1、查看是否有安装mysql 1.2、关闭运行的程序 1.3、卸载安装 二、配置yum 源 2.1、下载yum 源 2.2 安装yum源 2.3 查看是否已经生效 三、安装mysql服务 四、启动服务 五、登录方法 方法一&#xff08;不行就下一个&#xff09; 方法二&#xff08;不…

【Tauri + React 实战】VCluster - 了解技术选型与开发环境配置

VCluster A React Tauri App as visualizer of apps cluster on windows. 背景介绍 VCluster是一个在开发环境下&#xff0c;用以对一系列应用集群&#xff08;如分布式、微服务&#xff09;进行可视化管理的桌面应用程序&#xff0c;目标是实现类似 docker-compose 那样的集…

怎么解决亚马逊跟卖?为何卖家总是举报不成功?

以前大家都是从跟卖的时代走向现在的品牌化运营之路&#xff0c;但是现在跟卖已经从大家都模仿的对象变成了大部分卖家厌恶的对象&#xff0c;那么怎么解决这个跟卖问题呢&#xff1f;目前最直接的方法就是进入亚马逊后台进行举报&#xff0c;但是大概率是失败的。 一、举报违…

Spring Cloud 之 Gateway 网关

&#x1f353; 简介&#xff1a;java系列技术分享(&#x1f449;持续更新中…&#x1f525;) &#x1f353; 初衷:一起学习、一起进步、坚持不懈 &#x1f353; 如果文章内容有误与您的想法不一致,欢迎大家在评论区指正&#x1f64f; &#x1f353; 希望这篇文章对你有所帮助,欢…

elasticsearch基本操作

elasticsearch 下面参数详细解释 java 搜索查询看官方文档 https://www.elastic.co/guide/en/elasticsearch/client/java-api-client/8.8/connecting.html#_your_first_request{"name" : "Tom Foster","cluster_name" : "elasticsearch&q…

Kafka 入门到起飞 - 核心概念(术语解释)

在kafka之旅&#xff0c;我们会大量讨论Kafka中的术语&#xff0c;那么就让我们先来了解一下这些核心概念 消息(Message)&#xff1a; kafka的数据单元称为消息&#xff0c;相当于DB里的一行数据或一条记录 消息由字节数组组成 批次&#xff1a; 生产者组一批数据再向kafka推送…

消息重试框架 Spring-Retry 和 Guava-Retry

一 重试框架之Spring-Retry 1.Spring-Retry的普通使用方式 2.Spring-Retry的注解使用方式 二 重试框架之Guava-Retry 总结 图片 一 重试框架之Spring-Retry Spring Retry 为 Spring 应用程序提供了声明性重试支持。它用于Spring批处理、Spring集成、Apache Hadoop(等等)。…

MySQL高阶语句

目录 一、常用查询 1、按关键字排序 2、区间判断及查询不重复记录 3、限制结果条目 4、设置别名&#xff08;alias ——》as&#xff09; 5、通配符 一、常用查询 &#xff08;增、删、改、查&#xff09; 对 MySQL 数据库的查询&#xff0c;除了基本的查询外&#xff0c;…

R语言forestploter包优雅的绘制孟德尔随机化研究森林图

在既往文章中&#xff0c;我们对孟德尔随机化研究做了一个简单的介绍。我们可以发现&#xff0c;使用TwoSampleMR包做出来的森林图并不是很美观。今天我们使用R语言forestploter包优雅的绘制孟德尔随机化研究森林图。 使用TwoSampleMR包做出来的森林图是这样的 而很多SCI文章…

$.getScript()方法获取js文件

通过$.getScript(‘xxxx.js’)获取xxxx.js文件&#xff0c;这时的ajax是一个get请求的状态&#xff0c;如果进行了入参data的赋值那么他就会跟在url后面,同理获取json文件&#xff0c;css文件。 一开始没想起这茬。。。

Linux系统部署Nginx详细教程(图文讲解)

前言&#xff1a;本篇博客记录了我是如何使用Linux系统一步一步部署Nginx的完整过程&#xff0c;也是我学习之路上的一个笔记总结&#xff0c;每一行代码都进行了严格的测试&#xff0c;特此做一个技术分享&#xff01; 目录 一、安装依赖 二、安装Nginx 三、配置Nginx 四、…

Spring学习笔记---SpringBoot快速入门

Spring学习笔记---SpringBoot快速入门 Spring学习笔记---SpringBoot1 SpringBoot简介1.1 SpringBoot快速入门1.1.1 开发步骤1.1.1.1 创建新模块1.1.1.2 创建 Controller1.1.1.3 启动服务器1.1.1.4 进行测试 1.1.2 对比1.1.3 官网构建工程1.1.3.1 进入SpringBoot官网1.1.3.2 选择…

PETRv2: A Unified Framework for 3D Perception from Multi-Camera Images

PETRv2: A Unified Framework for 3D Perception from Multi-Camera Images 作者单位 旷视 目的 本文的目标是 通过扩展 PETR&#xff0c;使其有时序建模和多任务学习的能力 以此建立一个 强有力且统一的框架。 本文主要贡献&#xff1a; 将 位置 embedding 转换到 时序表…

Spring Batch之读数据—读XML文件(三十二)

一、XML格式文件解析 XML是一种通用的数据交换格式&#xff0c;它的平台无关性、语言无关性、系统无关性&#xff0c;给数据集成与交换带来了极大的方便。XML在Java领域的解析方式有两种&#xff0c;一种叫SAX&#xff0c;另一种叫DOM。SAX是基于事件流的解析&#xff0c;DOM是…

基于STM32单片机的智能家居烟雾温度火灾防盗报警的设计与实现

功能介绍 以STM32单片机作为主控系统&#xff1b;LCD1602液晶显示屏来显示显示测得的值&#xff1b;SR501人体红外感应是否有人进行防盗&#xff1b;通过烟雾传感器MQ-2获取前的烟雾值&#xff1b;通过DHT11温湿度传感器来获取当前的温湿度&#xff1b;所有的信息通过通过esp82…