两种方式实现51单片机五路循迹,经测试可实现

模块:L298N,五路寻迹模块

不使用L298N上的EAEB引脚

复制代码
#include <reg52.h>

// 电机控制引脚(P2口)
sbit IN1 = P2^3;
sbit IN2 = P2^2;
sbit IN3 = P2^1;
sbit IN4 = P2^0;

// 红外循迹传感器引脚(P1口)
sbit S1 = P1^0;
sbit S2 = P1^1;
sbit S3 = P1^2;
sbit S4 = P1^3;
sbit S5 = P1^4;

// 延时函数
void delay_ms(unsigned int t)
{
    unsigned int i, j;
    for(i = t; i > 0; i--)
        for(j = 50; j > 0; j--);
}

// 前进 ------ 大幅降速(通电极短,断电很长)
void forward(void)
{
    IN1 = 1; IN2 = 0;
    IN3 = 1; IN4 = 0;
    delay_ms(4);   // 通电时间更短
    IN1 = 0; IN2 = 0;
    IN3 = 0; IN4 = 0;
    delay_ms(20);  // 断电时间更长 → 速度极慢
}

// 轻微左转
void left_slow(void)
{
    IN1 = 0; IN2 = 0;
    IN3 = 1; IN4 = 0;
    delay_ms(6);
}

// 轻微右转
void right_slow(void)
{
    IN1 = 1; IN2 = 0;
    IN3 = 0; IN4 = 0;
    delay_ms(6);
}

// 原地左转
void left_spot(void)
{
    IN1 = 0; IN2 = 1;
    IN3 = 1; IN4 = 0;
    delay_ms(2);
}

// 原地右转
void right_spot(void)
{
    IN1 = 1; IN2 = 0;
    IN3 = 0; IN4 = 1;
    delay_ms(2);
}

// 停车
void stop(void)
{
    IN1 = 0; IN2 = 0;
    IN3 = 0; IN4 = 0;
}

void main(void)
{
    stop();
    delay_ms(50);
    while(1)
    {
        bit s1 = S1;
        bit s2 = S2;
        bit s3 = S3;
        bit s4 = S4;
        bit s5 = S5;

        if(s3 == 0)
        {
            forward();
        }
        else if(s2 == 0 && s3 == 1)
        {
            left_slow();
        }
        else if(s1 == 0 && s2 == 1 && s3 == 1)
        {
            left_spot();
        }
        else if(s4 == 0 && s3 == 1)
        {
            right_slow();
        }
        else if(s5 == 0 && s4 == 1 && s3 == 1)
        {
            right_spot();
        }
        else
        {
            stop();
            delay_ms(20);
            left_spot();
            right_spot();
        }
    }
}

使用EAEB引脚

复制代码
#include <REG52.H>

/* ================= ???? IO ?? ================= */
sbit IN1 = P2^0;   // ?????1
sbit IN2 = P2^1;   // ?????2
sbit IN3 = P2^2;   // ?????1
sbit IN4 = P2^3;   // ?????2
sbit ENA = P2^4;   // ???PWM??
sbit ENB = P2^5;   // ???PWM??

/* ================= ????? IO ?? ================= */
sbit Sensor_Left1   = P1^4;
sbit Sensor_Left2   = P1^3;
sbit Sensor_Mid     = P1^2;
sbit Sensor_Right1  = P1^1;
sbit Sensor_Right2  = P1^0;

/* ================= ???? ================= */
unsigned char LeftPWM  = 0;
unsigned char RightPWM = 0;
unsigned char pwm_count = 0;
signed char last_dir = 0;

/* ================= ???? ================= */
void Timer0_Init(void);
void DelayMs(unsigned int ms);
void Sensor_Read(unsigned char *sensor_data);
void Motor_SetForwardDir(void);
void Motor_SetBackwardDir(void);
void Motor_Stop(void);
void Set_Speed(unsigned char left, unsigned char right);
void Go_Straight(void);
void Turn_Left_Small(void);
void Turn_Left_Mid(void);
void Turn_Left_Big(void);
void Turn_Right_Small(void);
void Turn_Right_Mid(void);
void Turn_Right_Big(void);
void Track_Follow(unsigned char *sensor_data);

/* ================= ?????(????????) ================= */
void DelayMs(unsigned int ms)
{
    unsigned int i, j;
    for(i = 0; i < ms; i++)
        for(j = 0; j < 120; j++);
}

/* ================= ???0???(PWM) ================= */
void Timer0_Init(void)
{
    TMOD &= 0xF0;
    TMOD |= 0x01;
    TH0 = 0xFF;
    TL0 = 0x9C;
    ET0 = 1;
    EA  = 1;
    TR0 = 1;
}

/* ================= ???0??(??PWM) ================= */
void Timer0_ISR(void) interrupt 1
{
    TH0 = 0xFF;
    TL0 = 0x9C;
    pwm_count++;
    if(pwm_count >= 100)
        pwm_count = 0;

    if(pwm_count < LeftPWM)
        ENA = 1;
    else
        ENA = 0;

    if(pwm_count < RightPWM)
        ENB = 1;
    else
        ENB = 0;
}

/* ================= ?????? ================= */
void Motor_SetForwardDir(void)
{
    IN1 = 1; IN2 = 0;
    IN3 = 1; IN4 = 0;
}

void Motor_SetBackwardDir(void)
{
    IN1 = 0; IN2 = 1;
    IN3 = 0; IN4 = 1;
}

/* ================= ??PWM??? ================= */
void Set_Speed(unsigned char left, unsigned char right)
{
    if(left > 100)  left = 100;
    if(right > 100) right = 100;
    LeftPWM  = left;
    RightPWM = right;
}

