怎么改才能按一下红外遥控器小车动一下,一直按小车才一直动,我这个代码按一下就一直动,模式选择中加stop后按遥控器小车又不能动,怎么改呢


#include <REGX52.H>
#include <INTRINS.H>
#include "UART.h"
#include "Delayms.h"
#include "IR.h"

#define left_pwm P1_0        //左电机pwm信号端
#define right_pwm P1_5        //右电机pwm信号端

#define right_go {P1_1=1;P1_2=0;}        //右电机正转
#define    right_back {P1_1=0;P1_2=1;}        //右电机反转
#define    right_stop {P1_1=0;P1_2=0;}        //右电机停转

#define    left_go {P1_3=0,P1_4=1;}        //左电机正转
#define    left_back {P1_3=1,P1_4=0;}        //左电机反转
#define    left_stop {P1_3=0,P1_4=0;}        //左电机停转

unsigned int pwm_left=0;
unsigned int pwm_right=0;
unsigned int push_left=0;
unsigned int push_right=0;    //pwm递增,当小于push时,pwm信号端输出高电平(相当于push是pwm输出高电平的时间)
unsigned char Command;        //红外遥控控制码



void pwm_out_left()                    //左电机调速函数
{
    if(pwm_left<=push_left)             //此时左电机赋高电平转动(转速加快)
    {
        pwm_left=1;
        pwm_left++;
    }
    else        //此时左电机赋低电平停转(转速下降)
    {
        left_pwm=0;
        pwm_left++;
    }
    if(pwm_left>=20)        //pwm一周期20ms,超过重新开始
    {
        pwm_left=0;
    }
}                             

void pwm_out_right()                    //右电机调速函数
{
    if(pwm_right<=push_right)             //此时右电机赋高电平转动(转速加快)
    {
        right_pwm=1;
        pwm_right++;
    }
    else        //此时右电机赋低电平停转(转速下降)
    {
        right_pwm=0;
        pwm_right++;
    }
    if(pwm_right>=20)        //pwm一周期20ms,超过重新开始
    {
        pwm_right=0;
    }
}    

void go()        //小车前进函数
{
    right_go;
    left_go;    
}

void back()        //小车后退函数
{
    right_back;
    left_back;
}

void left_turn()        //小车左转函数
{
    left_back;
    right_go;
}

void right_turn()        //小车右转函数
{
    right_back;
    left_go;
}

void stop()        //小车停止函数
{
    left_stop;
    right_stop;
}

void car_move(unsigned char mode)
{
    switch(mode)
    {
        case 1:            //模式一前进
            stop();
            go();
            break;
        case 2:            //模式二后退
            stop();
            back();
            break;
        case 3:            //模式三左转
            stop();
            left_turn();
            break;
        case 4:            //模式四右转
            stop();
            right_turn();
            break;
    }
}

void yaokong()
{
    Command=IR_GetCommand();

    if(IR_GetDataFlag())        //红外遥控小车函数,加后半句遥控连续输出
    {
        if(Command==IR_2)                //按2前进
        {
            car_move(1);
            Delayms(50);
        }
        if(Command==IR_8)                //按8后退
        {
            car_move(2);
            Delayms(50);
        }
        if(Command==IR_4)                //按4左转
        {
            car_move(3);
            Delayms(50);
        }
        if(Command==IR_6)                //按6右转
        {
            car_move(4);
            Delayms(50);
        }
        if(Command==IR_5)                //按5停止
            stop();
    }    
}

