【 STM32实例 】 智能小车的红外循迹

news/2024/12/3 1:55:17/

文章目录

  • 前言
  • 一、硬件选择与连接
    • 1. STM32F103C8T6最小系统板
    • 2. L298N双路电机驱动
    • 3. 红外循迹模块
  • 二、环境配置
    • 1. Device
    • 2. Output
    • 3. C/C++
    • 4. Debug
  • 三、项目管理与代码实现
    • 1. 项目结构
    • 2. 工程管理
    • 3. 具体文件
      • xunji.c
      • xunji.h
      • main.c
  • 总结
  • 项目源码


前言

这篇文章我主要讲的是让基于stm32单片机下的智能小车实现红外循迹功能,智能小车的项目非常多,比如说循迹避障、蓝牙遥控、视觉控制等等,我将会一步一步带大家走进stm32单片机的项目当中。


项目源码置文章底部,可自提

一、硬件选择与连接

在硬件部分,与前几节我所介绍的51智能小车大致一样,所不同的是把51最小系统板换成了stm32最小系统板,其他驱动、红外循迹模块都一样,具体可前往【51单片机实例】智能小车(一)了解详情。

下面我还是会对相关重要模块进行简单介绍:

1. STM32F103C8T6最小系统板

在这里插入图片描述
在这里插入图片描述
配套资源:

  1. STM32F103C8主芯片一片
  2. 贴片8M晶振(通过芯片内部PLL最高达72M)ST官方标准参数
  3. 3.3V稳压芯片,最大提供800mA电流
  4. 一路miniUSB接口,可以给系统版供电,预留USB通讯功能
  5. 复位按键
  6. 标准SWD口一个,支持JLink,STLink,JLINK OB
  7. BOOT选择端口
  8. IO扩展排针 20pin x 2
  9. 电源指示灯1个
  10. 功能指示灯一个,用于验证IO口基本功能
  11. 预留串口接口,方便和5V开发板连接,用串口即可程序
  12. 高性能爱普生32768Hz晶振,价格是直插晶振的10倍价格,易起振
  13. 20K RAM,64K ROM ,TQFP48封装

2. L298N双路电机驱动

L298N,是一款接受高电压的电机驱动器,直流电机和步进电机都可以驱动。一片驱动芯片可同时控制两个直流减速电机做不同动作,在6V到46V的电压范围内,提供2安培的电流,并且具有过热自断和反馈检测功能,可对电机进行直接控制,通过主控芯片的I/O输入对其控制电平进行设定,就可为电机进行正转反转驱动,操作简单、稳定性好,可以满足直流电机的大电流驱动条件。
在这里插入图片描述

3. 红外循迹模块

在这里插入图片描述

TCRT5000传感器的红外发射二极管不断发射红外线,当发射出的红外线没有被反射回来或被反射回来但强度不够大时,红外接收管一直处于关断状态,此时模块的输出端为高电平,指示二极管一直处于熄灭状态;被检测物体出现在检测范围内时,红外线被反射回来且强度足够大,红外接收管饱和,此时模块的输出端为低电平,指示二极管被点亮。

接口说明:
(1) VCC 外接3.3V-5V电压(可以直接与5v单片机和3.3v单片机相连)
(2) GND 外接GND
(3) OUT 小板数字量输出接口(0和1)

二、环境配置

1. Device

我们选用的是STM32F103C8T6最小系统板,所以Device应选择STM32F103C8
在这里插入图片描述

2. Output

Output中应创建HEX可执行文件
在这里插入图片描述

3. C/C++

C/C++中应定义宏和包含文件路径
在这里插入图片描述
在这里插入图片描述

4. Debug

若选用 ST-link 或 J-link 还是其他下载器or串口,都需要事先安装相应的驱动和配置相关环境,这里我以ST-link为例配置相关环境
在这里插入图片描述
在这里插入图片描述

三、项目管理与代码实现

1. 项目结构

