智能车制作

 找回密码
 注册

扫一扫,访问微社区

查看: 829|回复: 0
打印 上一主题 下一主题

智能小车自动避障程序双路

[复制链接]

1

主题

5

帖子

0

精华

注册会员

Rank: 2

积分
53
威望
37
贡献
8
兑换币
10
注册时间
2016-1-14
在线时间
4 小时
毕业学校
跳转到指定楼层
1#
发表于 2016-1-16 11:06:14 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
//晶振=11.0592M
//MCU=STC516RD+
//************************************
#include<reg51.h>                                                //包括一个52标准内核的头文件
#define uchar unsigned char                                //定义一下方便使用
#define uint unsigned int                                //定义一下方便使用
uchar Distance;                                                        //定义Distance(距离)变量
sbit Tr1=P1^4;                                                        //定义超声波模块的控制端(Tr)
sbit Ec1=P1^5;                                                        //定义超声波模块的接收端(Ec)
sbit Tr2=P1^6;                                                        //定义第二个超声波模块的控制端(Tr)
sbit Ec2=P1^7;                                                        //定义第二个超声波模块的接收端(Ec)
sbit IN1=P2^1;                                                        //定义L298n步进电机驱动芯片的IN1管脚由51MCU的P2^1管脚控制IN1对应控制OUT1电机驱动脚
sbit IN2=P2^0;                                                        //定义L298n步进电机驱动芯片的IN2管脚由51MCU的P2^0管脚控制IN2对应控制OUT2电机驱动脚
sbit IN3=P2^2;                                                        //定义L298n步进电机驱动芯片的IN3管脚由51MCU的P2^2管脚控制IN3对应控制OUT3电机驱动脚
sbit IN4=P2^3;                                                        //定义L298n步进电机驱动芯片的IN4管脚由51MCU的P2^3管脚控制IN4对应控制OUT4电机驱动脚
sbit ENA=P2^5;                                                        //定义L298n步进电机驱动芯片的ENA管脚由51MCU的P2^5管脚控制ENA脚是使能脚控制IN1,2脚输入的高低电平是否有效
sbit ENB=P2^4;                                                        //定义L298n步进电机驱动芯片的ENB管脚由51MCU的P2^4管脚控制ENA脚是使能脚控制IN3,4脚输入的高低电平是否有效
void Delays(uint x)                                                //延时函数Delays..定义形参x为unsigned int 型
{
uint q,w;                                                                //定义实际参数q,w为unsigned int 型
for(q=x;q>0;q--)                                                //q=x,q小于0,q减一。如果q小于零则退出此语句
for(w=110;w>0;w--);                                                //w=110,w小于0,w减一。如果w小于零则退出此语句
}
void init()                                                           //初始化函数init
{                                                                           //初始化Ec1=0;
Ec1=0;                                                                   //初始化Tr1=0;
Tr1=0;
}
void Ranging()                                                   //Ranging(测距)函数用于检测出距离并控制电机做出相应的动作
{
while(1)
        {
        static uchar Num_Run=0;
        static uchar Num3=0;                                   //定义unsigned char型局部变量Num3,并且只第一次执行时Num3=0,以后执行时不会再次初始,主要用于超声波模块的使能信号过后用来检测接收端Ec1是否有高电平,或用于进入和退出while循环,,
        static uchar Choice=0;
        bit Bit_Num2;                                                   //定义bit型变量(51特有变量)Bit_Num2。。主要用于关闭定时器并进入下一个函数(检测Ec1的脉宽长度)
        uchar Move1,Move2,Move3,Move4;                                                              //定义unsigned char变量Move(用来进入switch语句并选择那种工作方式)
        if(Choice==2){Choice=0;}
        switch(Choice)
                {
                case 0:Tr1=1;Delays(10);Tr1=0;Num3=1;break;                         //Tr1给高电平 //至少延时10微秒        //Tr1给低电平 //Num3给1
                case 1:Tr2=1;Delays(10);Tr2=0;Num3=2;break;        
                default:break;
                }
        Choice++;                                                                  
        Bit_Num2=0;                                                           //Bit_Num2给0用于进入下一步while循环
        while(Num3==1)                                                   //当Num3检测到定于1时进入本循环
                {
                while(Ec1==1)                                           //当Ec1检测等于1是进入本循环,当Ec1(接收信号的高电平脉宽结束后退出此循环)
                        {                                                           //Bit_Num2给以用来键入笑一个if语句
                        Bit_Num2=1;                                           //打开定时器TR0进入定时器0中断
                        TR0=1;
                        }
                if(Ec1==0&Bit_Num2==1)                           //如果Ec1等于0(超声波测距模块的接收端发送到高电平脉宽传送完后)而且Bit_Num2等于1进入此语句
                        {                                                           
                        TR0=0;                                                   //关闭定时器
                        if(Distance<20)                                   //如果脉宽小于50微秒
                                {
                                Move1=0;                                          //Move等于1                           
                                }
                        else if(Distance>30)                   //如果上一语句不成立则检测此语句,如果脉宽的时间长度大于50微秒
                                {
                                uchar n;
                                for(n=1;n>0;n--)
                                        {
                                        Move1++;                                           //Move等于2
                                        }

                                }
                        else{};
                        if(Distance<30&Distance>20)        
                                {
                                uchar n;
                                for(n=2;n>0;n--)
                                        {
                                        Move1++;                                           //Move等于2
                                        }
                                }
                        Num3=0;
                        }                                                           
                }
        while(Num3==2)
                {
                Distance=0;
                while(Ec2==1)                                           //当Ec2检测等于1是进入本循环,当Ec1(接收信号的高电平脉宽结束后退出此循环)
                        {                                                           
                        Bit_Num2=1;                                           //Bit_Num2给以用来键入笑一个if语句
                        TR0=1;                                                  //打开定时器TR0进入定时器0中断
                        }
                        if(Ec2==0&Bit_Num2==1)                           //如果Ec1等于0(超声波测距模块的接收端发送到高电平脉宽传送完后)而且Bit_Num2等于1进入此语句
                                {                                                           
                                TR0=0;                                                  //关闭定时器                                                                                                                  
                                if(Distance<20)                                   //如果脉宽小于50微秒
                                        {
                                                Move2=0;                        
                                        }
                                else if(Distance>30)                   //如果上一语句不成立则检测此语句,如果脉宽的时间长度大于50微秒
                                        {
                                        uchar n;
                                        for(n=1;n>0;n--)
                                                {
                                                Move2++;                        
                                                }
                                        }
                                else{};
                                if(Distance<30&Distance>20)                   //如果上一语句不成立则检测此语句,如果脉宽的时间长度大于50微秒
                                        {
                                        uchar n;
                                        for(n=2;n>0;n--)
                                                {
                                                Move2++;                        
                                                }
                                        }
                                Num_Run=1;
                                Num3=0;
                                }                  
                }
        if(Num_Run==1)
                {
                unsigned char Get[4][4]={{0x01,0x02,0x03,0x04},{0x05,0x06,0x07,0x08},{0x0a,0x0b,0x0c,0x0e},{0x0f,0x11,0x21,0x31}};
                switch(Get[Move1][Move2])                                   //检测Move的值并进入相应的语句
                        {
                        case 0x01:IN1=1;IN2=0;IN3=0;IN4=1;ENA=1;ENB=1;break;         //如果Move等于0,则电机反转,并给Distance清零,然后退出此语句                 //
                        case 0x02:IN1=0;IN2=1;IN3=1;IN4=0;ENA=1;ENB=1;break;
                        case 0x05:IN1=1;IN2=0;IN3=0;IN4=1;ENA=1;ENB=1;break;          //左开右关
                        case 0x06:IN1=1;IN2=0;IN3=1;IN4=0;ENA=1;ENB=1;break;         //如果Move等于1,则电机正转,并给Distance清零,然后退出此语句**//前进
                        case 0x0a:IN1=1;IN2=0;IN3=0;IN4=1;ENA=1;ENB=1;break;
                        case 0x0b:IN1=0;IN2=0;IN3=0;IN4=1;ENA=1;ENB=1;break;
                        case 0x0c:IN1=1;IN2=0;IN3=0;IN4=1;ENA=1;ENB=1;break;
                        case 0x03:IN1=0;IN2=1;IN3=1;IN4=0;ENA=1;ENB=1;break;
                        case 0x07:IN1=1;IN2=0;IN3=0;IN4=0;ENA=1;ENB=1;break;                  
                        default:break;                                                                                                         //如果以上都不符合,则退出此语句,准备下一循环
                        }
                Distance=0;
                Move1=0;                                                                     //Move清零;
                Move2=0;
                Move3=0;
                Move4=0;
                Num_Run=0;
                }                                                                                                        
        }
}
void open_time()                                           //定时器初始函数
{
TMOD=0x01;                                                           //确定工作方式位01,(内容自己上网查啊,大概是16位手动重装计数器,,记不清了)
TH0=(65536-1)/256;                                           //确定一微秒记一次
TL0=(65536-1)%256;                                           //确定一微秒记一次
EA=1;                                                                   //打开总中断
ET0=1;                                                                   //打开定时器0中断
TR0=0;                                                                   //关闭定时器0
}
void main()                                                           //main函数(主函数),,所有函数都从这个函数开始执行
{                                                                           
init();                                                                   //执行init函数
open_time();                                                   //执行open_time函数
while(1)                                                           //进入大循环(除非执行中断函数否则永不退出)
        {
        Ranging();                                                   //执行Ranging函数
        }
}
void time() interrupt 1                                   //定时器0中断语句
{
TH0=(65536-1)/256;                                           //重装初值TH0=(65536-1)/256;
TL0=(65536-1)%256;                                           //重装初值TL0=(65536-1)%256;
Distance++;                                                           //每次走一步Distance加一
if(Distance==65535)                                           //如果Distance等于65535就进入此语句
        {
        Distance=0;                                                   //Distance的值清零
        }
}
回复

使用道具 举报

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

本版积分规则

关于我们|联系我们|小黑屋|智能车制作 ( 黑ICP备2022002344号

GMT+8, 2024-9-29 06:05 , Processed in 0.057138 second(s), 26 queries , Gzip On.

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

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