51单片机蓝牙遥控麦轮小车

一直以来就有想法自己做一个小车玩玩,但是一直没提上日程,这次寒假是个很好的机会,在这里把过程中的一些心得和资源分享给大家,源程序将在文末贴出来供大家参考

硬件部分

底盘

底盘用的是某宝现成的底盘,之前在学校比赛用的是亚克力板,这次选用的是铝合金材料的,怎么造也不会坏,也不贵,一二十块钱吧
在这里插入图片描述

麦克纳母轮

在选轮子的时候首先想到的就是麦轮,不仅可以实现全向移动,看起来逼格也更高,选购的时候一定要分清楚左轮和右轮,因为左轮和右轮在旋转时产生的分力是不一样的,想要小车向某一个方向移动,必须抵消掉其他方向的力,否则小车将不受控制我采用的是ABAB式安装,这也是常用的组装方法
在这里插入图片描述

减速电机

减速电机种类和样式简直是五花八门,价格也是参差不齐,有高标准的小伙伴们建议多了解一下这里面的套路,我用的是最最最普通的TT电机,速度不是很快,加5V电压的话转速在190r/min左右,主要是性价比让我动心,尤其是对于经济困难的我来说,这种几块钱一个的电机再合适不过了,另外一个要注意的是电机和轮子连接着一块要着重看看
在这里插入图片描述

主控模块

原本是准备用stm32的板子的,但是还没学完,就先用51单片机凑合用,其实对于玩玩来说51就够了,编程也简单,这次不是用的传统的带底座的单片机,而是选择了一款新的贴片封装的,看起来要轻巧一些,其实功能都一样,只是这款的TXD和RXD没有标注出来,学过的朋友应该知道其实就是P30和P31两个IO口,关于单片机的知识我不多说,不会的朋友请先简单学习学习,另外,这款板子容易自锁,导致stc一直检测不到单片机,这时候只需要把P10和P11两个IO口同时接地即可,源程序将在文末贴出来
在这里插入图片描述

电源模块

电源标称电压5V就够了,重点是要容量大,我用的是4000mAh的,容量太小跑一会儿就没电了影响体验
在这里插入图片描述

驱动模块

我选择的是一个集成的四路驱动,其他都挺好,可能散热差一点,有条件的可以选其他带散热片的驱动,驱动的选择不会影响程序的编写
在这里插入图片描述

蓝牙模块

蓝牙模块也有很多种,我用的是蓝牙2.0的HC-06主从一体模块,某宝上价格不一,推荐在经常去的店买,有保障,相对于HC-05来说这款更简便,上电就是AT模式,AT指令集我放在下面的链接里了,自取,手机端用的是SPP蓝牙助手
在这里插入图片描述
在这里插入图片描述

链接:https://pan.baidu.com/s/1RxVXp85P2vCJ9Oy9LTLdzA
提取码:YYDS

舵机

SG90舵机,需要给定持续输出的占空比0.5MS~2.5MS、周期20MS的方波才能转动,0.5MS对应-90°,2.5MS对应90°,SG90舵机角度极限是180°
在这里插入图片描述

软件部分

软件以及串口驱动

编译软件:Keil4
烧录软件:stc-isp
串口驱动:CH340

源程序

/**************************************************************
***名称:         蓝牙遥控小车
***作者:         ZhangGe0404
***创作日期:     2021.1.19
***晶振:		  12M
/*************************************************************/
#include<reg52.h>
#include<intrins.h>

sbit In1=P2^0; //左前电机
sbit In2=P2^1;
sbit In3=P2^2; //右前电机
sbit In4=P2^3;
sbit In5=P2^4; //左后电机
sbit In6=P2^5;
sbit In7=P2^6; //右后电机
sbit In8=P2^7;

sbit SG_PWM=P1^5;//舵机控制端

#define uchar unsigned char  //宏定义
/*****************************
***定义全局变量
/****************************/
uchar count=0;		 //计数变量
uchar PWM_count=15;	 //预设变量
uchar a=0;

/**************************************************
***初始化定时器函数
/*************************************************/
void Timer_Init()	
{
    
    
	TMOD=0x01;			 //设置定时器模式为1
	TH0=0xfe;
	TL0=0xa4;			 //设置定时器初值为0.1MS
	ET0=1;				 //打开定时器0中断
	TR0=1;				 //定时器0开始计时
	EA=1;				 //开总中断
}

/*************************************************
***定时器0中断处理函数
/************************************************/
void Timer() interrupt 1	 
{
    
    
TR0=0;						   //停止计时
TH0=0xfe;
TL0=0xa4;					   //重装初值
	if(count <= PWM_count)
		{
    
    
			SG_PWM=1;				   //舵机控制端给高电平
		}
		else
		{
    
    
			SG_PWM=0;				   //低电平
		}
		count++;
	if(count >= 200)		   //周期20MS
		{
    
    
			count=0;
			a++;
		}
TR0=1;
}
/************************************************
***前进
/***********************************************/
void forward()
{
    
    
	In1=1;
	In2=0;
	In3=1;
	In4=0;
	In5=1;
	In6=0;
	In7=1;
	In8=0;
}