int main()
{
    IR_Init();
    while(1)
    {
        yaokong();
    }
}
```c
#include <REGX52.H>
#include "Timer.h"
#include "Int0.h"

unsigned int IR_Time;          //计时
unsigned char IR_State;          //状态

unsigned char IR_Data[4];      //得到32位数据存储,分别表示四个字节
unsigned char IR_pData;          //当前存到第几位

unsigned char IR_DataFlag;      //等1说明收到数据
unsigned char IR_RepeatFlag;  //重发标志
unsigned char IR_Address;      //地址码,上面四个字节收完后存储在这
unsigned char IR_Command;      //控制码


void IR_Init(void)
{
    Timer0_Init();
    Int0_Init();
}

unsigned char IR_GetDataFlag(void)    //标志位
{
    if(IR_DataFlag)
    {
        IR_DataFlag=0;
        return 1;
    }
    return 0;
}

unsigned char IR_GetRepeatFlag(void)
{
    if(IR_RepeatFlag)
    {
        IR_RepeatFlag=0;
        return 1;
    }
    return 0;
}

unsigned char IR_GetAddress(void)
{
    return IR_Address;
}

unsigned char IR_GetCommand(void)
{
    return IR_Command;
}


void Int0_Routine(void) interrupt 0         //红外解码
{
    if(IR_State==0)            //空闲状态    
    {
        Timer0_SetCounter(0);    
        Timer0_Run(1);        //启动用于解码    
        IR_State=1;            
    }
    else if(IR_State==1)        
    {
        IR_Time=Timer0_GetCounter();
        Timer0_SetCounter(0);    
        if(IR_Time>12442-500 && IR_Time<12442+500)       //start信号
        {
            IR_State=2;            
        }
        else if(IR_Time>10368-500 && IR_Time<10368+500)     //repeat信号
        {
            IR_RepeatFlag=1;     //收到数据
            Timer0_Run(0);         //定时器停止
            IR_State=0;            
        }
        else                     //解码错误情况
        {
            IR_State=1;        
        }
    }
    else if(IR_State==2)    
    {
        IR_Time=Timer0_GetCounter();
        Timer0_SetCounter(0);
        if(IR_Time>1032-500 && IR_Time<1032+500)
        {
            IR_Data[IR_pData/8]&=~(0x01<<(IR_pData%8));      //0~31拆分成四个字节,每8个位存一次
            IR_pData++;    
        }
        else if(IR_Time>2074-500 && IR_Time<2074+500)
        {
            IR_Data[IR_pData/8]|=(0x01<<(IR_pData%8));    
            IR_pData++;    
        }
        else    //解码错误情况                
        {
            IR_pData=0;            
            IR_State=1;        
        }
        if(IR_pData>=32)    //收完数据    
        {
            IR_pData=0;            
            if((IR_Data[0]==~IR_Data[1]) && (IR_Data[2]==~IR_Data[3]))
            {
                IR_Address=IR_Data[0];    //将数据转移到这两个变量上
                IR_Command=IR_Data[2];
                IR_DataFlag=1;           //表示接收到数据
            }
            Timer0_Run(0);        //定时器停止归零
            IR_State=0;        
        }
    }
}


```

【以下回答由 GPT 生成】

问题描述比较模糊,并且给出的代码片段并不完整,缺少部分函数的定义。但从代码中可以大致推测出问题所在,即无法在模式选择中加入停止功能。

为了解决这个问题,首先需要理清思路和逻辑,然后进行代码修改。下面是一种可能的修改方案:

#include <REGX52.H>
#include <INTRINS.H>
#include "UART.h"
#include "Delayms.h"
#include "IR.h"

#define left_pwm P1_0        //左电机pwm信号端
#define right_pwm P1_5        //右电机pwm信号端

#define right_go {P1_1=1;P1_2=0;}        //右电机正转
#define right_back {P1_1=0;P1_2=1;}        //右电机反转
#define right_stop {P1_1=0;P1_2=0;}        //右电机停转

#define left_go {P1_3=0;P1_4=1;}        //左电机正转
#define left_back {P1_3=1;P1_4=0;}        //左电机反转
#define left_stop {P1_3=0;P1_4=0;}        //左电机停转

unsigned int pwm_left=0;
unsigned int pwm_right=0;
unsigned int push_left=0;
unsigned int push_right;    //pwm递增,当小于push时,pwm信号端输出高电平(相当于push是pwm输出高电平的时间)
unsigned char Command;        //红外遥控控制码

void pwm_out_left()                    //左电机调速函数
{
    if(pwm_left<=push_left)             //此时左电机赋高电平转动(转速加快)
    {
        pwm_left=1;
        pwm_left++;
    }
    else        //此时左电机赋低电平停转(转速下降)
    {
        left_pwm=0;
        pwm_left++;
    }
    if(pwm_left>=20)        //pwm一周期20ms,超过重新开始
    {
        pwm_left=0;
    }
}                         

