找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 3297|回复: 0
打印 上一主题 下一主题
收起左侧

51单片机小车走黑线程序

[复制链接]
跳转到指定楼层
楼主
ID:559337 发表于 2019-7-26 20:26 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式


/*请将此程序下载到U2
启动键为U2P32
停止键为U2P33
有可能会出现黑线传感器感应不到黑线的情况,是因为黑线传感器的灵敏度调得太高了
应该调低灵敏度,这样才能检测到黑线.因为灵敏度太高,黑色反射的红外光都能被传感
器识别,导致检测失败.应该把黑线传感器上的可调电阻逆时针调节,这样就能把灵敏
度调低(顺时针调节的时候是调高)*/

#include <at89x52.h>
#define uchar unsigned char
#define uint unsigned int
void motor_r_z(void);//右边电动机正转
void motor_l_z(void);//左边电动机正转
void motor_r_f(void);//右边电动机反转
void motor_l_f(void);//左边电动机反转
void go(uchar,uchar);//小车前进
void stop(void);//小车停止

sbit IN1=P3^6;//L298N的IN1接到P2.5
sbit IN2=P3^7;//L298N的IN2接到P2.4
sbit IN3=P2^7;//L298N的IN3接到P2.1
sbit IN4=P2^6;//L298N的IN4接到P2.2
sbit ENA=P3^4;//L298N的ENA接到P2.0
sbit ENB=P3^5;//L298N的ENB接到P2.2



sbit left_k=P1^2;//小车左转信号输入端为P0.5,P0.5为1时说明已经检测到黑线
sbit right_k=P1^3;//小车左转信号输入端为P0.4,P0.4为1时说明已经检测到黑线
sbit start_k=P3^2;//启动按键为U2P32
sbit stop_k=P3^3;//停止按键为U2P33

sbit sound=P2^4;//蜂鸣器接到了P2.4上,P2.4为低电平的时候,蜂鸣器响。

uchar data t_0;//每产生一次T0定时器中断的时候t_0加1
uchar data motor_r;//motor_r用于存放右边电机转速和转向的数据
uchar data motor_l;//motor_l用于存放左边电机转速和转向的数据
uchar data Speed_Parameters;

//**延时子程序**///
void delay_1ms(uint n)
{
        uint i,j;
        for(j=n;j>0;j--)
        for(i=20;i>0;i--);
}


/*******初始化函数***********/
void ini(void)
{
////T0初始化///
TMOD=0x01; //T0工作在方式1
TH0=0xff; //装入T0初值
TL0=0xf6;
TR0=1;//开T0中断
ET0=1;//T0允许中断
EA=1;
P0=0Xff;
//////////////////////
t_0=0;
/////////////////////
P2=0xff;
P3=0XFF;
P1=0XFF;
sound=0;
delay_1ms(100);//蜂鸣器响100ms
sound=1;
}


///蜂鸣器响///
void Sound(void)
{
sound=0;
delay_1ms(60);
sound=1;
}


/****启动处理函数****/
void start(void)
{
   uchar a;
aa:while(start_k);//防抖程序
   for(a=0;a<50;a++)
   {
   delay_1ms(1);
   while(start_k)
   goto aa;
   }
   Sound();//调用蜂鸣器发音程序
   go(0x64,0x64);//全速直行
}


void go(uchar left_motor,uchar right_motor)//直行
{
Speed_Parameters=right_motor;//给速度参数赋值
motor_r_z();//调用右边电机正转函数
Speed_Parameters=left_motor;
motor_l_z();//调用左边电机正转函数
}


void motor_r_z(void)//右边电动机正转
{
  motor_r=0x64+Speed_Parameters;
  ENA=1;
}

void motor_l_z(void)//左边电动机正转
{
  motor_l=0x64-Speed_Parameters;
  ENB=1;
}

void stop(void)
{
ENB=0;
ENA=0;
}


