⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 control_dir.c

📁 ucos-II源代码
💻 C
字号:
#include"19#405.h"

#define ON_LINE 90             // 主红外踩到黑线的临界值
#define ON_LINE_LOW 20     // 从红外踩到黑线的临界值
#define LEFT 1
#define RIGHT 2
#define MIDLE 0    


/*******当前状态记录值********/
char this_side = 0 ;              // 当今偏离的程度记录
unchar side_cal = 0 ;           // 在一段时间内的偏离程度的累计
unchar is_on_line = 1 ;         // 黑线在可视范围内的标志
unchar is_on_line_low = 1 ;
unchar l_or_r = 0 ;               // 上一个状态黑线是处于左边还是右边还是中间
unchar l_or_r_low = 0 ;
extern unchar led_show1 ;  
extern unchar led_show2 ;   
/*********起跑线的检测记录值***********/
//unchar status[ 7 ] = { 0, 0, 0, 0, 0, 0 } ;     // 对于一段时间内起跑线的检测状态的记录
unchar start_line = 0 ;                               // 经过起跑线的记录
 
/***********指向舵机偏离值表的指针*******/        
unchar* table_dir ;

void Control_dir( ATD atdget, unchar* dir )
{   
//静态变量
        static char num_lowest = 3 ;          // 当前踩到黑线的对管的代号
        static char pre_dir = DIR_MID ;     // 上一个状态的舵机的偏转值的记录  
        unchar pre_is_on_line = 1 ;           // 上一个状态的黑线是处于左边还是右边    
        unchar *ptr = &atdget.left3 ;           // 指向数据结构的指针,便于循环判断查询
        unchar counter ;                           // 循环辅助变量
        unchar atd_lowest = 255 ;             // 当前踩到黑线的对管采回的最小的AD值
        char pre_num_lowest ;                  // 上一个状态踩到黑线的对管的编号
       
        // 将上个状态的值记录下来
        pre_num_lowest = num_lowest ;     
        pre_is_on_line = is_on_line ;
      
        is_on_line = 0 ;
        num_lowest = 3 ;

        // 循环查找踩到黑线的红外对管的编号
        for( counter = 0; counter < 7; counter ++ )
        {
                if( *ptr < ON_LINE )
                {
                          is_on_line = 1 ;
                          if( *ptr < atd_lowest )
                          {
                                num_lowest = counter ;
                                atd_lowest = *ptr ;
                          }
                }
                ptr ++ ;
        }
 
 /********************************错误状况的判断及错误的解除*********************************/ 
        // 当上一个状态离线而这个状态踩到黑线时,如果出现两极情况,认为仍然离线      
        if( ( 0 == pre_is_on_line ) && ( 1 == is_on_line ) ) 
        {
            /*   if( 0 == is_on_line_low )
               {
                        is_on_line = 0 ;
                        l_or_r = l_or_r_low ;
               }       */
                if( 1 == l_or_r )               // 当上一个状态黑线处于左边,当今状态判断到右边                   
                {
                        if( num_lowest != 0 ) 
                                is_on_line = 0 ;
                }
                else if( 2 == l_or_r )          // 当上一个状态黑线处于右边,当今状态判断到左边
                {
                        if( num_lowest !=  6 )
                                is_on_line = 0 ;
                }                      
        }   
// 当相近的两个状态相差很大时,认为上一个状态正确     
     if( ( pre_num_lowest - num_lowest > 1 ) 
                                || ( pre_num_lowest - num_lowest < -1 ) ) 
                num_lowest = pre_num_lowest ;                         
/***********************************************************************************************************/        

// 当认为采集的数据正确时,开始对舵机及各个记录值进行处理
        if( is_on_line )
        {
        // 判断当前的黑线在左边还是右边
                if( num_lowest < 3 ) 
                        l_or_r = LEFT ;                  // 在左边
                else if( num_lowest > 3 )
                        l_or_r = RIGHT ;                // 在右边
                else 
                        l_or_r = MIDLE ;                // 在中间             
                switch( num_lowest  )   
                {
                        case 0 :
                        {
                                if( atdget.left2 > ON_LINE )
                                        *dir = table_dir[ 0 ] ;
                                else if( atdget.left2 > ( ON_LINE - 10 ) )
                                        *dir = table_dir[ 1 ] ;
                                else
                                        *dir = table_dir[ 2 ] ; 
                                        
                                this_side = -6 ;        
                                side_cal += 3 ;
                                break ;
                        }
                        case 1 :
                        {
                               if( atdget.left3 < ( ON_LINE - 10 ) )
                                        *dir = table_dir[ 3 ] ;
                               else if( atdget.left3 < ON_LINE ) 
                                        *dir = table_dir[ 4 ] ;
                                else if( atdget.left2 < ( ON_LINE - 10 ) )
                                        *dir = table_dir[ 7 ] ;
                                else if( atdget.left2 < ON_LINE  ) 
                                        *dir = table_dir[ 6 ] ;
                                else 
                                        *dir = table_dir[ 5 ] ;   
                                
                                this_side = -2 ;
                                side_cal += 2 ;
                                break ;
                        }
                        case 2 :
                        {
                                if( atdget.left1 < ( ON_LINE - 10  ) )
                                        *dir = table_dir[ 8 ] ;
                               else if( atdget.left1 < ON_LINE )
                                        *dir = table_dir[ 9 ] ;
                                else if( atdget.mid < (  ON_LINE - 10 ) )
                                         *dir = table_dir[ 12 ] ;
                                else if( atdget.mid < ON_LINE )
                                        *dir = table_dir[ 11 ] ;
                                else 
                                        *dir = table_dir[ 10 ] ;
                                this_side = -1 ;
                                side_cal += 1 ;
                                break ;
                        }
                        case 3 :
                        {
                                
                              if( atdget.left1 < ( ON_LINE - 10 ) )
                                        *dir = table_dir[ 13 ] ;
                                else if( atdget.left1 < ON_LINE )
                                        *dir = table_dir[ 14 ] ;
                                else if( atdget.right2 < ( ON_LINE - 10 ) )
                                        *dir = table_dir[ 17 ] ;
                                else if( atdget.right2< ON_LINE ) 
                                        *dir = table_dir[ 16 ] ;
                                else 
                                        *dir = table_dir[ 15 ] ;      
                                this_side = 0 ;
                                break ; 
                        } 
                        case 4 :
                        {
                                if( atdget.mid < ( ON_LINE - 10 ) )
                                        *dir = table_dir[ 18 ] ;
                                else if( atdget.mid < ON_LINE )
                                        *dir = table_dir[ 19 ] ;
                                else if( atdget.right2 < ( ON_LINE - 10 ) )
                                        *dir = table_dir[ 22 ] ;
                                else if( atdget.right2 < ON_LINE )
                                        *dir = table_dir[ 21 ] ;
                                else 
                                        *dir = table_dir[ 20 ] ;
                                side_cal += 1;
                                this_side = 1 ; 
                                break ;
                         }
                        case 5 :
                        {
                                if( atdget.right1 < ( ON_LINE - 10 ) )
                                        *dir = table_dir[ 23 ] ;
                                else if( atdget.right1 < ON_LINE )
                                        *dir = table_dir[ 24 ] ;
                                else  if( atdget.right3 < ( ON_LINE - 10 ) ) 
                                        *dir = table_dir[  27 ] ;
                                else if( atdget.right3 < ON_LINE )
                                        *dir = table_dir[ 26 ] ;
                                else 
                                        *dir = table_dir[ 25 ] ;
                                side_cal += 2 ;
                                this_side = 2 ;
                                break ;
                         } 
                        case 6 :
                        {
                                if( atdget.right2  < ( ON_LINE - 10  ) )
                                        *dir = table_dir[ 28 ] ;
                                else if( atdget.right2 < ON_LINE ) 
                                        *dir = table_dir[ 29 ] ;
                                else 
                                        *dir = table_dir[ 30 ] ;
                                side_cal += 3 ;
                                this_side = 6 ;
                                 break ;
                        }
                      
                }     
                 if( 0 == is_on_line_low )
                 {
                        if( ( LEFT == l_or_r ) && ( RIGHT == l_or_r_low ) )
                                *dir += 3 ;
                        else if( ( RIGHT == l_or_r ) && ( LEFT == l_or_r_low ) )
                                *dir -= 3 ;               
                 }
                                
        }
                  
// 如果处于离线状态则进行最大便移量处理                
        else
        {
                if( LEFT == l_or_r )  
                {
                        
                        *dir = DIR_LMAX ;
                        num_lowest = 0 ;
                }
                else if( RIGHT == l_or_r )
                {
                        
                        *dir = DIR_RMAX ;
                        num_lowest = 6 ;
                }
                else
                        *dir = DIR_MID ;
                side_cal += 4 ;
                
        } 
        led_show2 = num_lowest ;      
        led_show1 = l_or_r_low ;      
}



 void Check_StartLine( ATD atd_start )
 {
        unchar counter ; 
        unchar show_temp = 0 ;                          // 用于显示下排红外的踩线情况的临时变量
        unchar *ptr = &atd_start.left3 ;
        unchar deal_flag = 0 ;
        is_on_line_low = 0 ;
        /***********对起跑线的检测测试显示***************/       
//        PORTB |= 0x7F ;
        for( counter = 0; counter < 7; counter ++ )
       {
                if( *ptr < ON_LINE_LOW )
                {
                        //PORTB &= ~( 1 << counter ) ;
    //                    show_temp |= ( 1 << counter ) ;
                        is_on_line_low = 1 ;
                        break ;
                }
                ptr ++ ;
        }
//        PORTB = ~show_temp ;
        /********************************************************/
       if( is_on_line_low )
        {
                if( counter < 2 ) 
                        l_or_r_low = LEFT ;
                else if( counter > 4 ) 
                        l_or_r_low = RIGHT ;
                else 
                        l_or_r_low = MIDLE ;        
                
  //              PORTB = ~( l_or_r_low  << 4 ) ;
                ptr = &atd_start.left3 ;
                if( ON_CROSS != start_line )
                {
                        unchar *ptr_last = &atd_start.right3 ;
                        unchar scan_temp = 0 ;
                        ptr = &atd_start.left3 ;
                        while( ptr < ptr_last ) 
                        {
                                if( *ptr < ON_LINE_LOW )
                                {
                                        if( scan_temp )
                                        {
                                                start_line = ON_START ;
                                                deal_flag = 1 ;
                                                break ;
                                        }
                                        if( *( ptr + 1 )  > ON_LINE_LOW  )
                                        {
                                                scan_temp = 1 ;
                                                ptr ++ ;
                                        }
                                       
                                }
                                ptr ++ ;
                        }
                }
                if( 0 == deal_flag ) 
                {        
                        for( counter = 0; counter < 5; counter ++ )
                        {
                        
                                if( ( *ptr < ON_LINE_LOW ) 
                                        && ( *( ptr + 1 ) < ON_LINE_LOW ) 
                                                && ( *( ptr + 2 ) < ON_LINE_LOW ) )
                                                        
                                                        start_line = ON_CROSS ;      

                                ptr ++ ;
                        }
                }
        }
          
 }         
/***********************************************************/




	
	

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -