stm32五路循迹、超声波避障(2)

PWM.c、Motor.c已发 

Track.c

五路循迹

755ffa811122400f9fd3b04f85f67692.jpeg

#include "stm32f10x.h"                  // Device header
#include "Motor.h"

//红外从左到右
#define DET1  GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_12)
#define DET2  GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_11)
#define DET3  GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_10)
#define DET4  GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_9)
#define DET5  GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_8)

uint16_t Flag=0;//此标志位仅服务于直角转弯

/*循迹初始化*/
void Track_Init()
{
	GPIO_InitTypeDef GPIO_InitStructure;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8 |  GPIO_Pin_9 | GPIO_Pin_10 | GPIO_Pin_11 | GPIO_Pin_12;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOA,&GPIO_InitStructure);
}
 
//0检测到黑线
void Track()
{

/*注:以下代码每行前面注释的是实际上系统的值,后面注释的的是人为反转的0为黑线*/
	if(Flag==0)
	{
/*00100*/	if(!DET1 && !DET2 && DET3 && !DET4 && !DET5) {Car_Run();}//11011
///*01110*/	if(!DET1 && DET2 && DET3 && DET4 && !DET5)   {Car_Run();}//10001
///*11111*/	if(DET1 && DET2 && DET3 && DET4 && DET5)     {Car_Stop();}//00000
/*01000*/	if(!DET1 && DET2 && !DET3 && !DET4 && !DET5) {Car_L_Slow();}//10111
/*01100*/	if(!DET1 && DET2 && DET3 && !DET4 && !DET5)  {Car_L_Slow();}//10011
/*10000*/	if(DET1 && !DET2 && !DET3 && !DET4 && !DET5) {Car_Left();}//01111
/*11000*/	if(DET1 && DET2 && !DET3 && !DET4 && !DET5)  {Car_Left();}//00111
/*11100*/	if(DET1 && DET2 && DET3 && !DET4 && !DET5)   {Angle_Left();Flag=1;}//00011 直角左转
///*11110*/	if(DET1 && DET2 && DET3 && DET4 && !DET5)	 {Angle_Left();}//00001
/*00010*/	if(!DET1 && !DET2 && !DET3 && DET4 && !DET5) {Car_R_Slow();}//11101
/*00110*/	if(!DET1 && !DET2 && DET3 && DET4 && !DET5)  {Car_R_Slow();}//11001
/*00001*/	if(!DET1 && !DET2 && !DET3 && !DET4 && DET5) {Car_Right();}//11110
/*00011*/	if(!DET1 && !DET2 &&!DET3 && DET4 && DET5)   {Car_Right();}//11100
/*00111*/	if(!DET1 && !DET2 && DET3 && DET4 && DET5)   {Angle_Right();Flag=2;}//11000 直角右转
///*01111*/	if(!DET1 && DET2 && DET3 && DET4 && DET5)    {Angle_Right();}//10000
/*00000*/	if(!DET1 && !DET2 && !DET3 && !DET4 && !DET5){Car_Run();}//11111
	}
	
/*以下代码时当检测到该直角转弯时再执行*/
/*我将直角转弯分成了一个函数,可以使转向更稳定*/

	else if(Flag==1)//左
	{
		Angle_Left();
		if((!DET1 && !DET2 && !DET3 && !DET4 && DET5)||
			(!DET1 && !DET2 &&!DET3 && DET4 && DET5) || 
		    (!DET1 && !DET2 && DET3 && !DET4 && !DET5)
		)//11110||11100||11011转正
		{
			Flag=0;
		}
	}
	else if(Flag==2)//右
	{
		Angle_Right();
		if((DET1 && !DET2 && !DET3 && !DET4 && !DET5)||
		   (DET1 && DET2 && !DET3 && !DET4 && !DET5) ||
		   (!DET1 && !DET2 && DET3 && !DET4 && !DET5)
			)//01111||00111||11011转正
		{
			Flag=0;
		}
	}
}

SR04.c

注:我用的定时器1计时,用外部中断EXTI来控制定时什么是开始或结束计时,并且计算距离。

因为障碍物是随机出现的,外部中断可以随时响应并且没有固定时间什么时候才可以进中断,而定时器的中断是人为设定的时间,只能固定时间才会进中断计算距离

提醒

VCC 接5V!!!

a19953ce50be405dbaf6764357de5021.jpeg

#include "stm32f10x.h"                  // Device header
#include "Delay.h"
#include "Timer1.h"

#define Trig GPIO_Pin_6
#define Echo GPIO_Pin_5

float Num=0;
int i=0,Counter=0,Sum=0,Dec=0,CNT_Mean=0,CN1=0,CN2=0;

