问小白 wenxiaobai
资讯
历史
科技
环境与自然
成长
游戏
财经
文学与艺术
美食
健康
家居
文化
情感
汽车
三农
军事
旅行
运动
教育
生活
星座命理

基于STM32的智能小车红外循迹功能实现

创作时间:
作者:
@小白创作中心

基于STM32的智能小车红外循迹功能实现

引用
CSDN
1.
https://blog.csdn.net/Dustinthewine/article/details/124831614

本文将详细介绍如何使用STM32F103C8T6最小系统板实现智能小车的红外循迹功能。通过结合L298N双路电机驱动和红外循迹模块,我们将展示如何让小车沿着预设的轨迹行驶。

一、硬件选择与连接

在硬件部分,与前几节介绍的51智能小车大致相同,主要区别在于将51最小系统板替换为STM32最小系统板。其他驱动、红外循迹模块保持不变。具体硬件配置如下:

1. STM32F103C8T6最小系统板

该开发板的主要资源包括:

  • STM32F103C8主芯片
  • 贴片8M晶振(通过芯片内部PLL最高达72M)
  • 3.3V稳压芯片,最大提供800mA电流
  • 一路miniUSB接口,支持系统供电和USB通讯
  • 复位按键
  • 标准SWD口,支持JLink、STLink等调试工具
  • BOOT选择端口
  • IO扩展排针 20pin x 2
  • 电源指示灯和功能指示灯
  • 预留串口接口,方便与5V开发板连接
  • 高性能爱普生32768Hz晶振
  • 20K RAM,64K ROM ,TQFP48封装

2. L298N双路电机驱动

L298N是一款高性能的电机驱动芯片,支持直流电机和步进电机的驱动。其主要特点包括:

  • 工作电压范围:6V到46V
  • 最大电流:2安培
  • 具有过热保护和反馈检测功能
  • 支持正反转控制
  • 操作简单、稳定性好

3. 红外循迹模块

红外循迹模块采用TCRT5000传感器,其工作原理如下:

  • 红外发射二极管持续发射红外线
  • 当红外线被反射回来且强度足够大时,红外接收管饱和,模块输出低电平
  • 否则,模块输出高电平

接口说明:

  • VCC:3.3V-5V电源输入
  • GND:接地
  • OUT:数字量输出接口(0和1)

二、环境配置

1. Device

选择STM32F103C8T6最小系统板,因此Device应选择STM32F103C8。

2. Output

需要创建HEX可执行文件。

3. C/C++

需要定义宏和包含文件路径。

4. Debug

若使用ST-link或J-link等下载器,需要事先安装相应的驱动和配置相关环境。

三、项目管理与代码实现

1. 项目结构

项目结构主要包括以下几个部分:

  • xunji.c:电机控制和循迹逻辑实现
  • xunji.h:函数声明和引脚定义
  • main.c:主程序入口

2. 工程管理

在工程文件中添加对应的.c文件。

3. 具体文件

以下是几个关键文件的详细说明:

xunji.c

#include "xunji.h"
#include "stm32f10x.h"

void motor_gpio()
{
    GPIO_InitTypeDef  GPIO_InitStructure;
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_10|GPIO_Pin_11;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; // 推挽输出
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOB, &GPIO_InitStructure);
}

void xunji_gpio()
{
    GPIO_InitTypeDef  GPIO_InitStructure;
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3|GPIO_Pin_7;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; // 上拉输入
    GPIO_Init(GPIOA, &GPIO_InitStructure);
}

void pwm()
{
    GPIO_InitTypeDef GPIO_InitStructure;
    TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
    TIM_OCInitTypeDef  TIM_OCInitStructure;
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6|GPIO_Pin_8;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; // 复用输出
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOB, &GPIO_InitStructure);

    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE); // 使能定时器4时钟
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); // 使能GPIOB时钟

    TIM_TimeBaseStructure.TIM_Period = 99; // 设置自动重装载寄存器周期
    TIM_TimeBaseStructure.TIM_Prescaler = 71; // 设置预分频值
    TIM_TimeBaseStructure.TIM_ClockDivision = 0; // 设置时钟分割
    TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; // 向上计数模式
    TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStructure);

    TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; // 选择PWM模式1
    TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; // 比较输出使能
    TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; // 输出极性高
    TIM_OCInitStructure.TIM_Pulse = 0;

    TIM_OC1Init(TIM4, &TIM_OCInitStructure);
    TIM_OC3Init(TIM4, &TIM_OCInitStructure);

    TIM_OC1PreloadConfig(TIM4, TIM_OCPreload_Enable); // 使能CCR1预装载寄存器
    TIM_OC3PreloadConfig(TIM4, TIM_OCPreload_Enable); // 使能CCR3预装载寄存器

    TIM_Cmd(TIM4, ENABLE); // 使能TIM4
}

void run()
{
    TIM_SetCompare1(TIM4, 30);
    TIM_SetCompare3(TIM4, 30);
    IN1 = 1;
    IN2 = 0;
    IN3 = 1;
    IN4 = 0;
}

void back()
{
    TIM_SetCompare1(TIM4, 70);
    TIM_SetCompare3(TIM4, 70);
    IN1 = 0;
    IN2 = 1;
    IN3 = 0;
    IN4 = 1;
}

void right()
{
    TIM_SetCompare1(TIM4, 0);
    TIM_SetCompare3(TIM4, 30);
    IN1 = 1;
    IN2 = 0;
    IN3 = 0;
    IN4 = 0;
}

void left()
{
    TIM_SetCompare1(TIM4, 30);
    TIM_SetCompare3(TIM4, 0);
    IN1 = 0;
    IN2 = 0;
    IN3 = 1;
    IN4 = 0;
}

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

xunji.h

#ifndef __xunji_H
#define __xunji_H
#include "sys.h"
#define IN1         PBout(0)
#define IN2         PBout(1)
#define IN3         PBout(10)
#define IN4         PBout(11)
#define LEFT_ONE    PAin(3)
#define LEFT_TWO    PAin(7)

void run(void);
void left(void);
void right(void);
void back(void);
void stop(void);
void motor_gpio(void);
void xunji_gpio(void);
void pwm(void);
#endif

main.c

#include "stm32f10x.h"
#include "xunji.h"
#include "delay.h"

void Init()
{
    TIM_SetCompare1(TIM4, 25);
    TIM_SetCompare3(TIM4, 25);
    IN1 = 1;
    IN2 = 0;
    IN3 = 1;
    IN4 = 0;
}

int main(void)
{
    motor_gpio();
    xunji_gpio();
    pwm();
    delay_init();
    Init();
    while (1)
    {
        if (LEFT_ONE == 0 && LEFT_TWO == 0)
        {
            run();
        }
        else if (LEFT_ONE == 0 && LEFT_TWO == 1)
        {
            right();
        }
        else if (LEFT_ONE == 1 && LEFT_TWO == 0)
        {
            left();
        }
        else if (LEFT_ONE == 1 && LEFT_TWO == 1)
        {
            run();
        }
        else
        {
            stop();
        }
    }
}

总结

本项目以STM32F103C8T6最小系统板为核心,通过红外循迹模块和L298N驱动模块的结合,实现了智能小车的红外循迹功能。整个设计过程充分利用了红外循迹原理与PWM调速技术,简化了编程复杂度,提高了效率,具有很强的实用价值和研究意义。

© 2023 北京元石科技有限公司 ◎ 京公网安备 11010802042949号