在这里插入图片描述

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;     //设置用来作为TIMx时钟频率除数的预分频值TIM_TimeBaseStructure.TIM_ClockDivision = 0;   //设置时钟分割:TDTS = Tck_timTIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;   //TIM向上计数模式 TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStructure);    TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;  //选择定时器模式:TIM脉冲宽度调制模式1TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;   //比较输出使能TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;    //输出极性:TIM输出比较极性高TIM_OCInitStructure.TIM_Pulse=0;TIM_OC1Init(TIM4, &TIM_OCInitStructure);  TIM_OC3Init(TIM4, &TIM_OCInitStructure);  TIM_OC1PreloadConfig(TIM4, TIM_OCPreload_Enable);   //使能TIM4在CCR1上的预装载寄存器TIM_OC3PreloadConfig(TIM4, TIM_OCPreload_Enable);   //使能TIM4在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();}elsestop();}
}

总结

本节是以STM32F103C8T6最小系统为CPU,通过一些外围电路和软件编程实现小车红外循迹的功能。整个设计过程中最大的特点是利用简单的理论原理将红外循迹模块、L298N驱动模块、51单片机这三个模块有效的结合起来,利用红外循迹原理与pwm调节占空比的简单结合实现对小车红外循迹奠定编程理论基础,提高了效率,降低了编程的复杂度,具有很强的研究的意义,智能化的发展促使了智能小车往功能更加强大的方向发展。

项目源码

链接:https://pan.baidu.com/s/1_-j6TJepvMkMjUdHvDWS6w 
提取码:s0hj

一键三连啦😊
技术交流可加下方wx联系👇👇👇


http://www.ppmy.cn/news/188846.html

相关文章

软件测试新人害怕不过试用期,教你几招使你安稳度过!!!

对于很多刚步入职场的新人来说,害怕自己试用期过不了,被辞退。别的行业我可能不知道该如何帮大家应对,但在测试行业我希望还是能给大家带俩一点帮助,希望大家能安稳度过试用期,并且成功入行。 保持初心,安稳…

Mac机修改文件的句柄限制

### mac下的句柄数限制 某些mac版本,允许进程打开的最大文件数只有256 (可以用命令查看: launchctl limit maxfiles),不能满足加速场景的需求,可以通过下面的方法来修改 1. 创建启动加载文件(sudo vi /Library/LaunchDaemons/limit.maxfiles…

Python Struct 库之 pack 和 unpack 详解

1. 官网解析 首先是官网对于 pack 、 unpack 、calcsize以及Format Strings的描述 1.1 pack、unpack、calcsize struct.pack返回一个bytes对象,其中包含根据格式字符串format打包的值v1, v2,…。参数必须与格式所要求的值完全匹配。 struct.unpack根据…

MDM配置

VScode配置服务器 网上找个教程下载了一下 下载数据集 一开始按照MDM的paper配置了环境,之后说ML3D的数据集要安装,在mdm环境下继续安装humanML3D数据集 HumanML3D数据集安装 对着guo的教程跑,比较慢,跑完需要两天左右

MDD(模型驱动开发)

前言导读 当下企业软件应用开发面临着需求复杂多变、新的需求和系统不断增长,软件系统变得越来越复杂,普通的软件开发方式难以快速满足用户需求。为了解决这些问题,就出现了很多新的方法,其中最突出的一个就是模型驱动开发 MDD &a…

微软MDT 安装与配置(二)

前文我们完成MDT的安装与部署,但如果我们需要批量安装带有规定软件和驱动的系统,之前所部署的纯净系统就不能满足我们的需求了。接下来我们就需要用到镜像捕获功能,完成我们的定制需求。 目的: 批量部署带有规定软件和驱动的系统…

俩句话理解VS的MT/MD和MTD/MDD。

VC项目属性→配置属性→C/C→代码生成→运行时库 可以采用的方式有:多线程(/MT)、多线程调试(/MTd)、多线程DLL(/MD)、多线程调试。 DLL(/MDd)、单线程(/ML)、单线程调试(/MLd)。目前Win7、Win10等,选择MD问题不大,但是XP等一些比较老的系统…

MT、MTd、MD、MDd

在开发window程序是经常会遇到编译好好的程序拿到另一台机器上面无法运行的情况,这一般是由于另一台机器上面没有安装响应的运行时库导致的,那么这个与编译选项MT、MTd、MD、MDd有什么关系呢?这是msdn上面的解释: MT:…