/************************************************
***整体左行
/***********************************************/
void left()
{
    
    
	In1=0;
	In2=1;
	In3=1;
	In4=0;
	In5=1;
	In6=0;
	In7=0;
	In8=1;
}

/************************************************
***整体右行
/***********************************************/
void right()
{
    
    
	In1=1;
	In2=0;
	In3=0;
	In4=1;
	In5=0;
	In6=1;
	In7=1;
	In8=0;
}

/************************************************
***后退
/***********************************************/
void back()
{
    
    
	In1=0;
	In2=1;
	In3=0;
	In4=1;
	In5=0;
	In6=1;
	In7=0;
	In8=1;
}

/************************************************
***整体左旋
/***********************************************/
void tleft()
{
    
    
	In1=0;
	In2=1;
	In3=0;
	In4=1;
	In5=1;
	In6=0;
	In7=1;
	In8=0;
}

/************************************************
***整体右旋
/***********************************************/
void tright()
{
    
    
	In1=1;
	In2=0;
	In3=1;
	In4=0;
	In5=0;
	In6=1;
	In7=0;
	In8=1;
}

/************************************************
***向左前方
/***********************************************/
void lefor()
{
    
    
	In1=1;
	In2=0;
	In3=0;
	In4=0;
	In5=0;
	In6=0;
	In7=1;
	In8=0;
}

/************************************************
***向右前方
/***********************************************/
void rifor()
{
    
    
	In1=0;
	In2=0;
	In3=1;
	In4=0;
	In5=1;
	In6=0;
	In7=0;
	In8=0;
}

/************************************************
***向左后方
/***********************************************/
void leback()
{
    
    
	In1=0;
	In2=1;
	In3=0;
	In4=0;
	In5=0;
	In6=0;
	In7=0;
	In8=1;
}

/************************************************
***向右后方
/***********************************************/
void riback()
{
    
    
	In1=0;
	In2=0;
	In3=0;
	In4=1;
	In5=0;
	In6=1;
	In7=0;
	In8=0;
}

/************************************************
***停止
/***********************************************/
void ting()
{
    
    
	In1=0;
	In2=0;
	In3=0;
	In4=0;
	In5=0;
	In6=0;
	In7=0;
	In8=0;
}
/************************************************
***串口中断初始化
/***********************************************/
void UsartConfiguration()
{
    
    
	SCON=0x50;		//设置工作方式1 开启接受允许
	TMOD=0x20;		//设置T1工作方式为2
	PCON=0x00;		//波特率不倍增
	TH1=0xfd;		//设置计数器1初值,决定波特率
	TL1=0xfd;
	TR1=1;			//打开计数器1
	ES=1;			//打开串口接收中断
	EA=1;			//开总中断

}

/************************************************
***串口中断处理函数
/***********************************************/
void Com_Int(void) interrupt 4
{
    
    
	uchar receive_data;				   //定义数据接收存储变量
	EA=0;							   //关总中断
	if(RI == 1)						   //是否接受到数据
		{
    
    
			RI=0;							   //标志位清零
			receive_data=SBUF;				   //数据暂存

			if(receive_data == '1')
				{
    
    
					forward();
				}
			else if(receive_data == '2')
				{
    
    
					back();
				}
			else if(receive_data == '3')
				{
    
    
					left();
				}
			else if(receive_data == '4')
				{
    
    
					right();
				}
			else if(receive_data == '5')
				{
    
    
					tleft();
				}
			else if(receive_data == '6')
				{
    
    
					tright();
				}
			else if(receive_data == '7')
				{
    
    
					lefor();
				}
			else if(receive_data == '8')
				{
    
    
					rifor();
				}
			else if(receive_data == '9')
				{
    
    
					leback();
				}
			else if(receive_data == 'a')
				{
    
    
					riback();
				}
			else if(receive_data == '0')
				{
    
    
					ting();
				}
			else if(receive_data == 'c')
				{
    
    
					PWM_count=5;
				}
			else if(receive_data == 'd')
				{
    
    
					PWM_count=25;
				}
		}
	EA=1;								//重新打开总中断
}

/************************************************
***主函数
/***********************************************/
void main(void)
{
    
    
		Timer_Init();
		UsartConfiguration();
		while(1);

}

总结

成果展示

在这里插入图片描述

心得体会

在整个搭车过程中还是遇到了很多困难,比如蓝牙模块的调试,最初经常意外断开连接,检查才发现是供电电压太高,除此之外,单片机的自锁也很头疼,商家解决不了,通过不断的搜索才找到解决方案,做一辆车的过程其实也是一个锻炼心智的过程,不断的试错,不断的更新换代,这一切光靠一腔热血是换不来的,还要有扎实的技术基础和敏捷的思维,看着自己一点一点做出来的车正常跑的时候,心里是甜的,希望这篇文章能给志同道合的朋友提供一点参考,少走弯路。

#####部分图片来源于网络,如有侵权,联系删除#####

猜你喜欢

转载自blog.csdn.net/gfdgf11/article/details/113181233
今日推荐