基于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调速技术,简化了编程复杂度,提高了效率,具有很强的实用价值和研究意义。
热门推荐
SSD固态硬盘详解:类型、选择与应用
40岁想学中医怎么开始
《阿含经》故事:弥醯的独修挫折
暗黑3国服汉化团队揭秘“奈非天”的翻译缘由
如何通过沟通增强团队的凝聚力
如何在金融市场中理解企业的停盘决策?这些决策背后的影响因素是什么?
组蛋白乳酸化修饰的调控蛋白:Writers、Erasers和Readers
越南美食全攻略:必吃小吃与特色料理推荐
止咳橘红口服液的功效与作用
《格林童话》导读
旅游重要还是攒钱重要?——在体验与安全之间寻找平衡
咳嗽过敏原怎么查
睡前还在刷手机?快放下!抓住养生黄金时间,做好这4件事→
违规停放和充电如何治理?——电动自行车安全隐患系列调查之三
全国肺部肿瘤最好的医院排名前十
孕线的定义是什么?孕线在技术分析中有哪些应用?
病理报告中肝炎、肝硬化、肝癌怎么看?一文带你读懂肝穿报告
Docker容器目录挂载详解:数据卷挂载与直接挂载对比及MySQL案例
人养花,花也会养人,6种健康花,推荐给大家!
家居设计:现代简约风格的实用与美感
电动车楼道充电可以报警吗?处理流程全解析
虚惊一场?小行星撞地球概率调整为接近为零,专家:概率或还有波动
探索IM即时通讯在社交媒体中的应用
五输穴子母补泻法临床发挥
甜品店市场分析怎么开始?
电动车充电法规要求全面了解:安全、合规、便捷
吃止痛药竟吃成胃出血?这类人群要注意
per的用法有哪些 是什么意思
预防脑梗要检查什么
透过香调与场合找到最适合自己的香水秘诀