我会通过本系列文章,详细介绍如何从零开始用51单片机去实现智能小车的控制,在本系列的上一篇文章中介绍了如何通过手机蓝牙去控制智能小车,但是存在加减速指令异常的错误,本文主要介绍出现错误的原因,及改正方法。 本系列文章链接:
详细介绍如何从零开始制作51单片机控制的智能小车(一)———让小车动起来 详细介绍如何从零开始制作51单片机控制的智能小车(二)———超声波模块、漫反射光电管、4路红外传感器的介绍和使用 详细介绍如何从零开始制作51单片机控制的智能小车(三)———用超声波模块和漫反射光电传感器实现小车的自动避障 详细介绍如何从零开始制作51单片机控制的智能小车(四)———通过蓝牙模块实现数据传输以及通过手机蓝牙实现对小车运动状态的控制 详细介绍如何从零开始制作51单片机控制的智能小车(五)———对本系列第四篇文章介绍的手机蓝牙遥控加减速异常的错误的介绍及纠正 1、原因一 :由HC-COM所带来的错误 原因之一是HC-COM这个app的问题,他一下发送的是20个数,初始阶段设定为最大车速的50%,按程序来说是每收到一个5(加速指令),车速增加10%,每收到一个6(减速指令)车速减少10%,但是我们在用HC-COM输入一个5或者6的时候发送给单片机的时候,它实际上接收到的是20个5或者20个6,相当于执行了20次车速增加10%,或者减少10%,由于加减速在程序中进行了限幅,会加速到车速的最大值,和最小值,最小值车速为0。 2、对错误原因一 的纠正方法 通过修改加减速函数来纠正,原来的加减速函数如下:
void Speed_add() //加速函数
{
if(Left_Speed_Ratio<10) //限幅
{
Left_Speed_Ratio++;
Right_Speed_Ratio++;
}
}
void Speed_reduce() //减速函数
{
if(Left_Speed_Ratio>0) //限幅
{
Left_Speed_Ratio--;
Right_Speed_Ratio--;
}
}
我们通过设定一个累加的静态变量来纠正,纠正后的加减速函数如下:
void Speed_add() //加速函数
{
static int i=0;
i=i+1;
if(i==20) //因为每次接收到的是20个加速信号,这样就是每接收到20个加速信号,也就是每发送一个5,增加最大车速的10%
{ //将20这个常量就可以调节每次 增速的大小,比如把20改为10,则每发送一个5,增加最大车速的20%
i=0;
if(Left_Speed_Ratio<10)
{
Left_Speed_Ratio++;
Right_Speed_Ratio++;
}
}
}
void Speed_reduce() //减速函数
{
static int j=0;
j=j+1;
if(j==20) //因为每次接收到的是20个减速信号,这样就是每接收到20个减速信号,也就是每发送一个5,减小最大车速的10%
{ //将20这个常量就可以调节每次 减速的大小,比如把20改为10,则每发送一个5,减小最大车速的20%
j=0;
if(Left_Speed_Ratio>0)
{
Left_Speed_Ratio--;
Right_Speed_Ratio--;
}
}
}
3、原因二 :由while(1)循环所带来的错误 在进行了以上的修正后发现,问题还是没有得到解决,出错的原因之二是while(1)循环带来的,当我们通过手机蓝牙发送指令之后,在下一次发送之前receive_real_data的值将不再改变,原来主函数中的控制指令如下:
switch(receive_real_data)
{
case '1': run(); break;
case '2': left(); break;
case '3': right(); break;
case '4': back(); break;
case '5': Speed_add(); break;
case '6': Speed_reduce(); break;
case '7': stop(); break;
case '8': Work_Mode=1; break;
}
由于他在while(1)循环中,所以当我们发出加减速指令的时候,在发出下一次指令之前receive_real_data的值不变,从而在while(1)循环的作用下,不断地加速减速,直至到限幅的最大值和最小值,所以我们不能吧加减速指令的执行放在while(1)循环中。 4、对错误原因二的纠正方法 我们直接在主函数中删去对指令5和6的控制,如下(主函数的其他地方不用修改)
switch(receive_real_data)
{
case '1': run(); break;
case '2': left(); break;
case '3': right(); break;
case '4': back(); break;
case '7': stop(); break;
case '8': Work_Mode=1; break;
}
我们把5和6(加减速的控制指令)放到串口中断里面,原来的串口中断函数如下:
void Com_Int(void) interrupt 4
{
EA = 0;
if(RI == 1) //当硬件接收到一个数据时,RI会置位
{
LED=0;
RI = 0;
receive_data = SBUF;//接收到的数据
if(receive_data!=0)
receive_real_data=receive_data;
SBUF=receive_real_data;//将接收到的数据放入到发送寄存器
while(!TI); //等待发送数据完成
TI=0; //清除发送完成标志位
}
EA = 1;
}
纠正后的串口中断函数如下(新增了一个switch语句,其他地方未修改):
void Com_Int(void) interrupt 4
{
EA = 0;
if(RI == 1) //当硬件接收到一个数据时,RI会置位
{
LED=0;
RI = 0;
receive_data = SBUF;//接收到的数据
if(receive_data!=0)
receive_real_data=receive_data;
switch(receive_real_data) //新增的switch函数
{
case '5': Speed_add(); break;
case '6': Speed_reduce(); break;
}
SBUF=receive_real_data;//将接收到的数据放入到发送寄存器
while(!TI); //等待发送数据完成
TI=0; //清除发送完成标志位
}
EA = 1;
}
5、总结一下修改的地方 (1)修改了motor_control.c文件中的加减速函数 (2)删去了main.c文件中main函数switch语句内对加减速指令的控制 (3)在main.c文件中Com_Int(void)函数内增加了对加减速控制的switch语句 纠正后的完整代码的keil文件我会放到附件里,需要者自取,还是那句话,我放的时候都是免费的,但是它会自己涨,需要的可以评论区留言,我直接发给你 三个修改都很简单,大家可以直接在本系列第四篇文章的程序的基础上进行以上的3个简单修改,也可以直接下载本篇博文的附件(也就是已经修改好了的) 欢迎大家积极交流,本文未经允许谢绝转载