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

news2024/11/27 14:42:41

文章目录

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

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

相关文章

MinUv2靶场详解

MinUv2靶场详解 这个靶场我学到了.bash_history文件&#xff0c;每个用户都有一个名为 .bash_history 的文件&#xff0c;它位于用户的主目录中&#xff0c;默认有500行最近执行的命令。 这个靶场我用vmware是不能打开的&#xff0c;用virtualBox就可以&#xff0c;并且打开时…

MySQL索引、事务

目录 索引 作用 查看索引 创建索引 删除索引 索引背后的数据结构 B树 B树 事务 事务的本质 事务的特性 并发执行事务产生的问题 脏读问题 不可重复读 幻读 MySQL中隔离级别 read uncommitted readcommitted repeatable read serializable 索引 索引的本质…

SolidUI AI生成可视化,0.1.0版本模块划分以及源码讲解

1.背景 随着文本生成图像的语言模型兴起&#xff0c;SolidUI想帮人们快速构建可视化工具&#xff0c;可视化内容包括2D,3D,3D场景&#xff0c;从而快速构三维数据演示场景。SolidUI 是一个创新的项目&#xff0c;旨在将自然语言处理&#xff08;NLP&#xff09;与计算机图形学相…

【Java虚拟机学习1】JVM运行时数据区

JVM运行时数据区 一、前言 我们知道Java程序是运行在JVM&#xff08;Java虚拟机&#xff09;上的&#xff0c;Java程序运行时会占用一定的内存&#xff0c;在虚拟机自动管理机制的帮助下&#xff0c;不再需要为每一个new操作去写配对的delete/free代码&#xff0c;不容易出现…

指针进阶详解(下)

指针进阶详解&#xff08;下&#xff09; 前言1. 函数指针1.1 两端有趣代码 2. 函数指针数组2.1 函数指针数组的用途之一&#xff1a;转移表 3. 指向函数指针数组的指针4. 回调函数5. 结尾 前言 在指针进阶详解&#xff08;上&#xff09;中&#xff0c;我们已经介绍了部分指针…

基于数据安全的风险评估(三):风险分析与评估

完成了资产识别、脆弱性识别及威胁识别后&#xff0c;我们可以采用适当的方法和工具确定威胁利用脆弱性导致安全事件发生的可能性。综合安全事件作用资产价值及脆弱性的严重程度&#xff0c;判断事件造成的损失及对组织的影响&#xff0c;即安全风险。 一 风险计算形式及关键环…

HTTP协议对比HTTPS协议

HTTP协议对比HTTPS协议 1. HTTP协议1.1 概述1.2 HTTP协议格式1.3 HTTP协议支持的方法1.3.1 GET方法1.3.2 POST方法1.3.3 其他HTTP方法1.3.4 GET对比POST 1.4 请求报文1.4.1 Content-Type&#xff1a;请求体中数据格式1.4.2 Cookie&#xff1a;浏览器缓存 1.5 响应报文1.5.1 状态…

LED驱动(原始架构优化:分层/分离)——STM32MP157

文章目录 优化思想&#xff1a;分层Demo的LED驱动程序led_opr.hboard_demo.cleddrv.cledtest.cMakefile编译测试 STM32MP157的LED驱动程序board_stm32mp157.cleddrv.cled_opr.hMakefiel编译测试 优化思想&#xff1a;分离Demo的LED驱动程序led_resource.hboard_A_led.cchip_dem…

MacOS系统(M1/M2)安装AI绘画StableDiffusion保姆级教程

TOC 安装完成后&#xff0c;推荐阅读这篇教程&#xff1a;AI绘画&#xff1a;Stable Diffusion 终极炼丹宝典&#xff1a;从入门到精通 实操环境&#xff1a; macOS 13 Arm64&#xff08;建议12以上的系统使用&#xff09; Apple M1 先来看几个样例&#xff1a; AI绘画S…

goland自定义代码模版

在 GoLand 中我们既可以修改已有代码模版&#xff0c;也可以新建属于我们自己的代码模版&#xff0c;按需配置。 一、修改已有代码模版 现在代码编辑页输入你想更改的代码模版&#xff0c;然后点击右下角的小灯泡按钮&#xff0c;接着选中编辑活动模版设置即可。 二、新建…

