#include<reg52.h>
#define uchar unsigned char
#define uint unsigned int
sbit Left_moto_pwm =P1^6; //接驱动模块ENA 使能端,输入PWM信号调节速度
sbit Right_moto_pwm =P1^5; //接驱动模块ENB
sbit P21=P1^0; //接电机IN1
sbit P22=P1^1; //接电机IN2
sbit P23=P1^2; //接电机IN3
sbit P24=P1^3; //接电机IN4
sbit EchoPin=P3^6; //超声波管脚定义
sbit TrigPin=P3^7;
uchar pwm_val_left =0;//变量定义
uchar pwm_val_right =0;//变量定义
uchar push_val_left =0;//左电机占空比N/10
uchar push_val_right=0;//右电机占空比N/10
uint distance;
uint count;
void delayus(uint i) //延时秒函数
{
while(i--);
}
/*******************************************
延时函数
********************************************/
void delay(uint z) //延时函数
{
uint x,y;
for(x=z;x>0;x--)
for(y=110;y>0;y--);
}
/************************************************************************/
/* PWM调制电机转速 */
/************************************************************************/
/* 左电机调速 */
/*调节push_val_left的值改变电机转速,占空比 */
void pwm_out_left_moto(void)
{
if(pwm_val_left<=push_val_left)
Left_moto_pwm=1;
else
Left_moto_pwm=0;
if(pwm_val_left>=10)
pwm_val_left=0;
}
/******************************************************************/
/* 右电机调速 */
void pwm_out_right_moto(void)
{
if(pwm_val_right<=push_val_right)
Right_moto_pwm=1;
else
Right_moto_pwm=0;
if(pwm_val_right>=10)
pwm_val_right=0;
}
/***************************************************/
/************************************************************************/
void run(void) //前进函数
{
push_val_left =3; //PWM 调节参数1-10 1为最慢,10是最快 改这个值可以改变其速度
push_val_right =3; //PWM 调节参数1-10 1为最慢,10是最快 改这个值可以改变其速度
P21=1;
P22=0;
P23=1;
P24=0;
}
/*********************************************************/
void stop(void) //停止函数
{
P21=1;
P22=1;
P23=1;
P24=1;
}
/************************************************************************/
void left()//左转函数
{
push_val_left =2; //PWM 调节参数1-10 1为最慢,10是最快 改这个值可以改变其速度
push_val_right =4; //PWM 调节参数1-10 1为最慢,10是最快 改这个值可以改变其速度
P21=0;
P22=1;
P23=1;
P24=0;
}
/************************************************************************/
void right()//右转函数
{
push_val_left =4; //PWM 调节参数1-10 1为最慢,10是最快 改这个值可以改变其速度
push_val_right =2; //PWM 调节参数1-10 1为最慢,10是最快 改这个值可以改变其速度
P21=1;
P22=0;
P23=0;
P24=1;
}
/************************************************************************/
void spin_right()//原地右转函数
{
push_val_left =3; //PWM 调节参数1-10 1为最慢,10是最快 改这个值可以改变其速度
push_val_right =3; //PWM 调节参数1-10 1为最慢,10是最快 改这个值可以改变其速度
P21=1;
P22=0;
P23=0;
P24=1;
}
/************************************************************************/
void spin_left()//原地左转函数
{
push_val_left =3; //PWM 调节参数1-10 1为最慢,10是最快 改这个值可以改变其速度
push_val_right =3; //PWM 调节参数1-10 1为最慢,10是最快 改这个值可以改变其速度
P21=0;
P22=1;
P23=1;
P24=0;
}
/************************************************************************/
void back()//后退函数
{
push_val_left =3; //PWM 调节参数1-10 1为最慢,10是最快 改这个值可以改变其速度
push_val_right =3; //PWM 调节参数1-10 1为最慢,10是最快 改这个值可以改变其速度
P21=0;
P22=1;
P23=0;
P24=1;
}
/************************************************************************/
///*TIMER0中断服务子函数产生PWM信号*/
void timer0()interrupt 1
{
TH0=(65536-800)/256; //1MS定时
TL0=(65536-800)%256;
pwm_val_left++;
pwm_val_right++;
pwm_out_left_moto();
pwm_out_right_moto();
}
void timer1()interrupt 3
{
count++;
TH1=(65536-100)/256; //100us
TL1=(65536-100)%256;
}
void ultrasonic_trigger()
{
TrigPin=1;
delayus(15);
TrigPin=0;
}
int measure_Distance()
{
uint distance;
uchar l;
uint h,y;
ultrasonic_trigger();
while(!EchoPin); //触发超声波测距后,等待电平变为高电平,计时开始
TR1=1;
while(EchoPin); //超声波回波后,等待电平变成低电平,计时结束
TR1=0;
l=TL1;
h=TH1;
y=(h<<8)+1;
y=y-0xfce0; //us部分 fc66
distance=y+100*count; //计算总时间,us部分+计时器计数的次数(每次100us)
TL1=0xe0; //66
TH1=0xfc;
distance=distance/58; //换算公式:us/58=cm 即0.017us=cm
TrigPin=0;
count=0;
return distance;
}
/***************************************************
主函数
***************************************************/
void main(void)
{
TMOD=0X01;
TH0=(65536-800)/256;
TL0=(66536-800)%256;
EA=1;
ET0=1;
TR0=1;
TMOD|=0x10; //定时器1工作方式
TH1=(65536-800)/256; //1ms定时,装入初值
TL1=(66536-800)%256;
ET1=1; //允许T1中断
TrigPin=0; //初始化超声波管脚
while(1)
{
measure_Distance();
delayus(100);
if(distance>35)
{
run();
}
else if(distance>=25&&distance<=35)
{
run();
}
else if(distance<25)
{
spin_right();
stop();
delayus(100);
measure_Distance();
delayus(100);
if (distance>=25)
{
run();
}
else if (distance<25)
{
spin_left();
stop();
delayus(100);
if (distance>=25)
{
run();
}
else if(distance<25)
{
spin_left();
stop();
delayus(100);
}
}
}
}
}
|