找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 8340|回复: 2
收起左侧

有关智能小车的程序

[复制链接]
ID:186510 发表于 2017-4-5 23:18 | 显示全部楼层 |阅读模式
#include<reg52.h>
#include <math.h>
#include <intrins.h>
#define uchar unsigned char
#define uint  unsigned int

sbit P10 = P1^0;
sbit P11 = P1^1;   //  1号电机  右前轮
sbit P12 = P1^2;       
sbit P13 = P3^2;   //  2号电机  左前轮
sbit P14 = P1^4;
sbit P15 = P1^5;   //  3号电机  左后轮
sbit P16 = P1^6;
sbit P17 = P1^7;   //  4号电机  右后轮

sbit P20=P2^0;
sbit P21=P2^1;    //风扇

sbit P26=P2^6;   //噪声

sbit P35=P3^5;  //光敏

sbit TRIG = P3^6;    //   控制端
sbit ECHO = P3^7;           //   接收端


sbit a = P0^0;    // 避障 前右
sbit b = P0^1;    // 避障 前左                  
sbit c = P0^2;          // 避障 后右
sbit d = P0^3;    // 避障 后左

sbit f = P0^4;    // 循迹 前右
sbit g = P0^5;    // 循迹 前左
sbit h = P0^6;    // 循迹 后右
sbit i = P0^7;    // 循迹 后左

sbit PWM1=P2^2;   
sbit PWM2=P2^3;
sbit PWM3=P2^4;
sbit PWM4=P2^5;  //控制四个轮速度 需要用到定时器 在本程序中没有设置

sbit Beep=P1^3;  //蜂鸣器

uchar e;
uchar n,angle,count;    //距离标志位,0.5ms次数,角度标识
float S;                //距离变量

void delay()                  
{
        uchar a;
        for(a=450;a>0;a--)
        {
                _nop_();
        }
}

void DelayUs2x(uchar t)
{   
        while(--t);
}

void DelayMs(uchar t)
{
        while(t--)
        {
            DelayUs2x(245);
            DelayUs2x(245);
        }
}                  //大致延时1mS       

void Time(void)
{
    TMOD|=0x21;   /*TMOD有高八位与第八位   GATE=0, C/T=0(定时器模式),  |=位操作写法,强制赋值
                          定时器1工作方式2(8位自动重装定时器) (蓝牙),
                          定时器0(16位定时器)超声波  */
                TH0=0x00;     //定时器0  高八位的初值
    TL0=0x00;     //低八位的初值     定时最大的值65.536ms
    SCON=0x50;   //0101 0000  SM0=0 SM1=1 (10位异步收发器(8位数据)) SM2=0(多机通讯位) REN=1(串行接受允许位)              串口方式1 SM0 SM1 01 允许接收  
    PCON=0x00;   /*PCON没有位寻址的,不能直接操作  SMOD=0 16分频 波特率不加倍
                        波特率=(2*SMOD)/32*定时器1的溢出率
                        定时器1的溢出率=单片机内的时钟频率/(256-X) X是定时器的初值   
                        因此 波特率=(2*SMOD)/32*(单片机内部的时钟频率/(256-X))    */
          TH1=0xFd;   
    TL1=0xFd;     /*11.0592晶振   9600波特率
                          在串行通信时,T1定时器是用作波特率发生器的,且为方式2,这样,TL1是作为8位计数器的,
                          而TH1是作为时间常数的寄存器的,可以实现TL1计数回0时自动重装时间常数,即将TH1中的数自动送给TL1,再次计数。
                    TH1,TL1是单片机的16位定时器T1,只有给TH1,TL1赋值,定时器就开始计数,才能控制串行通信的波特率,而这值是根据需要的波特率计算出来的。*/
          TR1=1;       //打开定时器1
          IE=0x92;     //IE中断允许寄存器  1001 1010 即EA=1(打开总中断) ES=1(打开串口中断) ET1=1(打开定时器1源中断) ET0=1(打开定时器0源中断)

}

void csb()
{
        TRIG=1;            //触发信号是高电平脉冲,宽度大于10us
    DelayUs2x(10);
    TRIG=0;         
    while(!ECHO);   //等待高电平
    TR0=1;          //T0开始运行
    while(ECHO);    //等待低电平
    TR0=0;          //T0关闭
    S=TH0*256+TL0;  //取出定时器值高8位和低8位合并
    S=S/58;         //为什么除以58等于厘米,  Y米=(X秒*344)/2
                    // X秒=( 2*Y米)/344 -> X秒=0.0058*Y米 -> 厘米=微秒/58
    if(S>=40)
     {
                   n=1;        //距离大于40cm  标记
                 }
    if(S<40)
     {
                    n=0;       //距离小于40   标记
                 }

    TH0=0;
    TL0=0;         //清除定时器0寄存器中的值       
}

void FMQ()
{
                uint n;       
                                        for(n=1;n<20;n++)
                                {
                                                        uint m;
                                        for(m=800;m>0;m--)          
                                        {
                                                Beep=~Beep;       
                                                delay();               
                                        }
                                        for(m=500;m>0;m--)         
                                        {
                                                Beep=~Beep;
                                                delay();
                                                delay();       
                                        }
                                }
}

void fsz()
{
        P20=0;
        P21=1;
}

void fsf()
{
        P20=1;
        P21=0;
}

