c51 迷宫小车

头文件

//红外接口定义
sfr P4 = 0xe8;

//红外地址接口定义
sbit A0 = P4^0;
sbit A1 = P2^0;
sbit A2 = P2^7;

//红外传感器接收信号口定义
sbit irR1 = P2^1;//前(左)
sbit irR2 = P2^2;//左前
sbit irR3 = P2^3;//左
sbit irR4 = P2^4;//右
sbit irR5 = P2^5;//右前


//红外传感器检测状态全局位变量,0表示无障碍
unsigned char irC=0, irL=0, irR=0, irLU=0, irRU=0;


实现代码

#include <reg52.h>
#include "mouse.h"
#define  uchar unsigned char
#define  uint unsigned int
#define N 8
/* * * * * * * * * * * * * * * * * 
 *控制引脚申明
 */
sbit tube1 = P4^3;
sbit tube2 = P4^2;
sbit beep = P3^7;
/* * * * * * * * * * * * * * * * * *
 *数据单元
 */
//原地转圈
uchar code run1[] = {0x11,0x33,0x22,0x66,0x44,0xcc,0x88,0x99,0x11};
//直行
uchar code run2[] = {0x11,0x39,0x28,0x6c,0x44,0xc6,0x82,0x93,0x11};
//数码管
uchar code table[] = {0xc0,0xcf,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e,0xff};
//地图
uchar map[8][8] = {0};
//位置坐标
uchar location[2] = {7,0};
//岔路口信息
uchar stack[17][2] = {0};
//char finall[17] = {0 ,0, 1, 1, 0 , 0 , 1 , 1 , 1 , 0 , 1 , 1 , 0 , 0 };//测试路径数据
char top = -1;
uchar direction = 0;
char head,rear,top1 = -1 ;
unsigned char  b[6][2] ;//队列b,和记录路的座标的结构体数组
char way[17] = {0};//路径数据 
void recall();//回溯 
void voice();
uchar pass(uchar way);
void init(){//初始化队列
    head = 0;
    rear = 0;
}
void pop(){//弹出队列成员
    char i;
    for(i = 1;i <= rear; i++)
    {
        b[i-1][0] = b[i][0];
        b[i-1][1] = b[i][1];
    }
    rear --;
}
void record(char x ,char y){//将走过的点信息加入队列,next为指向
//上一个节点数据的指针
    b[rear][0] = x;
    b[rear][1] = y;
    rear ++;
}

/*
 *延时1ms
 */
void delayms(uint n)
{
    uchar i,j;
    for(j=n;j>0;j--)
    for(i=112;i>0;i--);
}

/* * * * * * * * * * * * * * * * * * * * * * * * * *
 *移动单元
 * * * * * * * * * * * * * * * * * * * * * * * * * *
 *
 *直行
 */
void go_straight()
{
//    uchar j,i;
//    for(j=0;j<106;j++)//一圈
//    {
//        for(i=8;i>0;i--)
//        {
//            P1 = run2[i];
//            delayms(2);
//        }
//    }
    uchar i,j,k,l = 21;
    while(l--){
        for(i=0;i<5;i++)
        {
            for(j=8;j>0;j--)
            {
                P1 = run2[j];
                delayms(3);
            }
        }
            if((irLU==1) && (irC == 0))
            {
                //voice();
                  for(k = 0 ;k < 3; k++)
                {
                    for(j=0;j<8;j++)
                    {
                        P1 = run1[j];
                        delayms(3);
                    }
                }
                
            }
            if((irRU==1) && (irC == 0))
            {   
                //voice();
                  for(k = 0;k < 3; k++)
                {
                    for(j=8;j>0;j--)
                    {
                        P1 = run1[j];
                        delayms(3);
                    }
                }
            }
        }
}

/*
 *掉头
 */
void back()
{
    uchar i,j;
    for(i=0;i<102;i++)
    {
        for(j=0;j<8;j++)
        {
            P1 = run1[j];
            delayms(2);
        }
    }
    direction = (direction + 2) % 4;
}

/*
 *右转
 */
void turn_right()
{
    uchar i,j;
    for(i=0;i<52;i++)
    {
        for(j=0;j<8;j++)
        {
            P1 = run1[j];
            delayms(2);
        }
    }
    direction = (direction + 1) % 4;
}

