基于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调速技术,简化了编程复杂度,提高了效率,具有很强的实用价值和研究意义。
热门推荐
治疗性进食训练:原理、方法与推广策略
LeetCode 112 & 113:路径总和问题详解与DFS算法应用
装修工的职业病有哪些?装修工人职业病预防
实惠之选:高性价比产品推荐
读博到底值不值得?从职场发展到待遇优劣的全面分析
车辆停放环境对雨刮更换频率的影响及房车设计流行元素
方腊起义的规模有多大?历史上的方腊最终结局如何?
我国近五年就业结构大变化:服务业蓝领数量首次超过制造业
1岁多孩子睡觉爱哭闹,怎么提高宝宝睡眠质量
华网童趣:网名里的童年记忆
今天我寒夜里看雪飘过什么歌?解析这句歌词出自哪首歌
济宁味道:六种地道美食,品味不一样的孔孟之乡
济宁周边游玩十处景点,不是运河文化就是儒家文化,最值得的看
基于Yolov5的闯红灯及红绿灯检测系统
如何分析全员劳动生产率的变化趋势?
管理项目知识怎么写的好
分不清路由器、交换机、光猫的概念,一文带你迅速搞懂!!!
分不清路由器、交换机、光猫的概念,一文带你迅速搞懂!
中国古代弓箭详解:从弓到箭的精妙构造
劳动生产率计算方法及应用
消除内脏脂肪最佳策略:饮食、运动、睡眠与压力管理全解析
经常生气会得癌?病都是被“气”出来的,看完别再生气了
劳动生产率是什么意思
注册不同类型公司需要满足哪些条件
胸肌锻炼的有效且快速的方法
全面解析:人工智能在医疗领域的应用与挑战
两线制直流电源电压显示表设计与实现
《DOTA2》征战号角响彻全场——上半年顶级赛事一览
中国最值得打卡的6条史诗级徒步古道,又美又虐,去过一半就是旅游达人
从Bjørn到Astrid:解码挪威的命名规则