单片机/MCU论坛
直播中

张珍霞

7年用户 3经验值
擅长:单片机
私信 关注
[问答]

求助PS2控制小车问题

一段基于STC12C5A60S2的手柄控制小车的程序,其他案件都可以控制,但是加减速度两个按键按下去只是加减一瞬间。就回到原来的速度。。。。求助大神啊,瞎摆弄好几天了。。。直接用宏定义小车加速没反应,单独写又只加速一瞬间。


#include "STC12C5A60S2.h"
#include "stdio.h"
//#include "uart_printf.h"
#include "ps2.h"


#define SPIF (SPSTAT&0X80)
#define ON 1     //使能LED
#define OFF 0    //禁止LED


                                                                                                                           
//unsigned char SPI_Buffer=0;


//定义电机引脚
***it Left_motor_go=P2^1;            //左电机前进AIN2
***it Left_motor_back=P2^2;           //左电机后退AIN1
***it Right_motor_go=P2^4;           //右电机前进BIN2
***it Right_motor_back=P2^3;           //右电机后退BIN1
***it Left_motor_pwm=P2^0;           //左电机控速PWMA
***it Right_motor_pwm=P2^5;           //右电机控速PWMB


unsigned char pwm_val_left  =0;//变量定义
unsigned char pwm_val_right =0;


//速度调节变量 0-20,0最小,20最大
unsigned char push_val_left =5;// 左电机占空比push_val_left/20
unsigned char push_val_right=5;// 右电机占空比push_val_right/20


***it FM=P2^7;           //蜂鸣器
***it LED_B=P3^4;
***it LED_G=P3^2;
***it LED_R=P3^3;                          
bit Left_PWM_ON=1;
bit Right_PWM_ON=1;


//unsigned char SPI_Rec_flag;


unsigned char  time;
//unsigned char  scan[9];
unsigned char FIRE;




//小车运行状态枚举
enum{
  enSTOP = 0,
  enRUN,
  enBACK,
  enLEFT,
  enRIGHT,
  enUPLEFT,
  enUPRIGHT,
  enDOWNLEFT,
  enDOWNRIGHT,
  enSPINLEFT,
  enSPINRIGHT
}enCarState;


/*
#define         enMinMin()         {push_val_left =20;push_val_right =20;}
#define         enMin()                 {push_val_left =24;push_val_right =24;}
#define         enMidle()        {push_val_left =28;push_val_right =28;}
#define                enMax()                 {push_val_left =32;push_val_right =32;}
*/




#define         enMinMin() do{
                       push_val_left =5;
                                           push_val_right =5;
                                           }while(0)


#define         enMin() do{
                       push_val_left =10;
                                           push_val_right =10;
                                           }while(0)


#define         enMidle() do{
                       push_val_left =15;
                                           push_val_right =15;
                                           }while(0)


#define         enMax() do{
                       push_val_left =20;
                                           push_val_right =20;
                                           }while(0)
                                          


/*
#define         enMin()                 {push_val_left =24;push_val_right =24;}
#define         enMidle()        {push_val_left =28;push_val_right =28;}
#define                enMax()                 {push_val_left =32;push_val_right =32;}
*/
//uchar g_volume=0;
int g_volume = 0;
int g_carstate = 0;


//延时函数        
void delay(unsigned int xms)                                
{
    unsigned int i,j;
        for(i=xms;i>0;i--)                     
    for(j=850;j>0;j--);
}
                        
void pwm_out_left_motor(void)                        //左电机调速
{  
     if(Left_PWM_ON)
     {
          if(pwm_val_left<=push_val_left)
              {
                  Left_motor_pwm =1;
              }
              else
              {
                   Left_motor_pwm=0;
          }
          if(pwm_val_left>=20) //这里的20代表的是pwm为20ms即50hz
              pwm_val_left=0;
     }
     else   
     {
          Left_motor_pwm=0;   //若未开启PWM则PWMA=0 左电机停止
     }
}


void pwm_out_right_motor(void)                   //右电机调速
{
    if(Right_PWM_ON)
    {
        if(pwm_val_right<=push_val_right)        
            {
                Right_motor_pwm=1;                                                         
        }
            else
            {
                Right_motor_pwm=0;
        }
            if(pwm_val_right>=20) //这里的20代表的是pwm为20ms即50hz
            pwm_val_right=0;
    }
    else   
    {
        Right_motor_pwm=0;          //若未开启PWM则PWMB=0右电机停止
    }
}