[机缘参悟-99] :关于局部最优与全局最优解的人生感悟

在没有获取全局信息之前&#xff0c;要获得全局最优解几乎是不可能的&#xff0c;最多是概率大一点而已&#xff0c;大多数时候&#xff0c;由于时空资源的限制&#xff0c;获得往往是局部最优解&#xff0c;局部最优解&#xff0c;放在全局&#xff0c;往往并非全局最优&#…

数学专题训练3 数论1

1. Problem - 27E - Codeforces 给定 n ( 1 ≤ n ≤ 1000 ) n(1 \le n \le 1000) n(1≤n≤1000)​​​&#xff0c;找到因子个数恰好为 n n n​​​ 个的最小正整数. 保证答案不大于 1 e 18 1e18 1e18. 和 反素数 的思路是一样的&#xff0c;深搜 这个是枚举当前数字可以…

Shiro反序列化漏洞(CVE-2016-4437)+docker靶场+工具利用

一、Shiro反序列化漏洞-CVE-2016-4437原理 将java对象转换为字节序列&#xff08;json/xml&#xff09;的过程叫序列化&#xff0c;将字节序列&#xff08;json/xml&#xff09;恢复为java对象的过程称为反序列化。 Shiro框架提供了“记住我”的功能&#xff0c;用户登陆成功…

JPA 概述及常用注解详解、SpringDataJpa 使用指南

JPA&#xff08;Java Persistence API&#xff09;是 Java 标准中的一套ORM规范&#xff08;提供了一些编程的 API 接口&#xff0c;具体实现由 ORM 厂商实现&#xff0c;如Hiernate、TopLink 、Eclipselink等都是 JPA 的具体实现&#xff09;&#xff0c;借助 JPA 技术可以通过…

Unity3D 入门

文章目录 拖拽快捷键资源商店地形构建器 拖拽快捷键 首先看到Scene界面&#xff0c;我们布置游戏场景中的游戏对象基本是在这个界面完成的 鼠标滚轮键按住&#xff1a;能够拖拽平面&#xff0c;不移动对象鼠标右键按住&#xff1a;能够旋转我们观察界面的视角&#xff0c;不移…

快速理解并实现权限控制

什么是权限控制? 权限控制是指在一个系统或应用中对用户或角色的操作进行限制和管理的过程。它用于确保只有经过授权的用户或角色能够执行特定的操作或访问特定的资源。权限控制是信息安全和访问控制的重要组成部分。 权限控制的主要目的是保护系统的安全性和完整性&#xf…

GEE:支持向量机(SVM)分类参数说明和官方案例

作者:CSDN @ _养乐多_ 本文记录了在GEE平台上进行支持向量机(SVM)分类使用ee.Classifier.libsvm的说明和官方案例。 文章目录 一、函数介绍1.1 GEE上说明1.2 函数说明二、官方案例一、函数介绍 1.1 GEE上说明 ee.Classifier.libsvm(decisionProcedure, svmType, kernelTyp…

CentOS5678 repo源 地址 阿里云开源镜像站

CentOS5678 repo 地址 阿里云开源镜像站 https://mirrors.aliyun.com/repo/ CentOS-5.repo https://mirrors.aliyun.com/repo/Centos-5.repo [base] nameCentOS-$releasever - Base - mirrors.aliyun.com failovermethodpriority baseurlhttp://mirrors.aliyun.com/centos/$r…

Springboot JPA 集成多租户

背景&#xff1a; ​ iot-kit项目用的是jpa&#xff0c;不是mybatis&#xff0c;项目中需要引入多租户 参考文章&#xff1a; 【讲解多租户的实现与原理】 https://www.bilibili.com/video/BV1F84y1T7yf/?share_sourcecopy_web&vd_source981718c4abc87423399e43793a5d3…

pytest实现用例间参数传递的方式

pytest实现用例间参数传递的方式 一、通过conftest创建全局变量二、使用tmpdir_factory方法 我们在做接口自动化测试的时候&#xff0c;会经常遇到这种场景&#xff1a;接口A的返回结果中的某个字段&#xff0c;是接口B的某个字段的入参。如果是使用postman&#xff0c;那我们可…