#include<at89x51.h>//此为红外线寻线小车程序 单片机为stc89c51rc 发射频率为38.5mKz 电机驱动芯片为L298
/
void delay_nus(unsigned int i) //延时:i>=12 ,i的最小延时单12 us
{
i=i/10;
while(--i);
}
void delay_nms(unsigned int n) //延时n ms
{
n=n+1;
while(--n)
delay_nus(900); //延时 1ms,同时进行补偿
}
/******************************************************
/************管脚定义********************/
extern int abs(int val); //声明abs函数
sbit ENA = P3^6; //左轮驱动使能
sbit IN1 = P3^2; //左轮黑线
sbit IN2 = P3^3; //左轮红线
sbit IN3 = P3^4; //右轮红线
sbit IN4 = P3^5; //右轮黑线
sbit ENB = P3^7; //右轮驱动使能
sbit L_scan=P0^2; //传感器扫描管脚
sbit R_scan=P0^3;
sbit L_led=P0^0; //LED控制管脚
sbit R_led=P0^1;
//=============PWM================
#define PWM_COUST 100 //PWM细分等份
unsigned int MOTO_speed1; //左边电机转速
unsigned int MOTO_speed2; //右边电机转速
unsigned int PWM_abs1; //左边电机取绝对值后占空比
unsigned int PWM_abs2; //左边电机取绝对值后占空比
//uchar PWM_var1=20; //左边电机直走速度 (不同的电机,此参数不同)
//uchar PWM_var2=20; //右边电机直走速度
unsigned int PWMAnd = 0; //PWM自增变量
/******************************************************************
名称:motor(char speed1,char speed2);
功能:同时调节电机的转速
参数:speed1:电机1的PWM值;speed2:电机2的PWM值
speed>0.正转;speed<0.反转(-100~100)
调用:extern int abs(int val); 取绝对值
返回:
******************************************************************/
void motor(unsigned int speed1,unsigned int speed2)
{
MOTO_speed1=speed1;
MOTO_speed2=speed2;
//==============左边电机=============
if(speed1==0)
{
IN1 =0;IN2 =0;
}
if (speed1>0)
{
IN1 =0;IN2 =1;//正转
}
else if (speed1<0)
{
IN1 =1;IN2 =0;//反转
}
//==============右边电机=============
if (speed2==0)
{
IN3 =0;IN4 =0;//不转
}
if (speed2>0)
{
IN3 =1;IN4 =0;//正转
}
else if (speed2<0)
{
IN3 =0;IN4 =1;//反转
}
}
/******************************************************************
名称:motor_PWM();
功能:PWM占空比输出
参数:无
调用:无
返回:无
******************************************************************/
void motor_PWM ()
{
PWM_abs1=abs(MOTO_speed1);
PWM_abs2=abs(MOTO_speed2);
if (PWM_abs1>PWMAnd) ENA=1; //左边电机占空比输出
else ENA=0;
if (PWM_abs2>PWMAnd) ENB=1; //右边电机占空比输出
else ENB=0;
if (PWMAnd>=PWM_COUST) PWMAnd=0; //PWM计数清零
else PWMAnd+=1;
}
/******************************************************************
名称:void TIME_Init ();
功能:定时器初始化
指令:
调用:无
返回:无
******************************************************************/
void TIME_Init ()
{
//=========定时器T0初始化 PWM==================
EA=1;
// TCON = 0x10;
TMOD = 0x01;
TH0 = 0xff;
TL0 = 0x9B;
// TL0 = 0x47;
ET0 = 1; //定时器1中断开
TR0 = 1; //PWM定时器开,PWM周期为10ms
}
/******************************************************************
名称:void PWM_Time0 () interrupt 0
功能:T2中断,PWM控制
参数:
调用:motor_PWM();//PWM占空比输出
返回:
******************************************************************/
void PWM_Time0 () interrupt 1
{
TR0 = 0;
//TF2 = 0;
ET0 = 0; //定时器0中断禁止
TH0 = 0xff;
TL0 = 0x9B;
motor_PWM();//PWM占空比输出
ET0 = 1; //定时中断0开启
TR0 = 1;
}
//扫描传感器状态
unsigned char scan(void)
{
unsigned char i,result,temp1,temp2;
for(i=38;i>0;i--) //LED发送38次脉冲
{
L_led=0;
delay_nus(12);
L_led=1;
delay_nus(12);
}
temp1=L_scan; //记录传感器状态
for(i=38;i>0;i--) //另一侧发脉冲
{
R_led=0;
delay_nus(12);
R_led=1;
delay_nus(12);
}
temp2=R_scan; //记录传感器状态
if(temp2==1&&temp1==1) //两侧都扫描到黑边
result=1;
if(temp1==0&&temp2==1) //左侧扫描到白线
result=0;
if(temp1==1&&temp2==0) //右侧扫描到白线
result=2;
if(temp1==0&&temp2==0) //两侧都扫描到白线
result=3;
return result;
}
unsigned char result;
void main()
{
while(1)
{
result=scan();
if(result==1) //直走
{
unsigned int i=0;
unsigned int y=0;
TIME_Init () ;
motor(100,100);//电机的转速
}
else if(result==0)//左转,左轮停止
{
unsigned int i=0;
unsigned int y=0;
TIME_Init () ;
motor(0,100);//电机的转速
while(1);
}
else if(result==2)//右转,右轮停止
{
unsigned int i=0;
unsigned int y=0;
TIME_Init () ;
motor(100,0);//电机的转速
}
else if(result==3)//两边都没有返回的状态(比如小车悬空)~自己定吧,这里停车
{ unsigned int i=0;
unsigned int y=0;
TIME_Init () ;
motor(0,0);//电机的转速
}
delay_nms(200);//延时200ms
}
}
|
|