/*
 *左转
 */
void turn_left()
{
    uchar i,j;
    for(i=0;i<52;i++)
    {
        for(j=8;j>0;j--)
        {
            P1 = run1[j];
            delayms(2);
        }
    }
    direction = (direction + 3) % 4;
}
/*
 *冲刺
 */
void run_fast()
{
        uchar i,j,k,l = 20;
    while(l--){
        for(i=0;i<5;i++)
        {
            for(j=8;j>0;j--)
            {
                P1 = run2[j];
                delayms(2);
            }
        }
            if((irLU==1) && (irC == 0))
            {
                    
                  for(k = 0 ;k < 3; k++)
                {
                    for(j=0;j<8;j++)
                    {
                        P1 = run1[j];
                        delayms(2);
                    }
                }
                
            }
            if((irRU==1) && (irC == 0))
            {   
                    
                  for(k = 0;k < 3; k++)
                {
                    for(j=8;j>0;j--)
                    {
                        P1 = run1[j];
                        delayms(2);
                    }
                }
            }
        }
}

/* * * * * * * * * * * * * * * * * * * * * * * * * *
 *外设单元
 * * * * * * * * * * * * * * * * * * * * * * * * * *
 *
 *蜂鸣器
 */
void voice()
{
      uchar j = 0;
        for(j = 10;j>0;j--){
            beep = ~beep;
            delayms(10);
        }
        for(j = 100;j>0;j--){
            beep = 1;
            delayms(10);
        }
}

/*
 *数码管
 */
void display(uchar num)
{
    uchar a,b;
    a = num / 10;
    b = num % 10;
    
    tube2 = 0;
    tube1 = 1;
    P0 = table[a];
    delayms(2);
    tube1 = 0;
    
    tube1 = 0;
    tube2 = 1;
    P0 = table[b];
    delayms(2);
    tube2 = 0;
}
行,列 显示
void now_x(uchar num)
{
    tube2 = 0;
    tube1 = 1;
    P0 = table[num];
    delayms(2);
    tube1 = 0;
}
void now_y(uchar num)
{
    tube1 = 0;
    tube2 = 1;
    P0 = table[num];
    delayms(2);
    tube2 = 0;
}
/* * * * * * * * * * * * * * * * * * * * * * * * * *
 *传感器单元
 * * * * * * * * * * * * * * * * * * * * * * * * * *
 *
 *红外发射
 */
void mouse_ir_on(uchar group_no)
{
    A0 = (group_no) & 0x01;
    A1 = (group_no) & 0x02;
    A2 = (group_no) & 0x04;
}

/*
 *设置T2自动重装载寄存器和计数器
 */
void setTime2(uint us)
{
    TH2 = (65536 - us) % 256;
    RCAP2H = (65536 - us) / 256;
    TL2 = (65536 -us) % 256;
    RCAP2L = (65536 - us) % 256;
}
/*
 *定时计数器初始化
 */
void initTime2()
{
    EA = 1;
    ET2 = 1;
    setTime2(5000);//设置5ms中断一次
    TR2 = 1;
}
/*
 *避障测试
 */
void test()
{
    if(!irR)
    {
        turn_right();
        delayms(500);
        go_straight();
        delayms(1000);
    }
    else if(!irC)
    {
        go_straight();
        delayms(500);
        delayms(1000);
    }
    else if(!irL)
    {
        turn_left();
        delayms(500);
        go_straight();
        delayms(1000);
    }
    else
    {
        back();
        delayms(500);
        go_straight();
        delayms(500);
        voice();
        delayms(1000);
    }
      
}
void ir_test(){ // 测试某个方向的红外
   
        if(irL||irR||irC){
            beep = 0;
        }else{
            beep = 1;
        }
   
}
/* * * * * * * * * * * * * * * 
 * 第一部分 遍历迷宫
 * 地图初始化
 */
void init_map()
{
    uchar i,j;
    //入栈
    top++;
    stack[top][0] = location[0];
    stack[top][1] = location[1];
    for(i=0;i<8;i++)
    {
        for(j=0;j<8;j++)
        {
            map[i][j] = 0xff;
        }
    }
}
    
 /*
 *记录当前位置信息
 */
