智能小车循迹模块
一. PWM电机调速原理
控制电机的时候,电源并非连续地向电机供电,而是在一个特定的频率下以方波脉冲的形式提供电能。电机实际上是一个大电感,它有阻碍输入电流和电压突变的能力,因此脉冲输入信号被平均分配到作用时间上,这样,改变在始能端EN1 和EN2 上输入方波的占空比就能改变加在电机两端的电压大小,从而改变了转速。
方法:
(1)软件:设置不同的延时时间得到不同的占空比(本实验使用),采用定时器中断来产生PWM波形
(2)硬件:用具有硬件PWM功能的芯片
注:占空比和电机转速并不是简单的线性关系。(电机调速后的能量,很大一部分会损耗在三极管上发热)
二. 循迹实现原理
平面为黑色:红外光反射量很少,传感器输出高电平1(达不到传感器动作的水平),L1(L2)信号灯不亮
平面为白色:红外光反射量很多,传感器输出低电平0,L1(L2)信号灯亮
各种循迹方法:
- 红外对管循迹法:利用黑、白色对红外线的吸收
作用不同; - 摄像头循迹法:利用摄像头读取赛道信息,分为
模拟和数字 - 激光管循迹法:和红外循迹法原理相似,但是检
测距离远; - 电磁循迹法
三. 循迹硬件调试
W1,W2调节----顺时针灵敏度增加,逆时针灵敏度降低
灵敏度越高越不易检测到黑线,因为灵敏度太高黑色反射的红外光都能被传感器识别
四. 程序
#include<AT89X52.H> //包含51单片机头文件,内部有各种寄存器定义
#include<HJ-4WD_PWM.H> //包含智能小车驱动IO口定义等函数
//主函数
void main(void)
{
TMOD=0X01;
TH0= 0XFc;
TL0= 0X18;
TR0= 1;
ET0= 1;
EA = 1; //1ms定时
while(1) //无限循环
{
if(Left_1_led==0&&Right_1_led==0)
run(); //调用前进函数
else
{
if(Left_1_led==1&&Right_1_led==0) //左边检测到黑线
{
leftrun(); //调用小车左转函数
}
if(Right_1_led==1&&Left_1_led==0) //右边检测到黑线
{
rightrun(); //调用小车右转函数
}
}
}
}
HJ-4WD_PWM.H文件:
#ifndef _LED_H_
#define _LED_H_
//定义小车驱动模块输入IO口
sbit IN1=P1^2;
sbit IN2=P1^3;
sbit IN3=P1^6;
sbit IN4=P1^7;
sbit EN1=P1^4;
sbit EN2=P1^5;
#define Left_1_led P3_3 //左传感器
#define Right_1_led P3_2 //右传感器
#define Left_moto_pwm P1_5 //PWM信号端
#define Right_moto_pwm P1_4 //PWM信号端
#define Left_moto_go {P1_2=0,P1_3=1;} //左电机向前走
#define Left_moto_back {P1_2=1,P1_3=0;} //左边电机向后转
#define Left_moto_Stop {P1_5=0;} //左边电机停转
#define Right_moto_go {P1_6=1,P1_7=0;} //右边电机向前走
#define Right_moto_back {P1_6=0,P1_7=1;} //右边电机向后走
#define Right_moto_Stop {P1_4=0;} //右边电机停转
unsigned char pwm_val_left =0;//变量定义
unsigned char push_val_left =0;// 左电机占空比N/20
unsigned char pwm_val_right =0;
unsigned char push_val_right=0;// 右电机占空比N/20
bit Right_moto_stop=1;
bit Left_moto_stop =1;
unsigned int time=0;
/************************************************************/
//延时函数
void delay(unsigned int k)
{
unsigned int x,y;
for(x=0;x<k;x++)
for(y=0;y<2000;y++);
}
/************************************************************/
//前进
void run(void)
{
push_val_left=10; //速度调节变量 0-20(0最小,20最大)
push_val_right=10;
Left_moto_go ; //左电机往前走
Right_moto_go ; //右电机往前走
}
//左转
void leftrun(void)