// Device header
void SR04_Init(void )
{
	//打开发射端Trig
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
	
	GPIO_InitTypeDef GPIO_InitStructure;
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 ;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;//通用推挽输出
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;//速度50MHz
	GPIO_Init(GPIOB,&GPIO_InitStructure);
	
	//打开接收端Echo
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);

	GPIO_InitTypeDef GPIO_InitStructure1;
	GPIO_InitStructure1.GPIO_Pin = GPIO_Pin_5;
	GPIO_InitStructure1.GPIO_Mode = GPIO_Mode_IPD;
	GPIO_Init(GPIOB, &GPIO_InitStructure1);
	GPIO_ResetBits(GPIOB,GPIO_Pin_5);

	//配置中断线,Echo接收时进中断
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);
	GPIO_EXTILineConfig(GPIO_PortSourceGPIOB,GPIO_PinSource5);// 配置GPIOB,选择第五个引脚作为中断源
	
	EXTI_InitTypeDef EXTI_InitStructure;
	EXTI_InitStructure.EXTI_Line = EXTI_Line5;
	EXTI_InitStructure.EXTI_LineCmd = ENABLE;
	EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;// 设置为中断模式
	EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;//上升沿触发中断
	EXTI_Init(&EXTI_InitStructure);// 应用配置到EXTI

	
	//NVIC中断优先级配置	
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
	
	NVIC_InitTypeDef NVIC_InitStructure;
	NVIC_InitStructure.NVIC_IRQChannel = EXTI9_5_IRQn;
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x00;
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x01;
	NVIC_Init(&NVIC_InitStructure);
		
}

void SR04_Start(void)//发射
{
	GPIO_SetBits(GPIOB,GPIO_Pin_6);
	Delay_us(15);
	GPIO_ResetBits(GPIOB,GPIO_Pin_6);
}


/*中断函数*/
//在接收到返回的声波时(Echo)才进入,并开始计时
void EXTI9_5_IRQHandler(void)
{
  if(EXTI_GetITStatus(EXTI_Line5) != RESET)
  {
		//LED1_ON();
		Timer_ON();
		CN1 = TIM_GetCounter(TIM1);
		while(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_5));
        //声波是一段距离,一直有Echo就一直检测为高电平且一直计时,直到一次的信号结束Echo才变低电平,然后执行后续代码
		CN2 = TIM_GetCounter(TIM1);
		Timer_OFF();
		Counter = CN2 - CN1;
		EXTI_ClearITPendingBit(EXTI_Line5);
		//LED1_OFF();
	}
}

float Get_Distant()
{
	
	SR04_Start();
	Num=Counter*0.017;//b/5 * 17/1000
	return Num;	
}
/*注:这个公式适用于从Echo检测到返回的声波时才开始计时的方法。
还有一种是从Trig发射声波时就开始计时,那就用到另一个公式*/

Timer1.c 

定时器1配置

#include "stm32f10x.h"                  // Device header

void Timer_Init(void)
{
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE);  // 

	TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;

	TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;//????
	TIM_TimeBaseInitStructure.TIM_Period = 65535;//ARR
	TIM_TimeBaseInitStructure.TIM_Prescaler=72-1;//????
	TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0;//CNT??ARR????

	TIM_TimeBaseInit(TIM1, &TIM_TimeBaseInitStructure);
	TIM_SetCounter(TIM1,0);
	//定时器1会清除其当前值(如果之前有计数值),并从0开始计数
}

void Timer_ON(void)
{
	TIM_Cmd(TIM1,ENABLE);
}


void Timer_OFF(void)
{
	TIM_Cmd(TIM1,DISABLE);
}

STM32红外循迹超声波避障在原理上并不会冲突,但在实际运用中可能存在一些问题需要考虑。 红外循迹超声波避障都是基于不同的传感器技术,用于检测和避开障碍物,以实现机器人的移动控制。 红外循迹原理是利用红外线传感器感知地面上的红外反射信号,通过检测黑线和白地之间的差异,从而确定机器人的运动方向。 超声波避障则是利用超声波传感器发射超声波信号,并通过接收返回的超声波信号来检测与物体之间的距离,以确定是否有障碍物。 在使用过程中,如果同时使用红外循迹超声波避障,需要注意以下几点: 1.传感器选用:要选择不同的接口或引脚连接红外与超声波传感器,确保它们能够正常工作,不存在硬件上的冲突。 2.信号干扰:因为红外传感器和超声波传感器都属于接收和发送传感器,可能会对彼此的信号产生干扰。在设计电路时,要合理分离它们的供电与信号线,以减少干扰的可能性。 3.算法设计:机器人的控制算法需要根据红外循迹超声波避障传感器返回的数据进行判断和决策。需要设计合适的算法,使机器人能够同时检测和处理两种传感器的数据,实现循迹和避障功能。 综上所述,STM32红外循迹超声波避障可以同时使用,但在硬件连接和算法设计方面需要注意一些细节,以确保它们能够正常工作,并避免可能出现的冲突。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值