void save()
{     unsigned char temp = 0,count = 0,temp1 = 0;
        switch(direction)//地图信息的记录* * * * 初次进入此单元格
        {
            case 0:temp+=irC; temp<<=1 ; temp+=irR; temp<<=2; temp+=irL; map[location[0]][location[1]] &= (0xf0+temp); map[location[0]][location[1]] &= 0xdf; break;
            case 1:temp+=irL; temp<<=1 ; temp+=irC; temp<<=1; temp+=irR; temp<<=1; map[location[0]][location[1]] &= (0xf0+temp); map[location[0]][location[1]] &= 0xef; break;
            case 2:temp+=irL; temp<<=1 ; temp+=irC; temp<<=1; temp+=irR; map[location[0]][location[1]] &= (0xf0+temp); map[location[0]][location[1]] &= 0x7f; break;
            case 3:temp+=irR; temp<<=2 ; temp+=irL; temp<<=1; temp+=irC; map[location[0]][location[1]] &= (0xf0+temp); map[location[0]][location[1]] &= 0xbf; break;
        }
        if(location[0] == 7 && location[1] == 0)
        map[7][0] = 0xf7;
        //判断是否为岔路口
        if((!irC) && pass(0))
            count++;
        if((!irR) && pass(1))
            count++;
        if((!irL) && pass(3))
            count++;
        if(count>=2)//记录岔路口信息
        {
            top++;
            stack[top][0] = location[0];
            stack[top][1] = location[1];
        }
}    
/*
 *检查当前要走的方向是否走过
 *走过为0,否则为1
 */
uchar pass(uchar way)
{
        unsigned char x1,y1;
      x1 = location[0];
      y1 = location[1];
        switch(direction)
        {
            case 0: 
            {
                switch(way)
                {
                    case 0: if(map[x1 - 1][y1] == 0xff) return 1;  return 0;//上 
                    case 1: if(map[x1][y1 + 1] == 0xff) return 1;  return 0;//右 
                    case 3: if(map[x1][y1 - 1] == 0xff) return 1;  return 0;//左 
                }
                
            }
            case 1: 
            {
                switch(way)
                {
                    case 0: if(map[x1][y1+1] == 0xff) return 1;  return 0;//右
                    case 1: if(map[x1+1][y1] == 0xff) return 1;  return 0;//下
                    case 3: if(map[x1-1][y1] == 0xff) return 1;  return 0;//上 
                }
            }
            case 2: 
            {
                switch(way)
                {
                    case 0: if(map[x1+1][y1] == 0xff) return 1;  return 0;//下 
                    case 1: if(map[x1][y1-1] == 0xff) return 1;  return 0;//左
                    case 3: if(map[x1][y1+1] == 0xff) return 1;  return 0;//右 
                }
            }
            case 3: 
            {
                switch(way)
                {
                    case 0: if(map[x1][y1-1] == 0xff) return 1; return 0;//左 
                    case 1: if(map[x1-1][y1] == 0xff) return 1; return 0;//上
                    case 3: if(map[x1+1][y1] == 0xff) return 1; return 0;//下 
                }
            }
        }
}
/*
 * * 更新当前位置信息
 * 上 右 下 左 0 1 2 3
 */
void move()
{
    switch(direction)
    {
        case 0: {
            location[0] -= 1;
            break;
        }
        case 1:{
          location[1] += 1;
          break;
      }
        case 2:{
            location[0] += 1;
            break;
        }
        case 3:{
            location[1] -= 1;
            break;
        }
    }
}    
/*
 * 回溯
 */
