循迹小车
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 } }