//       小车前进
void run(unsigned int time)
{
  //左电机前进
  Left_motor_go = 1;   //左电机前进使能
  Left_motor_back = 0;   //左电机后退禁止
  //更新指定管脚的PWM值,更改可实现控速(0-20)
  //push_val_left=10;
         
  //右电机前进
  Right_motor_go=1;   //右电机前进使能
  Right_motor_back=0;  //右电机后退禁止
  //更新指定管脚的PWM值,更改可实现控速(0-20)
  //push_val_right=10;
  
  //延时
  delay(time * 100);
  return;
}


//      小车停止
void brake(unsigned int time)
{
  //左电机停止
  Left_motor_go = 0;   //左电机前进禁止
  Left_motor_back = 0; //左电机后退禁止
         
  //右电机停止
  Right_motor_go=0;   //右电机前进禁止
  Right_motor_back=0;  //右电机后退禁止

  //延时
  delay(time * 100);
  return;
}


//     小车左转 左转(左轮不动,右轮前进)
void left(unsigned int time)
{
  //左电机停止
  Left_motor_go = 0;   //左电机前进禁止
  Left_motor_back = 0;   //左电机后退禁止
  //更新指定管脚的PWM值,更改可实现控速(0-20)
  push_val_left=0;
         
  //右电机前进
  Right_motor_go=1;   //右电机前进使能
  Right_motor_back=0;  //右电机后退禁止
  //更新指定管脚的PWM值,更改可实现控速(0-20)
  push_val_right=10;
  
  //延时
  delay(time * 100);
  return;
}


//  小车右转 (左轮前进,右轮不动)
void right(unsigned int time)
{
  //左电机前进
  Left_motor_go = 1;   //左电机前进使能
  Left_motor_back = 0;   //左电机后退禁止
  //更新指定管脚的PWM值,更改可实现控速(0-20)
  push_val_left=10;
  //printf("PSB_motor_right !n");
         
  //右电机停止
  Right_motor_go=0;   //右电机前进禁止
  Right_motor_back=0;  //右电机后退禁止
  //更新指定管脚的PWM值,更改可实现控速(0-20)
  push_val_right=0;
  
  //延时
  delay(time * 100);
  return;
}


void spin_left(unsigned int time)
{
  //左电机后退
  Left_motor_go = 0;   //左电机前进禁止
  Left_motor_back = 1;   //左电机后退使能
  //更新指定管脚的PWM值,更改可实现控速(0-20)
  push_val_left=18;
         
  //右电机前进
  Right_motor_go=1;   //右电机前进使能
  Right_motor_back=0;  //右电机后退禁止
  //更新指定管脚的PWM值,更改可实现控速(0-20)
  push_val_right=18;
  
  //延时
  delay(time * 100);
  return;
}


void spin_right(unsigned int time)
{
  //左电机前进
  Left_motor_go = 1;   //左电机前进使能
  Left_motor_back = 0;  //左电机后退禁止
  //更新指定管脚的PWM值,更改可实现控速(0-20)
  push_val_left=18;
         
  //右电机后退
  Right_motor_go=0;   //右电机前进禁止
  Right_motor_back=1;  //右电机后退使能
  //更新指定管脚的PWM值,更改可实现控速(0-20)
  push_val_right=18;
  
  //延时
  delay(time * 100);
  return;
}


void up_right(unsigned int time)        //右上
{


        Left_motor_go=1;
        Left_motor_back=0;
        push_val_left=18;


        Right_motor_go=1;
        Right_motor_back=0;
        push_val_right=10;


        delay(time * 100);
    return;
}


void down_right(unsigned int time)        //右下
{
        
        Left_motor_go=0;
        Left_motor_back=1;
        push_val_left=18;


        Right_motor_go=0;
        Right_motor_back=1;
        push_val_right=10;


        delay(time * 100);
    return;
}


void up_left(unsigned int time)          //左上
{
   
        Left_motor_back=0;
        push_val_left=10;


        Right_motor_go=1;
        Right_motor_back=0;
        push_val_right=18;


        delay(time * 100);
    return;
}


