基于STM32F407结合HC-SR04、TCRT5000模块 设计的智能小车(下篇)

开始语

书接上文 https://blog.csdn.net/canoe1996/article/details/121979751?spm=1001.2014.3001.5501,前面博主做了一个可以使用蓝牙遥控的小车,这几天因为项目上的事空下来,就把剩余的模块加上去了,让小车稍微“智能”了一点,下面直入主题:

超声测距与智能避障

HC-SR04模块简介与驱动程序

HC-SR04是市面上很常见的超声测距模块,4个口分别VCC接5V输入,GND,Trig触发口,Echo回响输入口
在这里插入图片描述
接下来看一下模块驱动图,首先使用MCU输出一个至少10us的信号至Trig口,模块内部会循环发出8个40Khz的脉冲,此后,Echo口会输出高电平,一直到输出的声波信号返回到模块,将Echo口接入MCU,用定时器记录输出回响信号,那么
距离 = 时间 * 声速(340m/s)/2
就可以计算出模块距离障碍物的距离,注意每次测量时间间隔200ms
在这里插入图片描述
按照前面驱动说明,下面是程序,这里直接定义了测距函数,使用TIM4为计时器,通过合适的分频和计数值,让定时器分辨率为1us,代码基本就是按照前面说的来写的,注释的也很清楚,这里我是取了5次平均来保证准确性,由于模块质量不太好,只能这样操作了。。。

float CS_front_distance(void)  //前方测距    单位为cm
{
	float length=0,sum=0; 
	u16 tim; 
	u8 i=0;
	
	while(i!=5)  //取5次平均
	{
		PCout(0)=1; 
		delay_us(20); 
		PCout(0)=0; //输出一个大于10us的高电平信号触发测距
		
		while(GPIO_ReadInputDataBit(GPIOC,GPIO_Pin_1)==RESET);
		TIM_Cmd(TIM4,ENABLE);

		i+=1; 
		while(GPIO_ReadInputDataBit(GPIOC,GPIO_Pin_1)==SET);
		TIM_Cmd(TIM4,DISABLE);  //记录回响时间

		tim=TIM_GetCounter(TIM4);

		length=(tim+overcount*1000)/58.0;  //1/58.0 为0.017 cm/us   计算距离

		sum=length+sum;
		TIM4->CNT=0; 
		overcount=0; 
		delay_ms(200);
	}
	length=sum/5;
	return length;


}


结合小车进行避障

这里就是实现一个检测前方有障碍物进行掉头的功能,下面是程序

//自动避障
	length[0]  = CS_front_distance();//将前方测距模块存放在0位置
  delay_ms(100);
		if(length[0] > 50) //如果前方距离大于50cm,保持直行
		{
		car_go_medium();
		}
		if(length[0] < 50) //如果前方距离小于50cm,掉头
		{
		car_stop();
		delay_ms(100);
		car_back();
		delay_ms(100);
		length[1]  = CS_left_distance();//测左边距离
		length[2]  = CS_Right_distance();//测右边距离
			if(length[1] > length[2] )
			{
				//如果左边距离大于右边距离,且都大于50cm,则向右掉头
				car_Left_circle();
				delay_ms(300);
			}
			if(length[2] > length[1] )
			{
				//否则向左掉头
				car_Right_circle();
				delay_ms(300);
			}
			
		
		}
		

红外TCRT模块与循迹

TCRT5000模块简介与驱动程序

这个模块就比较简单了,原理就是模块供电后不断发射红外光线,如果发射到黑色物体上,由于黑色吸收红外线,则模块接收不到反射回来的红外光,此时D0口输出高电平;如果发射到其他颜色的物体上,模块就会接收到反射回来的红外线,此时D0口输出低电平。
在这里插入图片描述
根据前面说的原理,驱动程序如下,首先是初始化PC6 和PC7为输入模式,然后通过GPIO_ReadInputDataBit()函数读取模块D0的状态

void trace_IO_init(void)
{

	GPIO_InitTypeDef  GPIO_InitStructure;

  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);//使能GPIOC时钟

	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6  | GPIO_Pin_7  ;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;//普通输入模式
  GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;//推挽输出
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;//100MHz
  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;//上拉
  GPIO_Init(GPIOC, &GPIO_InitStructure);//初始化
  GPIO_ResetBits(GPIOD,GPIO_Pin_6);//GPIOC0设置低
	GPIO_ResetBits(GPIOD,GPIO_Pin_7);//GPIOC1设置低
}

u16 Read_xunji_L_data(void)
{
	
   L = GPIO_ReadInputDataBit(GPIOD,GPIO_Pin_6);

	return L;

}

结合小车实现循迹

由于我只买了2个TCRT5000,实际上是需要很多的模块放置在车头来进行探测,提高循迹的灵敏性;在车头左右各放置一个模块进行探测,程序如下,注释的很清楚:

//循迹
	
	L1 =  Read_xunji_L_data();
	R1 =  Read_xunji_R_data();		
		if(L1 == 1 && R1 ==1 ) // 如果左右检测到高电平,则说明左右都在黑线上,保持直行即可
		{
			car_go_medium();
			delay_ms(100);
		}
		if(L1 == 1 && R1 ==0 ) // 如果左高右低,则说明右边不在黑线上,应该向左行驶
		{
			car_left();
			delay_ms(100);
		}
		
		if(L1 == 0 && R1 ==1 ) // 如果左低右高,则说明左边不在黑线上,应该向右行驶
		{
			car_right();
			delay_ms(100);
		}
		
		if(L1 == 0 && R1 ==0 ) // 如果都不在黑线上,则停止
		{
			car_stop();
			delay_ms(100);
		}

结束语

总结一下
现在算是基本完成了智能小车,但基本功能都有,蓝牙遥控,智能避障,循迹,算是告一段落了;
如果后面要参加比赛的话,优化方向,硬件上就是画块PCB,做一个STM32F4的最小系统,将模块全部集成在板上,尝试加入摄像头,做图像识别(这个可能要用FPGA来做,比较难的了);程序上的话,就是不断调试优化,加入PID算法,让小车行驶的更舒适,要做好的话也需要很多时间;
这是我学习STM32F4大半年以来完成的一个项目,在此对C站上大佬们写的博客表示感谢,学习过程中在C站找到很多答案,自己以后也会多更博客,总结分享自己的嵌入式学习道路,大家有什么问题和意见都可以在评论区留言,共同学习,一起进步~

  • 9
    点赞
  • 58
    收藏
    觉得还不错? 一键收藏
  • 23
    评论
评论 23
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值