void recall()
{
    unsigned char temp = 0,count = 0,temp1 = 0,i = 0; 
    temp = map[location[0]][location[1]];
    while(1)
    {
        temp = map[location[0]][location[1]];
        if(!((temp >>= 4) & 0x01))//左
        {
            
            switch(direction)
            {
                case 0: turn_left(); delayms(100); go_straight();delayms(100); break;
                case 1: back();delayms(100);go_straight();delayms(100); break;
                case 2: turn_right(); delayms(100); go_straight();delayms(100); break;
                case 3: go_straight(); delayms(100); break;
            }
            move(); 
            temp = map[location[0]][location[1]];
        }
        //显示当前坐标
      now_x(location[0]);
      now_y(location[1]);
        if(location[0] == stack[top][0] && location[1] == stack[top][1])
            break;
          
        
        temp = map[location[0]][location[1]];
        if(!((temp >>= 5) & 0x01))//下
        {
            switch(direction)
            {
                case 0: back();delayms(100);go_straight();delayms(100); break;
                case 1: turn_right(); delayms(100);go_straight();delayms(100);break;
                case 2: go_straight(); delayms(100); break;
                case 3: turn_left();delayms(100);go_straight();delayms(100);break;
            }
            move();
            temp = map[location[0]][location[1]];
        }
        //显示当前坐标
      now_x(location[0]);
      now_y(location[1]);
        if(location[0] == stack[top][0] && location[1] == stack[top][1])
            break;
        
        temp = map[location[0]][location[1]];
        if(!((temp >>= 6) & 0x01))//右
        {
            switch(direction)
            {
                case 0: turn_right();delayms(100);go_straight();delayms(100);break;
                case 1: go_straight();delayms(100); break;
                case 2: turn_left();delayms(100);go_straight();delayms(100); break;
                case 3: back();delayms(100);go_straight();delayms(100); break;
            }
             move();
            temp = map[location[0]][location[1]];
        }
        //显示当前坐标
      now_x(location[0]);
      now_y(location[1]);
        if(location[0] == stack[top][0] && location[1] == stack[top][1])
            break;
        
        temp = map[location[0]][location[1]];
        if(!((temp >>= 7) & 0x01))//上
        {
            switch(direction)
            {
                case 0: go_straight(); delayms(100); break;
                case 1: turn_left();delayms(100);go_straight();delayms(100);  break;
                case 2: back();delayms(100);go_straight();delayms(100);  break;
                case 3: turn_right();delayms(100); go_straight();delayms(100);break;
            }
            move(); 
            temp = map[location[0]][location[1]];
        }
        //显示当前坐标
      now_x(location[0]);
      now_y(location[1]);
        if(location[0] == stack[top][0] && location[1] == stack[top][1])
            break;
    }
    top--;//弹栈 
}
/* 
 *遍历迷宫
 */
void find()
{
      //显示当前坐标
      now_x(location[0]);
      now_y(location[1]); 
      //等待检测
//      delayms(2);
      //判断当前位置是否为第一次到达
      if(map[location[0]][location[1]] == 0xff)
      save();
      
          if(irR==0&&pass(1))//右边无挡板且未走过
            {
                turn_right();
                delayms(100);
                go_straight();
                delayms(500);
                move();
            }
            else if(irC==0&&pass(0))//右边有挡板,前边无且未走过
            {
                go_straight();
                delayms(500);
                move();
            }
            else if(irL==0&&pass(3))//右边有挡板前边有,左边无
            {
                turn_left();
                delayms(100);
                go_straight();
                delayms(500);
                move();
            }
            else//死胡同
            {
                recall();
            }

}
/* * * * * * * * * * * * * * 
 * 第二部分 寻找最优路径
 * 地图设置
 */