/*********T0中断服务程序*****************/
/*********PWM产生***********************/
void time0(void) interrupt 1 using 2
{
TR0=0;//停止T0计数
TH0=0xff;//当晶振频率是12M时,每隔0.01ms中断一次,200次中断为PWM信号输出的周期,
TL0=0xf6;//PWM信号的频率=1000/(200*0.01ms)=500HZ
++t_0;//产生一次中断t_0加1
ACC=t_0;//将t_0的值赋值给ACC
CY=0;//清零CY
ACC-=motor_r;//用ACC减去右边电动机的参数(此参数决定了右边电机的转向和速度)
   if(CY==1)//判断CY是否置1,如果为1,说明ACC-motor_r已经为负数,置位了CY
  {
   IN1=1;//IN1由原来的0变成了1
   IN2=0;//IN2由原来的1变成了0
   goto PWM_2;
  }
IN1=0;//如果CY不等于1,IN1=0,IN2=1
IN2=1;
PWM_2:
ACC=t_0;//重新将t_0的值赋值给ACC
CY=0;//清零CY
ACC-=motor_l;//用ACC减去左边电动机的参数(此参数决定了左边电机的转向和速度)
  if(CY==1)//判断CY是否置1,如果为1,说明ACC-motor_l已经为负数,置位了CY
  {
   IN3=1;//IN3由原来的0变成了1
   IN4=0;//IN4由原来的1变成了0
   goto HIGHT;
  }
  IN3=0;//如果CY不等于1,IN3=0,IN4=1
  IN4=1;

HIGHT:
//ACC=t_0; //重新将t_0的值赋值给ACC
if(t_0!=0xc8)//判断t_0的值是否不等于200
goto EXIT;//如果不等于200,程序指针指向EXIT执行程序  
ACC=0;//如果t_0的值等于200,清零ACC和t_0
t_0=ACC;
EXIT:
TR0=1;//打开TO计数
}  


void main(void)
{
uchar a;
ini();//调用初始化函数
start();//调用启动处理函数
////判断左传感器状态////
while(1)
{
aa:
         while(!left_k)//判断左边传感器的值是否为0
         goto bb;//如果是0,程序指针指向标号bb,执行程序
                 P0_0=0;//如果是1,点亮P1.0上连接的发光二极管
                // Sound();
                 while(left_k)//如果left_k的值一直为1,不断的循环执行 go(0x00,0x64);小车左转 直到left_k的值为0为止。
         go(0x00,0x64);//0x00,0x64分别代表左右电动机的转速,两个值的取值为0x00到0x64之间,0x00最慢。0x64最快
                              //0x00,0x64这两个值不一样代表两个电机向前转的速度不同,小车将拐弯
         go(0x40,0x40);//执行到这句说明left_k已经为1,说明左传感器已经离开了黑线。小车直线前进
                               //0x40,0x40这连个值同表示小车执行这个函数时将向前走,用户可以自任意修改这些数值,达到小车走黑线
                               //最稳定的效果,建议不要取得太大(十六进制0x64是最大,其实也就是十进制数的100),也就是速度等级
                                           //为0到100个等级。
                 P0_0=1;//关闭LED指示灯
////判断右传感器状态////
bb:
        while(!right_k)//判断右传感器的值是否为0
        goto cc;//如果是0,程序指针指向标号cc,执行程序
                 P0_1=0;//如果是1,点亮P1.1上连接的发光二极管
        // Sound();
                 while(right_k)//如果right_k的值一直为1,不断的循环执行go(0x64,0x0);;小车右转 直到right_k的值为0为止
         go(0x64,0x0);
         go(0x40,0x40);//执行到这句说明right_k已经为1,说明左传感器已经离开了黑线。小车直线前进
                 P0_1=1;//关闭LED指示灯
///判断是否按下停止按钮//////
cc:   

       while(stop_k)//判断停止键是否按下,按下的时候stop_k为1
       goto aa;////如果是1,程序指针指向标号aa,执行程序
        for(a=0;a<20;a++)//如果是0,进入防抖程序
        {
          delay_1ms(1);
          while(stop_k)//判断20次stop_k是否为1
          goto cc;//如果是1,程序指针指向标号cc,执行程序
        }
          stop();//20次判断之后stop_k都是0,立马停止两个电动机
          start();//跳到启动处理函数,执行程序。
}
}


00 走黑线源程序.zip

21.51 KB, 下载次数: 6, 下载积分: 黑币 -5

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表