void down_left(unsigned int time)        //左下
{
   //Left_moto_back;  
   //Right_moto_back;  
   //push_val_left = 10;
   //push_val_right = 25;
           Left_motor_go=0;
        Left_motor_back=1;
        push_val_left=10;


        Right_motor_go=0;
        Right_motor_back=1;
        push_val_right=18;


        delay(time * 100);
    return;
}


//  小车后退
void back(unsigned int time)
{
  //左电机后退
  Left_motor_go = 0;   //左电机前进禁止
  Left_motor_back = 1; //左电机后退使能
  //更新指定管脚的PWM值,更改可实现控速(0-20)
  push_val_left=10;
         
  //右电机后退
  Right_motor_go=0;   //右电机前进禁止
  Right_motor_back=1; //右电机后退使能
  //更新指定管脚的PWM值,更改可实现控速(0-20)
  push_val_right=10;
  
  //延时
  delay(time * 100);
  return;
}
/*
void setspeed()
{
        switch(g_volume)
        {
                case 1: enMinMin();break;
                case 2: enMin();break;
                case 3: enMidle();break;
                case 4: enMax();break;
                //default:enMidle();break;
        }
                             
}
*/


//    TIMER0中断服务子函数产生PWM信号,
void timer0()interrupt 1
{
     TH0=0XFC;              //1Ms定时
         TL0=0X66;
         pwm_val_left++;
         pwm_val_right++;
         pwm_out_left_motor();
         pwm_out_right_motor();
}


//pwm初始化                利用定时器0
void pwm_Init(void)
{
        TMOD |=0X01;        //定时器工作方式1
        TH0= 0XFC;  //1ms定时
    TL0= 0X66;
        TR0= 1;                 //启动T0工作
        ET0= 1;                          //允许T0中断
        EA = 1;            //开总中断


}




void UartInit(void)   //初始化波特率为9600
{
    SCON=0x50;  
    TMOD=0x20;
    TCON=0x40;
    TH1=0xfd;
    TI=1;
    TR1=1;
}




void color_led(int v_iRed, int v_iGreen, int v_iBlue)
{
  //红色LED
  v_iRed == ON ? (LED_R = 1): (LED_R = 0);

  //绿色LED
  v_iGreen == ON ? (LED_G = 1): (LED_G = 0);
  
  //蓝色LED
  v_iBlue == ON ? (LED_B = 1): (LED_B = 0);
}