void set_map()
{
    unsigned char i,j,temp=0;
    for(i = 0; i < N ; i++)
    {
        for(j = 0;j < N; j++)
        {
            temp = map[i][j];
            temp &= 0x0f;
            temp += 0x10; 
            map[i][j] = temp;
        }
    }

/*
 * 开始寻路
 */
void go_map(){//遍历地图
     char  count = 1, num = 1, loop = 1, first = 0, temp1 = 0, flag = 0;
    unsigned char temp[2] = {0} ;
    record(7,0);//起点坐标.............. 
    while(1){
        if(head >=rear )return ;//当队头和队尾相等时,退出
        temp[0] = b[0][0];
        temp[1] = b[0][1];
        pop();

        if( temp[0] == 0 && temp[1] == 7){//当走到终点时,用way 数组又保存返回到起点的路径
            map[temp[0]][temp[1]] = num++;
            return ;
        }
         temp1 = map[temp[0]][temp[1]];
         flag = 0;
        //左方 
        if((!(temp1 &= 0x01)) && map[temp[0]][temp[1]-1] >> 4)//遍历四个方向,只要满足条件,//就加入队列
        {
            record(temp[0] , temp[1] -1 ); 
            flag += 1;
        }
        //下方
         temp1 = map[temp[0]][temp[1]]; 
         temp1 >>= 1;
        if((!(temp1 &= 0x01)) && map[temp[0]+1][temp[1]] >>4){
            record(temp[0] + 1 ,temp[1] ); 
            flag += 1;
        }
        //右方
        temp1 = map[temp[0]][temp[1]];
        temp1 >>= 2; 
        if((!(temp1 &= 0x01)) && map[temp[0]][temp[1]+1] >>4){
            record(temp[0] ,temp[1] + 1 );
            flag += 1;
        }
        temp1 = map[temp[0]][temp[1]];
        temp1 >>= 3; 
        //上方 
        if((!(temp1 &= 0x01)) && map[temp[0]-1][temp[1]] >>4){
            record(temp[0]- 1 ,temp[1]);
            flag += 1;
        }
        if(flag >=2 && first == 0)
        {
            count += flag - 1;
            first = 1;
        }
        else if(flag >= 2){
            count += flag - 1;
        }
        if(flag >0){
            map[temp[0]][temp[1]] = num;
            loop --; 
        }
        else{
            map[temp[0]][temp[1]] = num;
            loop --;
            count --;
        }
    
        if(loop == 0)
        {
            loop = count;
            num++;
        }
    }
}
/*
 * 准备冲刺
 */
void final_way()
{
    
    char x = 0, y = 7;//终点坐标 
    while(1)
    {
            if(x == 7 && y == 0)//起点坐标 
            break;
            if((map[x-1][y] == (map[x][y] - 1)) && (x-1 >=0))//上方 
            {
                top1++;
                way[top1] = 2;
                x -= 1; 
                continue;
            }
            if((map[x][y+1] == (map[x][y] - 1)) && (y+1 <= 7))//右方 
            {
                top1++;
                way[top1] = 3;
                y += 1; 
                continue;
            }
            if((map[x+1][y] == (map[x][y] - 1)) && (x+1 <= 7))//下方 
            {
                top1++;
                way[top1] = 0;
                x += 1; 
                continue;
            }
            if((map[x][y-1] == (map[x][y] - 1)) && (y-1 >= 0))//左方 
            {
                top1++;
                way[top1] = 1;
                y -= 1; 
                continue;
            }
    }
}  
/* * * * * * * * * * * * * 
 * 第三部分 冲刺
 * 冲刺
 */
//void run()
//{
//  direction = 2;
//    top1 = 13;
//    back();
//    while(top1 > -1)
//    {
//        switch(direction){
//            case 0:
//                {
//        
//            switch(finall[top1])
//            {
//                case 1: turn_right(); run_fast() ; break;
//                case 0: run_fast() ; break; 
//            }
//            break;
//        }
//            case 1:{
//                
//            
//            switch(finall[top1])
//            {
//                case 1: run_fast() ;break;
//                case 0: turn_left(); run_fast() ; break; 
//            }    
//            break;
//        }
//       }
//        top1--;
//    }    

//} 


void main()
{
//    initTime2();//初始化定时器
//    while(1){
//        //test();
//        ir_test();
//    }
    
    initTime2();//初始化定时器
    init_map();//初始化地图
    while(top >= 0)
    {
        delayms(500);
        find();//遍历地图
    }

    set_map();//处理地图
    
    init();//初始化队列
    
    go_map();//寻路
    
    final_way();//准备冲刺
    
//    run();//冲刺
//    voice();
//    voice();
//    voice();
    while(1);
}
/*
 *中断服务函数
 */
void time2() interrupt 5{ // TIM2中断服务函数
    static bit ir = 0;
    static unsigned char n=1;
    TF2 = 0;
    if(!ir)    {
        mouse_ir_on(n-1);
    }else{
        if(n==1){
            if(irR1)    irC=0;
            else            irC=1;
        }else if(n==2){
            if(irR2)    irLU=0;
            else            irLU=1;
        }else if(n==3){
            if(irR3)    irL=0;
            else            irL=1;
        }else if(n==4){
            if(irR4)    irR=0;
            else            irR=1;
        }else if(n==5){
            if(irR5)    irRU=0;
            else            irRU=1;
        }
    }
    if(ir)    n++;
    if(n>5)    n=1;
    ir=~ir;
}

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值