两种方式实现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单片机后即可

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

相关推荐
salipopl1 天前
基于STM32平台的多旋翼无人机系统设计与实现
stm32·嵌入式硬件·无人机
智者知已应修善业1 天前
【51单片机模拟生日蜡烛】2023-10-10
c++·经验分享·笔记·算法·51单片机
智者知已应修善业1 天前
【51单片机如何让LED灯从一亮到八,再从八亮到一】2023-10-13
c++·经验分享·笔记·算法·51单片机
iCxhust1 天前
8086/8088单板机VSCode集成自动下载功能(完善串口接收显示版)
ide·vscode·单片机·编辑器·微机原理·8088单板机·8086单板机
振南的单片机世界1 天前
从数码管到点阵屏:动态扫描加595,3个IO驱动256个LED
stm32·单片机·嵌入式硬件
listhi5201 天前
STC8 16通道模拟采集 + 4路串口 + 8路PWM 程序
stm32·单片机·嵌入式硬件
星夜夏空991 天前
STM32单片机学习(4)——嵌入式概述
stm32·单片机·学习
Deitymoon1 天前
STM32——OLED显示字符串
单片机·嵌入式硬件
Graceful_scenery1 天前
龙芯2k0300 - 走马观碑组按键驱动移植
单片机·嵌入式硬件
d111111111d1 天前
MQTT+STM32+ESP8266网络程序分层+韦老师
笔记·stm32·单片机·嵌入式硬件·学习·php