/* ================= ???? ================= */
void Motor_Stop(void)
{
    LeftPWM = 0; RightPWM = 0;
    ENA = 0; ENB = 0;
    IN1 = 0; IN2 = 0; IN3 = 0; IN4 = 0;
}

/* ================= ??????? ================= */
void Sensor_Read(unsigned char *sensor_data)
{
    sensor_data[0] = Sensor_Right2;
    sensor_data[1] = Sensor_Right1;
    sensor_data[2] = Sensor_Mid;
    sensor_data[3] = Sensor_Left2;
    sensor_data[4] = Sensor_Left1;
}

/* ================= ?????? ================= */
void Go_Straight(void)
{
    Motor_SetForwardDir();
    Set_Speed(15, 15);
    last_dir = 0;
}

void Turn_Left_Small(void)
{
    Motor_SetForwardDir();
    Set_Speed(10, 20);
    last_dir = -1;
}

void Turn_Left_Mid(void)
{
    Motor_SetForwardDir();
    Set_Speed(5, 25);
    last_dir = -1;
}

void Turn_Left_Big(void)
{
    // ????,????(????)
    IN1 = 0; IN2 = 1;
    IN3 = 1; IN4 = 0;
    Set_Speed(20, 20);
    last_dir = -1;
}

void Turn_Right_Small(void)
{
    Motor_SetForwardDir();
    Set_Speed(20, 10);
    last_dir = 1;
}

void Turn_Right_Mid(void)
{
    Motor_SetForwardDir();
    Set_Speed(25, 5);
    last_dir = 1;
}

void Turn_Right_Big(void)
{
    // ????,????(????)
    IN1 = 1; IN2 = 0;
    IN3 = 0; IN4 = 1;
    Set_Speed(20, 20);
    last_dir = 1;
}

/* ================= ?????? ================= */
void Track_Follow(unsigned char *sensor_data)
{
    unsigned char s1, s2, s3, s4, s5;
    s1 = sensor_data[0];
    s2 = sensor_data[1];
    s3 = sensor_data[2];
    s4 = sensor_data[3];
    s5 = sensor_data[4];

    // ???? -> ??
    if(s1==0 && s2==0 && s3==0 && s4==0 && s5==0)
    {
        Go_Straight();
        return;
    }

    // ??(????)-> ?????????
    if(s1==1 && s2==1 && s3==1 && s4==1 && s5==1)
    {
        if(last_dir < 0)
        {
            Turn_Left_Big();
            Set_Speed(10, 10);
        }
        else if(last_dir > 0)
        {
            Turn_Right_Big();
            Set_Speed(10, 10);
        }
        else
        {
            Go_Straight();
            Set_Speed(10, 10);
        }
        return;
    }

    // ?????????
    if(s3 == 0)
    {
        if(s2==0 && s4==0)      // ???
        {
            Go_Straight();
            return;
        }
        if(s2==0 && s4==1)      // ??
        {
            Turn_Left_Small();
            return;
        }
        if(s2==1 && s4==0)      // ??
        {
            Turn_Right_Small();
            return;
        }
        Go_Straight();
        return;
    }

    // ??????,???????????
    if(s1==0 && s2==0) { Turn_Left_Big(); return; }
    if(s2==0)          { Turn_Left_Mid(); return; }
    if(s4==0 && s5==0) { Turn_Right_Big(); return; }
    if(s4==0)          { Turn_Right_Mid(); return; }
    if(s1==0)          { Turn_Left_Big(); return; }
    if(s5==0)          { Turn_Right_Big(); return; }

    Go_Straight();
}

/* ================= ??? ================= */
void main(void)
{
    unsigned char sensor[5];
    Motor_Stop();
    DelayMs(300);           // ??????,??
    Timer0_Init();

    while(1)
    {
        Sensor_Read(sensor);
        Track_Follow(sensor);
        // ??????,?????????
    }
}

上述代码经测试后都能实现循迹,不用封装,直接在主函数中编译再烧录进51单片机后即可

无法循迹的可能原因:左轮与右轮动力不一,会使小车左转时冲出循迹线,进而无法实现循迹(折磨了我一个星期)

相关推荐
0南城逆流02 小时前
【STM32】知识点介绍九:看门狗功能
stm32·单片机·嵌入式硬件
VBsemi-专注于MOSFET研发定制2 小时前
面向高端汽车暖风系统控制器的功率MOSFET选型策略与器件适配手册
单片机·嵌入式硬件
Byron Loong2 小时前
【常识】通俗易懂的讲CPU,GPU,MCU,FPGA,DSP的区别和特点
单片机·嵌入式硬件·fpga开发
zmj3203242 小时前
工业通信--CRC校验分类及实现细节
人工智能·单片机·数据挖掘·can
潜创微科技2 小时前
CH398:高集成度 USB 3.0 转千兆以太网芯片方案
嵌入式硬件·音视频
charlie11451419113 小时前
嵌入式C++工程实践第16篇:第四次重构 —— LED模板,从通用GPIO到专用抽象
c语言·开发语言·c++·驱动开发·嵌入式硬件·重构
深圳市九鼎创展科技15 小时前
MT8883 vs RK3588 开发板全面对比:选型与场景落地指南
大数据·linux·人工智能·嵌入式硬件·ubuntu
三品吉他手会点灯17 小时前
STM32 VSCode 开发-C/C++的环境配置中,找不到C/C++: Edit Configurations选项
c语言·c++·vscode·stm32·单片机·嵌入式硬件·编辑器
yu859395819 小时前
STM32 智能红外循迹小车(含码盘测速 + 避障)
stm32·单片机·嵌入式硬件