巡线代码如下,模块化代码可通过B站视频学习,我代码通过大量的delay,达到车身不断微调摇晃的效果从而巡线,我小车内无配置PID,因为硬件不允许,所以导致小车很抖低速地巡线,后续我会再进行改进。同时代码通过key,用单片机对小车是否启动循迹进行控制,按一下独立按键后开关动,再按一下开关小车停止,此时通过控制小车的电机输出引脚来控制小车的运动状态。电机输出引脚也来控制小车的左转前进右转之类的运动状态。代码还通过定时器控制使能引脚,达到控制电机PWM的效果。
#include <REGX52.H>
#include "delay.h"
#include "Timer0.h"
#include "LCD1602.h"
#include "car.h"
#include "Key.h"
sbit IN1 =P1^1;
sbit IN2 =P1^2;
sbit IN3 =P1^4;
sbit IN4 =P1^3;
sbit ENB = P1^0;
sbit ENA = P1^5;
sbit D1=P2^0; //最左边的红外传感器
sbit D2=P2^1;
sbit D3=P2^2;
sbit D4=P2^3;
unsigned char PWMA,PWMB,time;
unsigned char keynum=0,speed=0;
void main()
{
Timer0_Init();
while(1)
{
PWMA =0;
PWMB =0;
delay(1);
keynum=Key();
if(keynum==1)
{
speed++;
speed%=2;
}
if(speed==1)
{
if (D1==1 && D2==1 && D3==1 && D4==1) //悬空时候
{
PWMA =0;
PWMB =0;
stop();
}
if (D1==0 && D2==1 && D3==1 && D4==0) //平地
{
PWMA =21.0;
PWMB =21.0;
turn_right();
delay(30);
turn_left();
delay(30);
}
if(D1==0 &&D2==0&&D3==1&&D4==0) //偏右向左调整前进
{
PWMA=20.9;
PWMB=21.0;
turn_right();
delay(3);
}
if(D1==0 &&D2==1&&D3==0&&D4==0)//偏左向右调整前进
{
PWMA=21.0;
PWMB=20.9;
turn_left();
delay(4);
}
if((D1==1 &&D2==1&&D3==0&&D4==0)||(D1==1 &&D2==1&&D3==1&&D4==0)) //左直角转弯
{
PWMA=20.0;
PWMB=19.9;
turn_str();
delay(30);
turn_left();
delay(190);
}
if((D1==0 &&D2==1&&D3==1&&D4==1)||(D1==0 &&D2==0&&D3==1&&D4==1)) //右直角转弯
{
PWMA=20.0;
PWMB=19.9;
turn_str();
delay(30);
turn_right();
delay(190);
}
if(D1==0 &&D2==0&&D3==0&&D4==1) //严重偏离航线,往右大调整
{
PWMA=21.0;
PWMB=20.9;
turn_right();
delay(40);
}
if(D1==1 &&D2==0&&D3==0&&D4==0) //严重偏离航线,往左大调整
{
PWMA=21.0;
PWMB=20.9;
turn_left();
delay(40);
}
}
if(speed==0)
{
IN1=0;IN2=0;IN3=0;IN4=0;
}
}
}
void Timer0_Rountine() interrupt 1 //0.1ms
{
static unsigned int T0count; //在静态区的局部变量,占内存,退出函数还会存在,不丢失
TL0 = 0x9C; //设置定时初值
TH0 = 0xFF; //设置定时初值
T0count++;
T0count %=100;
if(T0count>PWMA)
{
ENA=0;
}
else
{
ENA =1;
}
if(T0count>PWMB)
{
ENB=0;
}
else
{
ENB=1;
}
}