void pwm_out_right()                    //右电机调速函数
{
    if(pwm_right<=push_right)             //此时右电机赋高电平转动(转速加快)
    {
        pwm_right=1;
        pwm_right++;
    }
    else        //此时右电机赋低电平停转(转速下降)
    {
        right_pwm=0;
        pwm_right++;
    }
    if(pwm_right>=20)        //pwm一周期20ms,超过重新开始
    {
        pwm_right=0;
    }
}

void main()
{
    EA=1;            //全局中断使能
    delay_init();    //延时函数初始化
    uart_init();     //串口初始化
    IR_Init();       //红外遥控初始化

    while(1)
    {
        Command = IR_GetCommand();    //获取红外遥控控制码

        switch(Command)
        {
            case 0x08:                //红外遥控器按下stop键
                left_stop;
                right_stop;
                break;
            case 0x04:                //红外遥控器按下左转键
                left_back;
                right_go;
                break;
            case 0x02:                //红外遥控器按下前进键
                left_go;
                right_go;
                break;
            case 0x06:                //红外遥控器按下右转键
                left_go;
                right_back;
                break;
            case 0x00:                //红外遥控器没有按下任何键
                left_stop;
                right_stop;
                break;
            default:
                left_stop;
                right_stop;
                break;
        }

        pwm_out_left();     //调用左电机调速函数
        pwm_out_right();    //调用右电机调速函数
        delay_ms(1);        //延时1ms
    }
}

在上述修改的代码中,我加入了一个switch语句,根据红外遥控器的按键值来控制小车的运动。当按下stop键时,左右电机都停止转动;当按下左转键时,左电机反转,右电机正转;当按下前进键时,左右电机都正转;当按下右转键时,左电机正转,右电机反转;当没有按下任何键时,左右电机都停止转动。

在循环中,每次循环都会调用pwm_out_left()和pwm_out_right()函数来调整左右电机的转速,然后延时1ms。

此处给出的代码修改方案是根据问题的描述和现有代码片段进行的推测,可能与实际情况有所出入。如需进一步的准确解答,请提供更多的代码和相关信息。



【相关推荐】



如果你已经解决了该问题, 非常希望你能够分享一下解决方案, 写成博客, 将相关链接放在评论区, 以帮助更多的人 ^-^

引用 皆我百晓生 小程序回复内容作答:
在你的代码中,我注意到红外遥控器控制码的处理部分。你已经定义了四种不同的运动模式:前进、后退、左转和右转。你可以在收到相应的控制码后调用相应的函数来执行相应的动作。因此,你可以通过增加一个新的控制码来添加停止功能。

这里是一种可能的方式来实现停止功能:

首先,你可以定义一个新的控制码来表示停止命令,例如:IR_STOP。

然后,你可以在yaokong()函数中添加一个新的条件分支来处理停止命令,在该条件下调用stop()函数停止小车。

这是你可以尝试的代码修改:

void yaokong()
{
    Command=IR_GetCommand();

    if(IR_GetDataFlag())        //红外遥控小车函数,加后半句遥控连续输出
    {
        if(Command==IR_2)                //按2前进
        {
            car_move(1);
            Delayms(50);
        }
        else if(Command==IR_8)                //按8后退
        {
            car_move(2);
            Delayms(50);
        }
        else if(Command==IR_4)                //按4左转
        {
            car_move(3);
            Delayms(50);
        }
        else if(Command==IR_6)                //按6右转
        {
            car_move(4);
            Delayms(50);
        }
        else if(Command==IR_5)                //按5停止
        {
            stop();
            Delayms(50);
        }
    }    
}

通过以上修改,当收到红外遥控器发送的控制码为IR_5时,小车将会停止运动。注意要在每个if条件的最后添加Delayms(50)来确保接收到每个相关的控制码后有一定的延迟,以避免过快地处理多个控制码。你可以根据实际需要调整延迟时间。

希望这些信息能对你有帮助!祝你成功!