一、制作过程中的问题与解决方案
1.导线与马达链接不牢固
此种情况可使用电烙铁焊接的方式进行加固,但由于焊接完成后很难更改,请务必提前规划好导线的连接与排布。
2.蓝牙程序无法下载进单片机
注意在烧录程序时将蓝牙取下,否则电脑可能无法识别单片机。若仍无法下载,请注意P30与P31口是否被占用。
3.小车无法通过蓝牙接受指令
请注意波特率是否正确,不同型号蓝牙波特率可能不同,可以在电脑上利用串口助手向蓝牙发送信息来验证波特率
如果仍无法解决,请检查输出波特率的定时器代码是否正确,stc-isp上生成的可能无法使用
可尝试以下代码
void Uart_Init()
{
PCON &= 0x7F;
SCON = 0x50;
TMOD &= 0x0F;
TMOD |= 0x20;
TL1 = 0xFD;
TH1 = 0xFD;
ET1 = 0;
TR1 = 1;
EA=1;
ES = 1;
}
4.两电机转速不同
此种问题较为普遍,可设置两个比较值来分别控制两电机转速,但收效甚微。四电机小车可能不存在此种问题或影响较小。
5.蓝牙控制时超声波避障无法停止
此问题目前尚未解决,推测是定时器未调试完成,经过舍友3人4天的尝试,决定放弃。
二、各模块代码
1.电机驱动模块
#include <REGX52.H>
unsigned char Counter,Compare1,Compare2;
sbit EN1A = P0^7;//左轮
sbit EN1B = P0^2;//右轮
void Timer0Init(void) //100微秒@11.0592MHz
{
TMOD=0x21;
TH0=65436/256; //11111111
TL0=65436%256; //01111000
TF0=0;//清除FTO标志
TR0=1;//开始计时
ET0=1;
EA=1;
PT0=1;
}
void Timer0_Routine() interrupt 1
{
TH0=65436/256;
TL0=65436%256;
Counter++;
Counter%=100;
if(Counter<Compare1)
{
EN1A = 1;
}
else
{
EN1A = 0;
}
if(Counter<Compare2)
{
EN1B = 1;
}
else
{
EN1B = 0;
}
}
sbit IN11=P0^6;//左轮
sbit IN12=P0^5;
sbit IN13=P0^4;//右轮
sbit IN14=P0^3;
void L_motor_go2()
{Compare1=20;IN11 = 0;IN12 = 1;}
void R_motor_go2()
{Compare2=20;IN13 = 0;IN14 = 1;}
void L_motor_back()
{Compare1=20;IN11 = 1;IN12 = 0;}
void R_motor_back()
{Compare2=20;IN13 = 1;IN14 = 0;}
void L_motor_stop()
{IN11 = 1;IN12 = 1;}
void R_motor_stop()
{IN13 = 1;IN14 = 1;}
2.行走模块
#include <REGX52.H>
#include "motor.h"
void car_go()
{
L_motor_go2();
R_motor_go2();
}
void car_back()
{
L_motor_back();
R_motor_back();
}
void car_stop()
{
L_motor_stop();
R_motor_stop();
}
void car_leftgo()//向前左转
{
R_motor_go2();
L_motor_stop();
}
void car_rightgo()//向前右转
{
R_motor_stop();
L_motor_go2();
}
void car_leftstop()//原地左转
{
L_motor_back();
R_motor_go2();
}
void car_rightstop()//原地右转
{
L_motor_go2();
R_motor_back();
}
3.循迹模块
#include <REGX52.H>
#include <intrins.h>
#include "car.h"
sbit D1 = P2^7;
sbit D2 = P2^6;
void xunji()
{
if(D1==1&&D2==1)//检测到黑线
{car_go();}
if(D1==1&&D2==0)//左侧检测到黑线
{
car_leftstop();
if(D1==1&&D2==1)
{car_go();}
}
if(D1==0&&D2==1)//右侧检测到黑线
{
car_rightstop();
if(D1==1&&D2==1)
{car_go();}
}
if(D1==0&&D2==0)//未检测到黑线
{car_go();}
}
4.超声波避障模块
#include <REGX52.H>
#include "car.h"
#include "xunji.h"
#include <intrins.h>
sbit Trig=P2^0;
sbit Echo=P2^1;
unsigned int Time;
unsigned char Distance;
void Delay10us() //@11.0592MHz
{
unsigned char i;
i = 2;
while (--i);
}
void Delay300us() //@11.0592MHz
{
unsigned char i;
_nop_();
i = 135;
while (--i);
}
void HCSR()
{
TMOD = 0x10; //设置定时器模式
PT1=1;
TL1=1; //设置定时器初始值
TH1=1; //设置定时器初始值
Trig=1; //发射一段脉冲
Delay10us();
Trig=0;
while(Echo==0); //等待超声波模块返回脉冲
TR1=1; //打开定时器
while(Echo==1); //等待超声波模块返回脉冲结束
TR1=0; //停止定时器,计时结束
Time=TH1*256+TL1; //计算距离
Distance=(Time*0.034)/2;//计算距离
if(Distance<20)
{
car_stop();
Delay300us();
if(Distance<20)
{
car_rightstop();
}
}
else
{
car_go();
}
}
5.主函数及蓝牙控制
#include <REGX52.H>
#include "car.h"
#include "xunji.h"
#include "chaoshengbo.h"
#include "motor.h"
unsigned char Data;
unsigned int mode;
void receive(unsigned char Data)
{
switch(Data)
{
case '2':
mode=1;
break;
case '4':
mode=2;
break;
case '6':
mode=3;
break;
case '8':
mode=4;
break;
case '5':
mode=5;
break;
case '7':
mode=6;
break;
case '9':
mode=7;
break;
case '1':
mode=8;
break;
case '3':
mode=9;
break;
}
}
void Uart_Init()
{
PCON &= 0x7F; //波特率不倍速
SCON = 0x50; //8位数据,可变波特率
TMOD &= 0x0F;
TMOD |= 0x20;
TL1 = 0xFD; //设定定时初值
TH1 = 0xFD; //设定定时器重装值
ET1 = 0; //禁止定时器1中断
TR1 = 1; //启动定时器1
EA=1;
ES = 1; //打开串口中断
}
void Uart_Routine() interrupt 4
{
car_stop();
RI = 0;
Data=SBUF;
receive(Data);
}
void main()
{
Uart_Init();
Timer0Init();
while(1)
{
if(mode==1)
{
car_go();
}
if(mode==2)
{
car_leftgo();
}
if(mode==3)
{
car_rightgo();
}
if(mode==4)
{
car_back();
}
if(mode==5)
{
car_stop();
}
if(mode==6)
{
car_leftstop();
}
if(mode==7)
{
car_rightstop();
}
if(mode==8)
{
xunji();
}
if(mode==9)
{
HCSR();
}
}
}
三、结语
此智能车的制作较为简陋,代码也较于简单粗暴,但大致思路正确,因此此博客中的解决方法及代码部分仅供参考,请勿照搬,否则可能无法运行
参考教学视频:B站 江协科技 BV1Mb411e7re
B站 HBSTU自动化 BV16S4y1C7ad