基于STM32的智能循迹小车

电子说

1.2w人已加入

描述

智能循迹小车

1、小车架构

(1)车架:

       车架是淘宝上买的双层亚克力的两轮小车,配备了两个直流电机,两个驱动轮,两个辅助万向轮,一个两节的电池盒,这些东西淘宝上很多都是打包售卖的。

单片机底部照片

 

单片机正面照片

(2)电源模块

单片机电源模块

        电源模块采用的是两节高电压的5号可充电电池(没节电池3.2V),由于手上没有DC线,干脆直接将电池盒连上了两根飞线插在面包板上,然后又将DC接口下面的正负极引脚焊接了两根公对公的杜邦线然后插在面包板上,这样就可以直接利用电池给这块HW-131面包板供电模块供电了。这块供电模块内置稳压芯片可以输出多路的3.3V和5V的电压,这样就正好可以解决电机和循迹班5V供电的问题啦。

(3)驱动板

单片机驱动板

      非常尴尬,不会利用画图软件画原理图,所以用的洞洞板焊接,用的是一块STM32F103C8T6、TB6612电机驱动模块,另外还预留了一块NRF24L01-2.4G无线通信模块想要后面做个遥控器,加上遥控功能。刚练习焊接,所以洞洞板的后面其实焊得跟块大便一样,就不做介绍了,核心思想就是用飞线各种飞。。。。。。好在利用万用表一直测,没有出现短路烧板子之类的坏现象,并且最后功能也都可以完成。

2、采用TCRT5000五路循迹模块实现循迹功能

单片机循迹模块

      循迹模块用的是TCRT5000五路循迹模块,便宜好用,非常nice,至少自己用来玩玩是可以的,如果比赛要用的话应该需要哪种灰度循迹模块(太贵了舍不得买),循迹函数的话中规中矩。

void Track_Correct(uint8_t RoadwayData)
{
	if(RoadwayData == 0x00)
	{
		Track_Flag=0;
		Stop_Flag=1;
		
	}else if(RoadwayData==0x1B)//11011
	{
		LSpeed=Car_Speed;
		RSpeed=Car_Speed;
		
	}else if(RoadwayData==0x1D)//11101
	{
		LSpeed=Car_Speed+20;
		RSpeed=Car_Speed-20;
		
	}else if(RoadwayData==0x19)//11001	有向右的大弯道
	{
		LSpeed=Car_Speed+20;
		RSpeed=Car_Speed-40;
		
	}else if(RoadwayData==0x18)//11000	有向右的直角弯道
	{
		LSpeed=Car_Speed;
		RSpeed=-Car_Speed;
		
	}else if(RoadwayData==0x1E)//11110
	{
		LSpeed=Car_Speed+40;
		RSpeed=Car_Speed-40;
		
	}else if(RoadwayData==0x17)//10111
	{
		LSpeed=Car_Speed-20;
		RSpeed=Car_Speed+20;
		
	}else if(RoadwayData==0x13)//10011	有向左的大弯道
	{
		LSpeed=Car_Speed-40;
		RSpeed=Car_Speed+20;
		
	}else if(RoadwayData==0x03)//00011	有向左的直角弯道
	{
		LSpeed=-Car_Speed;
		RSpeed=Car_Speed;
		
	}else if(RoadwayData==0x0F)//01111
	{
		LSpeed=Car_Speed-40;
		RSpeed=Car_Speed+40;
		
	}else 
	{
		LSpeed=Car_Speed;
		RSpeed=Car_Speed;
	}
	if(Track_Flag != 0)
	{
		Track_Go(LSpeed,RSpeed);
	}
}

3、超声波

超声波用的是一个HC-SR04超声波模块,实现了正向避障的功能,该模块有一个Trig引脚和Echo引脚,当给Trig触发引脚一个大于10us的高电平脉冲,则Echo会开始工作,模块会给出一个与距离等比的高电平脉冲信号,在Echo工作前清零计数器的计数值,并在电平重新变为低电平后获取计数值,就可以根据计数值的大小来计算距离。

单片机单片机
void Wave_TimerInit(void){			//超声波定时器初始化函数
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1,ENABLE);
	TIM_InternalClockConfig(TIM1);						
	
	TIM_TimeBaseInitTypeDef Timer_InitStructure;
	Timer_InitStructure.TIM_ClockDivision=TIM_CKD_DIV1;
	Timer_InitStructure.TIM_CounterMode=TIM_CounterMode_Up;
	Timer_InitStructure.TIM_Period=10000-1;
	Timer_InitStructure.TIM_Prescaler=7200-1;//7200Hz=0.0001s=0.1ms=10us
	Timer_InitStructure.TIM_RepetitionCounter=0;
	TIM_TimeBaseInit(TIM1,&Timer_InitStructure);
		
	//TIM_Cmd(TIM3,ENABLE);
}

void Wave_Init(void){	//超声波中断初始化函数
	
	Wave_TimerInit();

	GPIO_InitTypeDef GPIO_InitStructure;
	GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;
	GPIO_InitStructure.GPIO_Pin=GPIO_Pin_5;
	GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
	GPIO_Init(GPIOA,&GPIO_InitStructure);
	
	GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IPD;
	GPIO_InitStructure.GPIO_Pin=GPIO_Pin_11;
	GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
	GPIO_Init(GPIOA,&GPIO_InitStructure);

	GPIO_EXTILineConfig(GPIO_PortSourceGPIOA,GPIO_PinSource11);
	EXTI_InitTypeDef EXTI_InitStructure;
	EXTI_InitStructure.EXTI_Line=EXTI_Line11;
	EXTI_InitStructure.EXTI_LineCmd=ENABLE;
	EXTI_InitStructure.EXTI_Mode=EXTI_Mode_Interrupt;
	EXTI_InitStructure.EXTI_Trigger=EXTI_Trigger_Rising;
	EXTI_Init(&EXTI_InitStructure);
	
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
	NVIC_InitTypeDef NVIC_InitStructure;
	NVIC_InitStructure.NVIC_IRQChannel=EXTI15_10_IRQn;
	NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=1;
	NVIC_InitStructure.NVIC_IRQChannelSubPriority=1;
	NVIC_Init(&NVIC_InitStructure);
}

void Wave_Start(void){			//超声波开始函数
	if(Wave_Flag==1){
		GPIO_SetBits(GPIOA,GPIO_Pin_5);
		Delay_us(50);
		GPIO_ResetBits(GPIOA,GPIO_Pin_5);
	}
}

void Wave_Check(void){			//超声波避障实现函数
		if(Distance<=1300){
			Car_Stop();Delay_ms(500);
			Car_Back(60);Delay_ms(1000);
			Car_Stop();Delay_ms(500);
			Car_Left(40);
		}else if(Distance >=2000){
			Car_Go(Car_Speed);
		}
}

void EXTI15_10_IRQHandler(void){	//外部中断处理函数
	Delay_us(10);
	if(EXTI_GetITStatus(EXTI_Line11)!=RESET){
		TIM_SetCounter(TIM1,0);
		TIM_Cmd(TIM1,ENABLE);
		while(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_11));
		TIM_Cmd(TIM1,DISABLE);
		Distance=TIM_GetCounter(TIM1)*340/2.0;
		OLED_ShowNum(2,6,Distance,5);
		Wave_Check();
		EXTI_ClearITPendingBit(EXTI_Line11);
	}
}

4、总结

学习单片机以来的第一个小项目,也是受到了江科大的一期视频的启发,就决定复刻一下这个小车,后面还会再做一个遥控器,继续去完善,初学者我很菜,仅供参考。

审核编辑 黄宇

打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分