我是个萌新小白,还请各位大佬看到错误可以指出,谢谢啦!!
(1)准备工作:循迹小车用到的主要零件有:STC89C51单片机、L298N、TCRT5000红外反射传感器、HC-08蓝牙模块、12V可充电电池、两个电机和轮子、一个小车底盘、若干杜邦线等。
(2)理论分析:通过51单片机的io口来控制其他模块,从而来控制小车遇到什么情况对于传回的信号需要做出什么应对措施。在蓝牙控制方面,单片机通过蓝牙和手机进行通信,对手机发出的指令然后做出相应的动作。在寻迹方面,通过红外传感器接感应到轨迹然后转为数字信号传给单片机,使单片机做出相应的动作。
(3)主要模块功能介绍:
首先分析一下需要用到的模块的功能;
- :L289N模块,如下图是我用到的一个L289N的实物图。
可以用12V的电池来接12V供电口通过该模块来给整个小车供电,其中5V可以给单片机供电。IN1、IN2、IN3、IN4连接单片机来IO口,这里我连接的是单片机的P1.0、P1.1、P1.2、P1.3,可以通过单片机来输出高低电平来控制L289N模块中四个OUT的高低电平,从而来控制两个电机的正转和反转。因为要用到PWM调速,所以这里我取掉了L298N通道A、B使能的跳线帽,也用单片机来控制(P1^4,P1^5)。
- :TCRT5000红外反射传感器,如下图是我用的实物图。
该模块一共有四个引脚,分别为VCC、GND、DO、AO,其中VCC工作电压为3.3V-5V,但是在实际操作中发现该模块接在单片机的3.3V的输出口并不能使该传感器正常工作,接在5V上可以正常工作。DO:TTL开关信号输出。AO:模拟信号输出,AO在这次设计中不用,因此只需要连接DO即可。
TCRT5000 传感器的红外发射二极管不断发射红外线,当发射出的红外 线没有被反射回来或被反射回来但强度不够大时,红外接收管一直处于关断状态,此时模块的输出端为高电平,指示二极管一直处于熄灭状态; 被检测物体出现在检测范围内时,红外线被反射回来且强度足够大,红 外接收管饱和,此时模块的输出端为低电平,指示二极管被点亮。
反射回来 未反射回来或强度不大
- :HC-08蓝牙模块(带底板),实物图如下:
HC-08(带底板)总共有六个引脚,用到的有VCC、GND、RXD、TXD这四个引脚,前两个是给HC-08供电,后两个RXD和TXD与单片机的的RXD和TXD交叉连接,与单片机进行通信。工作电压是3.2V~6V,但是在实践中发现VCC接在单片机的3.3V引脚上不能工作(单片机这个引脚上的输出电压实际小于3.3V),所以接在单片机5V的输出口上。
(4):小车的各个模块间的具体工作以及连线。
如下是main.c代码:
#include<car.h>
extern unsigned char left_radio;
extern unsigned char right_radio;
extern unsigned char left_val_p;
extern unsigned char right_val_p;
unsigned char receive_data=0;
unsigned char receive_real_data=0;
char Work_Mode=0; //工作模式的选择 为0时为手机对小车进行蓝牙遥控 ,为1时小车自动循迹模式
void Timer0init()
{
EA = 1;
TR0 = 1;
TMOD |= 0x01;
TH0 = 0XDC;
TL0 = 0X00;
ET0 = 1;
}
void Timer1init1()
{
SCON=0X50; //设置为工作方式1
TMOD |=0X20; //工作方式2
PCON=0X00;
TH1=0XFd; //计数器初始值设置,9600 @11.0592MHz
TL1=0XFd;
TR1=1;
ES = 1;
EA = 1;
}
void main()
{
Timer1init1();
Timer0init();
left_radio = 4;
right_radio = 4;
while(1)
{
if(Work_Mode)
{
left_radio = 2;
right_radio = 2;
ES = 0;
if(L_sensor==1 && R_sensor == 1)
{run(); }
if( L_sensor == 0 && R_sensor)
{right();}
if(R_sensor == 0 && L_sensor)
{left();}
}
else
{
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; //转变为循迹功能
}
}
}
}
void Timer0() interrupt 1 using 2
{
TH0 = 0XFC;
TL0 = 0X67;
left_val_p++;
right_val_p++;
left_motor_pwm();
right_motor_pwm();
}
void Com_Int(void) interrupt 4
{
EA = 0;
if(RI == 1)
{
RI = 0;
receive_data = SBUF;
if(receive_data!=0)
receive_real_data = receive_data;
SBUF = receive_real_data;
while(!TI);
TI=0;
}
EA = 1;
}
car.h代码如下
#include<reg52.h>
#include <intrins.h>
sbit p10 = P1^0; //in1
sbit p11 = P1^1; //in2
sbit p12 = P1^2; //in3
sbit p13 = P1^3; //in4
sbit left_motor_pwm_stop = P1^4; //左轮调速 左使能
sbit right_motor_pwm_stop = P1^5; //右轮调速 右使能
sbit L_sensor = P0^0; //左红外寻迹检测
sbit R_sensor = P0^1; //右红外寻迹检测
void left_motor_pwm();
void right_motor_pwm();
void left_motor_go();
void left_motor_back();
void left_motor_stop();
void right_motor_go();
void right_motor_back();
void right_motor_stop();
void delay1s(void);
void Timer0init();
void run();
void back();
void left();
void right();
void stop();
motor_control代码如下:
#include<car.h>
unsigned char left_val_p = 0;
unsigned char left_val_s = 0;
unsigned char right_val_p = 0;
unsigned char right_val_s = 0;
unsigned char left_radio;
unsigned char right_radio;
void left_motor_go() //左电机正转
{p10=1;p11=0;}
void left_motor_back() //左反转
{p10=0;p11=1;}
void left_motor_stop() //左停止
{p10=1;p11=1;}
void right_motor_go() //右正
{p12=1;p13=0;}
void right_motor_back() //右反
{p12=0;p13=1;}
void right_motor_stop() //右停止
{p12=1;p13=1;}
void left_motor_pwm() //左轮调速
{
if(left_val_p<=left_val_s)
{
left_motor_pwm_stop = 1;
}
else
{
left_motor_pwm_stop = 0;
}
if(left_val_p>=10)
left_val_p = 0;
}
void right_motor_pwm() //右轮调速
{
if(right_val_p<=right_val_s)
{
right_motor_pwm_stop = 1;
}
else
{
right_motor_pwm_stop = 0;
}
if(right_val_p>=10)
right_val_p =0;
}
void run() //小车前进
{
right_val_s = right_radio;
left_val_s = left_radio;
left_motor_go();
right_motor_go();
}
void back() //小车后退
{
right_val_s = right_radio;
left_val_s = left_radio;
left_motor_back();
right_motor_back();
}
void left() //小车左转
{
right_val_s = 2;
left_motor_back();
right_motor_go();
}
void right() //小车右转
{
left_val_s = 2;
left_motor_go();
right_motor_stop();
}
void stop() //小车停止
{
left_motor_stop();
right_motor_stop();
}