这里我用了三个光敏电阻的传感器来进行寻迹:这里用X1,X2,X3(检测到了为0)来表示:
算法思路:
将三个传感器放置如图: | | |
1)直行:X1=1;X2=0;X3=1;
2)左转:X1=0;X2=1;X3=1;
3)右转:X1=1;X2=1;X3=0;
4)直角左转:X1=0;X2=0;X3=1;
5)直角右转:X1=1;X2=0;X3=0;
其他情况慢慢后退:这样提高了小车的容错性,如果一旦出现寻迹乱码的情况(这里指未出现的组合数如:X1=1 X2=0 X3=1)
算法思路很简单主要看小车寻迹的赛道,代码中的pwm的宽度是随意设置的,具体什么样的弯道角度需要耐心调试,反复试验。
main.c
#include<reg52.h>#include<pwm.h>#defineu8unsignedchar#defineu16unsignedint//光学开关模块sbitLS=P2^3; //接寻迹模块#definefin_1P3^6#definefin_2P3^7#definefin_3P3^5voidmain() { P1=0X00; //关电机 TMOD=0X01; TH0=0XFc; //1ms定时TL0=0X18; TR0=1; ET0=1; EA=1; //开总中断while(1) { if(LS==1) { if(fin_1==1&&fin_2==0&&fin_3==1) run(); elseif(fin_1==1&&fin_2==1&&fin_3==0) right(); elseif(fin_1==0&&fin_2==1&&fin_3==1) left(); elseif(fin_1==1&&fin_2==0&&fin_3==0) right_90(); elseif(fin_1==1&&fin_2==0&&fin_3==0) left_90(); elseback(); } else { P0=0X00; //关电机 } } }
pwm.h文件:
#ifndef_PWM_H#define_PWM_H#include<reg52.h>//定义小车驱动模块输入IO口 sbitIN1=P1^0; sbitIN2=P1^1; sbitIN3=P1^2; sbitIN4=P1^3; //pwm端使能位:sbitLeft_pwm=P1^6; //PWM信号端sbitRight_pwm=P1^7; //PWM信号端//小车驱动接线定义 voidLeft_moto_go(); //左电机向前走voidLeft_moto_back(); //左边电机向后转//void Left_moto_Stop(); //左边电机停转 voidRight_moto_go(); //右边电机向前走voidRight_moto_back(); //右边电机向后走//void Right_moto_Stop(); //右边电机停转//左电机调速 调节push_val_left的值改变电机转速,占空比externvoidpwm_out_left_moto(void); externvoidpwm_out_right_moto(void); //调速模块externvoidrun(); externvoidleft_90(); externvoidright_90(); externvoidleft(); externvoidright(); externvoidback(); #endif
pwm.c文件
#include<reg52.h>#include<pwm.h>unsignedcharpwm_left=0;//变量定义unsignedcharpush_left=0;// 左电机占空比N/100unsignedcharpwm_right=0; unsignedcharpush_right=0;// 右电机占空比N/100unsignedinttime=0; voidLeft_moto_go() { IN1=1; IN2=0; } voidLeft_moto_back() { IN1=0; IN2=1; } /*void Left_moto_Stop() {IN1=0;IN2=0;}*/voidRight_moto_go() { IN3=1; IN4=0; } voidRight_moto_back() { IN3=0; IN4=1; } /* void Right_moto_Stop() {IN3=0;IN4=0;} *///左电机调速 调节push_val_left的值改变电机转速,占空比voidpwm_out_left_moto(void) { if(pwm_left<=push_left) { Left_pwm=1; } else { Left_pwm=0; } if(pwm_left>100) pwm_left=0; } //右电机调速 voidpwm_out_right_moto(void) { if(pwm_right>100) pwm_right=0; if(pwm_right<=push_right) { Right_pwm=1; } else { Right_pwm=0; } } //前进voidrun(void) { push_right=80; push_left=80; Left_moto_go(); Right_moto_go(); } //左转直角voidleft_90(void) { push_right=50; push_left=80; Left_moto_go(); Right_moto_back(); } //右转直角voidright_90(void) { push_right=80; push_left=50; Right_moto_go(); Left_moto_back(); } //左转微调voidleft(void) { push_right=80; push_left=60; Left_moto_go(); Right_moto_go(); } //右转微调voidright(void) { push_right=80; push_left=60; Right_moto_go(); Left_moto_go(); } //后退voidback(void) { push_right=20; push_left=20; Left_moto_back(); Right_moto_back(); } // TIMER0中断服务子函数产生PWM信号voidtimer0() interrupt1using2{ TH0=0XFc; //1Ms定时TL0=0X18; time++; pwm_left++; pwm_right++; pwm_out_left_moto(); pwm_out_right_moto(); }