void fst()
{
        P20=0;
        P21=0;
}
void  run(void)                 // 前进
{

  P10 =1;
  P11 =0;

  P12 =1;
  P13 =0;

  P14 =1;
  P15 =0;

  P16 =1;
  P17 =0;
}

void backrun(void)                // 后退
{
  P10 =0;
  P11 =1;

  P12 =0;
  P13 =1;

  P14 =0;                                                         
  P15 =1;

  P16 =0;
  P17 =1;
}

void stop(void)                         // 停止
{
  P10 =0;
  P11 =0;

  P12 =0;
  P13 =0;

  P14 =0;
  P15 =0;

  P16 =0;
  P17 =0;
}

void leftrun(void)           // 左转
{
  P10 =1;
  P11 =0;

  P12 =0;
  P13 =1;

  P14 =0;
  P15 =1;

  P16 =1;
  P17 =0;
}

void rightrun(void)                 // 右转
{
  P10 =0;
  P11 =1;

  P12 =1;
  P13 =0;

  P14 =1;
  P15 =0;

  P16 =0;
  P17 =1;
}


void main(void)
{
                     
    Time();             //初始化定时器
        while(1)
        {
                         if(e=='2')
                         {
                                        run();
                                                                while((a==1)&&(b==0))     //前左侧遇到障碍物右拐
                                                                {
                                                                        rightrun();
                                                                        DelayMs(200);
                                                                }
                                                                while((a==0)&&(b==1))     //前右侧遇到障碍物左拐
                                                                {
                                                                        leftrun();
                                                                        DelayMs(200);
                                                                }
                                                                while((a==0)&&(b==0))     //两边同时遇到障碍物左拐
                                                                {
                                                                        stop();
                                                                        DelayMs(5000);
                                                               
                                                                }
                                                                while((c==1)&&(d==0))      //后右侧遇到障碍物右拐
                                                                {
                                                                        rightrun();
                                                                        DelayMs(200);
                                                                }
                                                                while((c==0)&&(d==1))     //后右侧遇到障碍物左拐
                                                                {
                                                                        leftrun();
                                                                        DelayMs(200);
                                                                }
                                                                while((f==1)&&(g==0))     //左边遇到白右转 1黑0白
                                                                {
                                                                        rightrun();
                                                                        DelayMs(170);       
                                                                }
                                                                while((f==0)&&(g==1))     //右边遇到白左转
                                                                {
                                                                        leftrun();
                                                                        DelayMs(170);
                                                                }
                                                                while((h==0)&&(i==1))    //右边遇到白左转
                                                                {
                                                                        leftrun();
                                                                        DelayMs(170);
                                                                }
                                                                while((h==1)&&(i==0))    //左边遇到白右转
                                                                {
                                                                        rightrun();
                                                                        DelayMs(170);
                                                                }
                                                         }                               //按键2 前进(带避障)
                                                         
                                                                else if(e=='4') leftrun();     //按键4 向左转
                                                         
                                                                else if(e=='6')  rightrun();   //按键6 向右转
                                                         
                                                                else if(e=='8')
                                                                {
                                                                                        backrun();
                                                                                        while((a==1)&&(b==0))     //前左侧遇到障碍物右拐
                                                                                        {
                                                                                                rightrun();
                                                                                                DelayMs(200);
                                                                                        }
                                                                                 while((a==0)&&(b==1))     //前右侧遇到障碍物左拐
                                                                                        {
                                                                                                leftrun();
                                                                                                DelayMs(200);
                                                                                        }
                                                                                 while((a==0)&&(b==0))     //两边同时遇到障碍物左拐
                                                                                        {
                                                                                                stop();
                                                                                                DelayMs(5000);
                                                                                        }
                                                                                 while((c==1)&&(d==0))      //后右侧遇到障碍物右拐
                                                                                        {
                                                                                                rightrun();
                                                                                                DelayMs(200);
                                                                                        }
                                                                                 while((c==0)&&(d==1))      //后右侧遇到障碍物左拐
                                                                                        {
                                                                                                leftrun();
                                                                                                DelayMs(200);
                                                                                        }
                                }                                      //按键8 后退(带避障)
                               
                                else if(e=='1')
                                {
                                        FMQ();
                                        DelayMs(100);                         //按键1 蜂鸣器
                                }
                               
                                else if(e=='A') run();                //向上箭头 仅前进
                                       
                                else if(e=='B') backrun();            //向下箭头 仅后退
                               
                                else if(e=='C') leftrun();            //向左箭头 仅左转
                               
                                else if(e=='D') rightrun();           //向右箭头 仅右转
                               
                                else if(e=='7') fsz();
                               
                                else if(e=='9') fsf();
                               
                                else if(e=='5') fst();
                       
                                else stop();
                               
                                if(P26==0) FMQ();
                               
                                else Beep=0;
                               
         }
}

void serial() interrupt 4
{
        RI=0;                              //接受中断位 必须由软件置0  硬件置1
        e=SBUF;                            //接受缓冲器SBUF赋值给e
}

void Time0_0(void) interrupt 1      //定时器中断   (void)是必须的
{
        ECHO=0;
}
回复

使用道具 举报

ID:440298 发表于 2018-12-5 18:37 | 显示全部楼层
感谢
回复

使用道具 举报

ID:357019 发表于 2018-12-9 09:38 | 显示全部楼层
程序很到位,谢谢楼主,第一次接触这类的东西。
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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