基于51单片机的循迹小车设计与实现
材料的选择:
使用材料:stc89c52rc单片机一个

L298N电机驱动模块:
四路循迹模块:
车架电机轮子:
杜邦线若干,电池,开关按钮:
小车接线图:
循迹模块连接单片机电源,可以将单片机5v和GND引到面包板上。
搭建好的整体结构:
代码部分:
#include<reg52.h>
#include "Delay.h"
#include "Timer0.h"
typedef unsigned int uint;
typedef unsigned char uchar;
uchar left,right; //左右占空比标志,取1-100
uchar i=0,j=0; //调速计时间
uchar flag; //用于循迹方向的判断
sbit IN1=P2^4; //右电机 //使IN1~IN4端通过杜邦线接到不同的P口,这里我接的是P2
sbit IN2=P2^5; //其中IN1、IN2控制电机M1;IN3、IN4控制电机M2
sbit IN3=P2^6;//左电机
sbit IN4=P2^7;
sbit ENA = P2^1; //用于pwm调速
sbit ENB = P2^0;
sbit sw1=P3^ 7;//四个灰度传感器,分别对应四个位置
sbit sw2=P3^ 6;
sbit sw3=P3^5;
sbit sw4=P3^4;
//小车直行速度赋值
void forward_move()
{
left=17;//PWM调速,值越大,电机速度越快
right=17;
IN1=1; //两个电机均正转
IN2=0;
IN3=1;
IN4=0;
}
//小车停止
void stop()
{
left=0;
right=0;
IN1=0;
IN2=0;
IN3=0;
IN4=0;
}
//小车左转速度赋值(用于左边传感器检测到黑线)
void Left_turning()
{
left=28;
right=30;
IN1=1; //两个电机一个正转一个反转(或者一个正转一个不转)
IN2=0;
IN3=0;
IN4=1;
}
//小车右转速度赋值(用于右边传感器检测到黑线)
void Right_turning()
{
left=30;
right=28;
IN1=0; //两个电机一个正转一个反转(或者一个正转一个不转)
IN2=1;
IN3=1;
IN4=0;
}
//循迹模块
void xunji()
{
if((sw1==0)&&(sw3==0)&&(sw2==1)&&(sw4==1))
{
flag = 0;//直行
}
else if((sw1==0)&&(sw3==1)&&(sw2==1)&&(sw4==1))
{
flag = 1;//直行偏右,调节直行偏移
}
else if((sw1==1)&&(sw3==0)&&(sw2==1)&&(sw4==1))
{
flag = 2;//直行偏左
}
else if((sw3==0)&&(sw2==0)&&(sw4==1))
{
flag = 3;//左转
}
else if((sw3==1)&&(sw2==0)&&(sw4==1))
{
flag = 4;//左转2
}
else if((sw1==0)&&(sw3==0)&&(sw2==1)&&(sw4==0))
{
flag = 5;//右转
}
else if((sw1==1)&&(sw3==0)&&(sw2==1)&&(sw4==0))
{
flag = 6;//右转2
}
else if((sw1==1)&&(sw3==1)&&(sw2==1)&&(sw4==1))
{
flag = 7;//直行
}
else if((sw1==1)&&(sw3==1)&&(sw2==1)&&(sw4==0))
{
flag = 8;//右转3
}
else if((sw1==1)&&(sw3==1)&&(sw2==0)&&(sw4==1))
{
flag = 9;//左转3
}
else
{
flag = 10;
}
switch(flag)
{
case 0: forward_move();break;
case 1: Left_turning();break;
case 2: Right_turning();break;
case 3: Left_turning();break;
case 4: Left_turning();break;
case 5: Right_turning();break;
case 6: Right_turning();break;
case 7: forward_move();break;
case 8: Right_turning();break;
case 9: Left_turning();break;
case 10: forward_move();break;
default: forward_move();break;
}
}
void main()
{
Timer0_Init();
while(1)
{
xunji();
}
}
void Timer0_Rountine() interrupt 1 //定时器0中断,用于pwm调速
{
TL0 = 0xA4; //设置定时初值
TH0 = 0xFF; //设置定时初值
i++;
j++;
if(i<=left)//设置左轮占空比,即左轮速度
ENA=1;
else
ENA=0;
if(j<=right)
ENB=1;
else
ENB=0;
if(i==100) //设置pwm周期=0.1ms*100=10ms,这样开头定义的变量正好表示占空比数值
{
i=0;//加到100后变为0,重新计数
}
if(j==100)
{
j=0;
}
}
打开百度网盘,直接下载项目工程文件 链接:https://pan.baidu.com/s/1q7UVJ5SifeuI4uncI4bNrQ
提取码:tzmj
效果演示:
51循迹小车