原理
当光电传感器识别到白线,发射的红外线大部分被白线反射而导致光电晶体管吸收红外线,光信号转换为电信号,达到导通的条件。于是信号输出端OUT直接与电源+5v接通,为高电频。反之,传感器识别到黑线时红外线大部分被黑线吸收,光电晶体管截止,OUT输出低电频。通过小车前面一排光电传感器传回的高低电频值来判断小车的偏移量,从而进行不同的调整,使得小车可以在固定的赛道内稳定行驶。
材料
STC89C52RC
ST188光电传感器
LM298N电机驱动
LM7805
3296W可调电阻
18650电池2-3节
电池盒
晶振、电阻、LED灯、开关、电容以及小车套件等
接线图
光电传感器模块
稳压模块(用来将电压稳定到5v)
单片机最小系统
电机驱动模块

程序代码
#include<reg51.h>
#define uchar unsigned char
#define uint unsigned int
unsigned char zkb1=0 ; //**左边电机的占空比**//
unsigned char zkb2=0 ; //**右边电机的占空比**//
unsigned char t=0; //**定时器中断计数器**//
sbit RSEN2=P1^0;
sbit RSEN1=P1^1;
sbit LSEN1=P1^2;
sbit LSEN2=P1^3;
sbit IN1=P0^0;
sbit IN2=P0^1;
sbit IN3=P0^2;
sbit IN4=P0^3;
sbit ENA=P0^4;
sbit ENB=P0^5;
//****************延时函数****************//
void delay(int z)
{
while (z--);
}
//**********初始化定时器,中断***********//
void init()
{
TMOD=0x01;
TH0=(65536-100)/256;
TL0=(65536-100)%256;
EA=1;
ET0=1;
TR0=1;
}
//***********中断函数+脉宽调制***********//
void timer0() interrupt 1
{
if(t<zkb1)
ENA=1;
else
ENA=0;
if(t<zkb2)
ENB=1;
else
ENB=0;
t++;
if(t>=100)
{t=0;}
}
//******************直行******************//
void qianjin()
{ zkb1=30; zkb2=30; }
//***************左转函数1***************//
void turn_left1()
{ zkb1=0; zkb2=50; }
//***************左转函数2***************//
void turn_left2()
{ zkb1=0; zkb2=60; }
//***************右转函数1***************//
void turn_right1()
{ zkb1=50; zkb2=0; }
//***************右转函数2***************//
void turn_right2()
{ zkb1=60; zkb2=0; }
//***************循迹函数*****************//
void xunji()
{ uchar flag;
if((RSEN2==1)&&(RSEN1==1)&&(LSEN2==1)&&(LSEN1==1))
{ flag=0;} //*******直行*******//
else if((RSEN2==0)&&(RSEN1==1)&&(LSEN2==1)&&(LSEN1==1))
{ flag=1;} //***左偏2,右转2***//
else if((RSEN2==0)&&(RSEN1==0)&&(LSEN2==1)&&(LSEN1==1))
{ flag=2;} //***左偏1,右转1***//
else if((RSEN2==1)&&(RSEN1==1)&&(LSEN2==0)&&(LSEN1==0))
{ flag=3;} //***右偏1,左转1***//
else if((RSEN2==1)&&(RSEN1==1)&&(LSEN2==0)&&(LSEN1==1))
{ flag=4;} //***右偏2,左转2***//
switch (flag)
{ case 0:qianjin();
break;
case 1:turn_right1();
break;
case 2:turn_right2();
break;
case 3:turn_left1();
break;
case 4:turn_left2();
break;
default: break;
}
}
//****************主程序****************//
void main()
{
init();
zkb1=30;
zkb2=30;
while(1)
{ IN1=1; //******给电机加电启动******//
IN2=0;
IN3=1;
IN4=0;
ENA=1;
ENB=1;
while(1)
{ xunji(); //*********寻迹**********//
}
}
}
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END
一发入魂
请登录后发表评论
注册
社交帐号登录