void main()
{
    //printf("PS:%xn", PS2->FunBtn);
    stPS2KeyValue * PS2;
        UartInit();
    P2=0XC0;       //关电机        
        P1 = 0xff;           //关闭所有LED和风扇
        FIRE = 0;
        pwm_Init();
        printf("PS:fdsgfdsrn");


        /*while(1)
        {
                 Left_motor_go = 0;
                 delayms(1);
                 Left_motor_go = 1;
                 delayms(1);


        } */


        PS2_Init();
        while(1)        //无限循环
        {
            


                PS2 = ReadPS2KeyValue();


                printf("PS:%xn", PS2->FunBtn);




                if((PS2->FunBtn & PSB_SELECT) == 0)
                {
//                  uart_sendbyte("start3");
                  printf("PSB_SELECT!n");
                }
               


                if((PS2->FunBtn & PSB_START) == 0)
                {
                  printf("PSB_START!n");
                }
                 
                if((PS2->FunBtn & PSB_L3) == 0)
                {
                         printf("PSB_L3!n");
                         g_carstate = enSTOP;
                }


                if((PS2->FunBtn & PSB_R3) == 0)
                {
                         printf("PSB_R3!n");
                         g_carstate = enSTOP;
                }


                //方向控制
                if((PS2->FunBtn & PSB_PAD_UP) == 0)
                {
                         printf("PSB_PAD_UP!n");
                         g_carstate = enRUN;
                }


                else if((PS2->FunBtn & PSB_PAD_RIGHT) == 0)
                {
                         printf("PSB_PAD_RIGHT!n");
                         g_carstate = enRIGHT;
                }
                else if((PS2->FunBtn & PSB_PAD_DOWN) == 0)
                {
                        printf("PSB_PAD_DOWN!n");
                        g_carstate = enBACK;
                }
                else if((PS2->FunBtn & PSB_PAD_LEFT) == 0)
                {
                         printf("PSB_PAD_LEFT!n");
                         g_carstate = enLEFT;
                }
           /*
                else //去掉则按下一直执行,加此段则放开停止
                {
                   //SendBuf("Stop!n");
                   g_carstate = enSTOP;
                }
                 */  
                 if((PS2->FunBtn & PSB_L2) == 0)
                {
                        printf("PSB_L2!n");
                        //g_volume++;
                         g_volume++;
                        printf("PSB_L2_1 !n");
                        if(g_volume>=4)
                        {
                                g_volume = 4;
                        }
                        printf("PSB_L2_1_1 !n");
                        switch(g_volume)
                        {
                                case 1:
                                printf("push_val_left = %dn",push_val_left);
                                //enMinMin();
                                push_val_left=12;push_val_right=12;
                                printf("PSB_l2_4 !n");
                                break;
                                case 2:
                                printf("push_val_left = %dn",push_val_left);  
                        //        enMin();
                            push_val_left=15;push_val_right=15;
                                printf("PSB_l2_4_1 !n");
                                break;
                                case 3:
                                printf("push_val_left = %dn",push_val_left);  
                                //enMidle();
                                push_val_left=18;push_val_right=18;
                                printf("PSB_l2_4_2 !n");
                                break;
                                case 4:
                                printf("push_val_left = %dn",push_val_left);
                                //enMax();
                                push_val_left=20;push_val_right=20;
                                printf("PSB_l2_4_3 !n");
                                break;
                                default:enMidle();
                                break;
                        }
                        printf("PSB_L2_5 !n");
                }
                 
                if((PS2->FunBtn & PSB_R2) == 0)
                {
                        printf("PSB_R2!n");
                        g_volume--;
                        if(g_volume<=0)
                        {
                                g_volume = 1;
                        }
                        
                        switch(g_volume)
                        {
                                case 1:
                                enMinMin();
                                break;
                                 //case 1:push_val_left=10;push_val_right=10;break;
                                case 2:
                                enMin();
                                //push_val_left=14;push_val_right=14;
                                break;
                                case 3:
                                enMidle();
                                //push_val_left=17;push_val_right=17;
                                break;
                                case 4:
                                enMax();
                                //push_val_left=20;push_val_right=20;
                                break;
                                //default:enMidle();break;
                        }
                }
                        
               
                if((PS2->FunBtn & PSB_L1) == 0)
                {
                         printf("PSB_L1!n");
                         //左摇杆*
                    if (PS2->Y1 < 5 && PS2->X1 > 80 && PS2->X1 < 180) //上
                    {
                      g_carstate = enRUN;
                          printf("enRUNn");
                    }
                    else if (PS2->Y1 > 230 && PS2->X1 > 80 && PS2->X1 < 180) //下
                    {
                      g_carstate = enBACK;
                          printf("enBACKn");
                    }
                    else if (PS2->X1 < 5 && PS2->Y1 > 80 && PS2->Y1 < 180) //左
                    {
                      g_carstate = enLEFT;
                          printf("enLEFTn");
                    }
                    else if (PS2->Y1 > 80 && PS2->Y1 < 180 && PS2->X1 > 230)//右
                    {
                      g_carstate = enRIGHT;
                          printf("enRIGHTn");
                    }
                    else if (PS2->Y1 <= 80 && PS2->X1 <= 80) //左上
                    {
                      g_carstate = enUPLEFT;
                          printf("enUPLEFTn");
                    }
                    else if (PS2->Y1 <= 80 && PS2->X1 >= 180) //右上
                    {
                      g_carstate = enUPRIGHT;
                          printf("enUPRIGHTn");
                    }
                    else if (PS2->X1 <= 80 && PS2->Y1 >= 180) // 左下
                    {
                      g_carstate = enDOWNLEFT;
                          printf("enDOWNLEFTn");
                    }
                    else if (PS2->Y1 >= 180 && PS2->X1 >= 180) //右下
                    {
                      g_carstate = enDOWNRIGHT;
                          printf("enDOWNRIGHTn");
                    }
                    else//停
                    {
                      g_carstate = enSTOP;
                    }
                }


                if((PS2->FunBtn & PSB_R1) == 0)
                {
                 printf("PSB_L1!n");
                         //左摇杆*
                    if (PS2->Y2 < 5 && PS2->X2 > 80 && PS2->X2< 180) //上
                    {
                      g_carstate = enRUN;
                          printf("enRUNn");
                    }
                    else if (PS2->Y2 > 230 && PS2->X2 > 80 && PS2->X2 < 180) //下
                    {
                      g_carstate = enBACK;
                          printf("enBACKn");
                    }
                    else if (PS2->X2 < 5 && PS2->Y2 > 80 && PS2->Y2< 180) //左
                    {
                      g_carstate = enLEFT;
                          printf("enLEFTn");
                    }
                    else if (PS2->Y2 > 80 && PS2->Y2 < 180 && PS2->X2 > 230)//右
                    {
                      g_carstate = enRIGHT;
                          printf("enRIGHTn");
                    }
                    else if (PS2->Y2 <= 80 && PS2->X2 <= 80) //左上
                    {
                      g_carstate = enUPLEFT;
                          printf("enUPLEFTn");
                    }
                    else if (PS2->Y2 <= 80 && PS2->X2 >= 180) //右上
                    {
                      g_carstate = enUPRIGHT;
                          printf("enUPRIGHTn");
                    }
                    else if (PS2->X2 <= 80 && PS2->Y2 >= 180) // 左下
                    {
                      g_carstate = enDOWNLEFT;
                          printf("enDOWNLEFTn");
                    }
                    else if (PS2->Y2 >= 180 && PS2->X2 >= 180) //右下
                    {
                      g_carstate = enDOWNRIGHT;
                          printf("enDOWNRIGHTn");
                    }
                    else//停
                    {
                      g_carstate = enSTOP;
                    }
                }        
                       
                if((PS2->FunBtn & PSB_TRIANGLE) == 0) //△ 控制红灯
                {
                         printf("PSB_TRIANGLE!n");
                         //FIRE = (FIRE == 1)?0:1;
                          color_led(ON, OFF, OFF);
                         delay(2000);
                         ReadPS2KeyValue();


                }  
                if((PS2->FunBtn & PSB_CIRCLE) == 0)        // o控制蓝灯
                {
                         printf("PSB_CIRCLE!n");
                         color_led(OFF, OFF, ON);  
                         delay(2000);
                         ReadPS2KeyValue();
                }  
        
                if((PS2->FunBtn & PSB_CROSS) == 0) // × 鸣笛
                {
                        printf("PSB_CROSS!n");
                        FM = 0;
                        delay(2000);
                        FM = 1;
                        ReadPS2KeyValue();
                }
                 
                if((PS2->FunBtn & PSB_SQUARE) == 0)          //控制绿灯
                {
                         printf("PSB_SQUARE!n");
                         color_led(OFF ,ON, OFF);  
                         delay(2000);
                         ReadPS2KeyValue();
                }                             


            switch(g_carstate)
            {
                        case enSTOP:
                                     brake(2);
                                     TR0= 0;
                                     break;
                        case enRUN:
                                     run(2);
                                     TR0= 1;           
                                                 break;
                        case enLEFT:
                                     left(2);
                                     TR0= 1;
                                                  break;
                        case enRIGHT:
                                      right(2);
                                     TR0= 1;
                                                  break;
                        case enBACK:
                                      back(2);
                                     TR0= 1;
                                                  break;
                        case enUPLEFT:
                                      up_left(2);  
                                     TR0= 1;
                                                  break;
                    case enUPRIGHT:
                                        up_right(2);
                                        TR0= 1;
                                                        break;
                    case enDOWNLEFT:
                                         down_left(2);  
                                         TR0= 1;
                                                         break;
                    case enDOWNRIGHT:
                                          down_right(2);
                                          TR0= 1;
                                                          break;
                        case enSPINLEFT:
                                         spin_left(2);
                                         TR0 = 1;
                                                          break;
                        case enSPINRIGHT:
                                          spin_right(2);
                                          TR0 = 1;
                                                           break;
                                          default:
                                                 break;
            }
                delay(50);   
        
        }         
         
}

更多回帖

发帖
×
20
完善资料,
赚取积分