目录
循迹小车
1. 循迹模块使用
2. 循迹小车原理
3. 循迹小车开发和调试代码
循迹小车
1. 循迹模块使用
- TCRT5000传感器的红外发射二极管不断发射红外线
- 当发射出的红外线没有被反射回来或被反射回来但强度不够大时
- 红外接收管一直处于关断状态,此时模块的输出端为高电平,指示二极管一直处于熄灭状态
- 被检测物体出现在检测范围内时,红外线被反射回来且强度足够大,红外接收管饱和
- 此时模块的输出端为低电平,指示二极管被点亮
- 总结就是一句话,没反射回来,D0输出高电平,灭灯
接线方式
- VCC:接电源正极(3-5V)
- GND:接电源负极 DO:TTL开关信号输出0、1
- AO:模拟信号输出(不同距离输出不同的电压,此脚一般可以不接)
2. 循迹小车原理
由于黑色具有较强的吸收能力,当循迹模块发射的红外线照射到黑线时,红外线将会被黑线吸收,导致 循迹模块上光敏三极管处于关闭状态,此时模块上一个LED熄灭。在没有检测到黑线时,模块上两个LED常亮
总结就是一句话,有感应到黑线,D0输出高电平 ,灭灯
3. 循迹小车开发和调试代码
//main.c
#include "motor.h"
#include "delay.h"
#include "uart.h"
#include "time.h"
#include "reg52.h"
extern char speedLeft;
extern char speedRight;
sbit leftSensor = P2^7;
sbit rightSensor = P2^6;
void main()
{
Time0Init();
Time1Init();
//UartInit();
while(1){
if(leftSensor == 0 && rightSensor == 0){
speedLeft = 32;
speedRight = 40;
}
if(leftSensor == 1 && rightSensor == 0){
speedLeft = 12;//10份单位时间全速运行,30份停止,所以慢,20ms是40份的500us
speedRight = 40;
}
if(leftSensor == 0 && rightSensor == 1){
speedLeft = 32;
speedRight = 20;
}
if(leftSensor == 1 && rightSensor == 1){
//停
speedLeft = 0;
speedRight = 0;
}
}
}
//motor.c
#include "reg52.h"
sbit RightCon1A = P3^2;
sbit RightCon1B = P3^3;
sbit LeftCon1A = P3^4;
sbit LeftCon1B = P3^5;
void goForwardLeft()
{
LeftCon1A = 0;
LeftCon1B = 1;
}
void stopLeft()
{
LeftCon1A = 0;
LeftCon1B = 0;
}
void goForwardRight()
{
RightCon1A = 0;
RightCon1B = 1;
}
void stopRight()
{
RightCon1A = 0;
RightCon1B = 0;
}
void goForward()
{
LeftCon1A = 0;
LeftCon1B = 1;
RightCon1A = 0;
RightCon1B = 1;
}
void goRight()
{
LeftCon1A = 0;
LeftCon1B = 1;
RightCon1A = 0;
RightCon1B = 0;
}
void goLeft()
{
LeftCon1A = 0;
LeftCon1B = 0;
RightCon1A = 0;
RightCon1B = 1;
}
void goBack()
{
LeftCon1A = 1;
LeftCon1B = 0;
RightCon1A = 1;
RightCon1B = 0;
}
void stop()
{
LeftCon1A = 0;
LeftCon1B = 0;
RightCon1A = 0;
RightCon1B = 0;
}
//delay.c
#include "intrins.h"
void Delay1000ms() //@11.0592MHz
{
unsigned char i, j, k;
_nop_();
i = 8;
j = 1;
k = 243;
do
{
do
{
while (--k);
} while (--j);
} while (--i);
}
//time.c
#include "motor.h"
#include "reg52.h"
char speedLeft;
char cntLeft = 0;
char speedRight;
char cntRight = 0;
void Time1Init()
{
//1. 配置定时器1工作模式位16位计时
TMOD &= 0x0F;
TMOD |= 0x1 << 4;
//2. 给初值,定一个0.5出来
TL1=0x33;
TH1=0xFE;
//3. 开始计时
TR1 = 1;
TF1 = 0;
//4. 打开定时器1中断
ET1 = 1;
//5. 打开总中断EA
EA = 1;
}
void Time0Init()
{
//1. 配置定时器0工作模式位16位计时
TMOD = 0x01;
//2. 给初值,定一个0.5出来
TL0=0x33;
TH0=0xFE;
//3. 开始计时
TR0 = 1;
TF0 = 0;
//4. 打开定时器0中断
ET0 = 1;
//5. 打开总中断EA
EA = 1;
}
void Time1Handler() interrupt 3
{
cntRight++; //统计爆表的次数. cnt=1的时候,报表了1
//重新给初值
TL1=0x33;
TH1=0xFE;
//控制PWM波
if(cntRight < speedRight){
//右前进
goForwardRight();
}else{
//停止
stopRight();
}
if(cntRight == 40){//爆表40次,经过了20ms
cntRight = 0; //当100次表示1s,重新让cnt从0开始,计算下一次的1s
}
}
void Time0Handler() interrupt 1
{
cntLeft++; //统计爆表的次数. cnt=1的时候,报表了1
//重新给初值
TL0=0x33;
TH0=0xFE;
//控制PWM波
if(cntLeft < speedLeft){
//左前进
goForwardLeft();
}else{
//停止
stopLeft();
}
if(cntLeft == 40){//爆表40次,经过了20ms
cntLeft = 0; //当100次表示1s,重新让cnt从0开始,计算下一次的1s
}
}