这里我用了三个光敏电阻的传感器来进行寻迹:这里用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>
#define u8 unsigned char
#define u16 unsigned int
//光学开关模块
sbit LS=P2^3;
//接寻迹模块
#define fin_1 P3^6
#define fin_2 P3^7
#define fin_3 P3^5
void main()
{
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();
else if(fin_1==1&&fin_2==1&&fin_3==0)
right();
else if(fin_1==0&&fin_2==1&&fin_3==1)
left();
else if(fin_1==1&&fin_2==0&&fin_3==0)
right_90();
else if(fin_1==1&&fin_2==0&&fin_3==0)
left_90();
else
back();
}
else
{
P0=0X00; //关电机
}
}
}
pwm.h文件:
#ifndef _PWM_H
#define _PWM_H
#include <reg52.h>
//定义小车驱动模块输入IO口
sbit IN1=P1^0;
sbit IN2=P1^1;
sbit IN3=P1^2;
sbit IN4=P1^3;
//pwm端使能位:
sbit Left_pwm=P1^6; //PWM信号端
sbit Right_pwm=P1^7; //PWM信号端
//小车驱动接线定义
void Left_moto_go(); //左电机向前走
void Left_moto_back(); //左边电机向后转
//void Left_moto_Stop(); //左边电机停转
void Right_moto_go(); //右边电机向前走
void Right_moto_back(); //右边电机向后走
//void Right_moto_Stop(); //右边电机停转
//左电机调速 调节push_val_left的值改变电机转速,占空比
extern void pwm_out_left_moto(void);
extern void pwm_out_right_moto(void);
//调速模块
extern void run();
extern void left_90();
extern void right_90();
extern void left();
extern void right();
extern void back();
#endif
pwm.c文件
#include <reg52.h>
#include <pwm.h>
unsigned char pwm_left=0;//变量定义
unsigned char push_left=0;// 左电机占空比N/100
unsigned char pwm_right=0;
unsigned char push_right=0;// 右电机占空比N/100
unsigned int time=0;
void Left_moto_go()
{
IN1=1;
IN2=0;
}
void Left_moto_back()
{
IN1=0;
IN2=1;
}
/*
void Left_moto_Stop()
{
IN1=0;
IN2=0;
}
*/
void Right_moto_go()
{
IN3=1;
IN4=0;
}
void Right_moto_back()
{
IN3=0;
IN4=1;
}
/*
void Right_moto_Stop()
{
IN3=0;
IN4=0;
}
*/
//左电机调速 调节push_val_left的值改变电机转速,占空比
void pwm_out_left_moto(void)
{
if(pwm_left <= push_left)
{
Left_pwm = 1;
}
else
{
Left_pwm = 0;
}
if(pwm_left>100)
pwm_left=0;
}
//右电机调速
void pwm_out_right_moto(void)
{
if(pwm_right>100)
pwm_right=0;
if(pwm_right<=push_right)
{
Right_pwm = 1;
}
else
{
Right_pwm =0;
}
}
//前进
void run(void)
{
push_right=80;
push_left=80;
Left_moto_go();
Right_moto_go();
}
//左转直角
void left_90(void)
{
push_right=50;
push_left=80;
Left_moto_go();
Right_moto_back();
}
//右转直角
void right_90(void)
{
push_right=80;
push_left=50;
Right_moto_go();
Left_moto_back();
}
//左转微调
void left(void)
{
push_right=80;
push_left=60;
Left_moto_go();
Right_moto_go();
}
//右转微调
void right(void)
{
push_right=80;
push_left=60;
Right_moto_go();
Left_moto_go();
}
//后退
void back(void)
{
push_right=20;
push_left=20;
Left_moto_back();
Right_moto_back();
}
// TIMER0中断服务子函数产生PWM信号
void timer0() interrupt 1 using 2
{
TH0=0XFc; //1Ms定时
TL0=0X18;
time++;
pwm_left++;
pwm_right++;
pwm_out_left_moto();
pwm_out_right_moto();
}