stm32循迹小车详细制作过程(附加完全版代码)

2023-11-17

stm32循迹小车详细制作过程

一.材料准备

1、主控板
Stm32f103c8t6 (推荐,便宜够用)

在这里插入图片描述

2、下载器
USB转TTL串口模块
在这里插入图片描述

3、电源
12v锂电池组、配套充电器(推荐下图这种,方便,好接线,12v!12v! 12v!)
在这里插入图片描述

4、电机驱动模块
L298n电机驱动模块(尽量多备一两个,容易烧)
在这里插入图片描述

5、循迹模块
TCRT5000循迹模块(多买几个,四个吧)
在这里插入图片描述

6、杜邦线
公对公、母对母、公对母(都买上,不贵,消耗品)

在这里插入图片描述

7、开关
避免出现意外还是备一个吧
在这里插入图片描述

8、小车底座
有四个轮的,三个轮的(其中一个是万向轮)。
三个轮:好接线,可以转直角弯。
四个轮:稳定,也可以转直角弯,但相对来说比三个轮难转。
在这里插入图片描述

9、蜂鸣器模块
在这里插入图片描述

二.各器件详细解释

1.L298N介绍
如图,中间的三个接线端从左到右分别为VCC、GND、+5,其中VCC为12V供电,GND为供电地,+5为5V供电;左右两边的接线端分别为输出A和输出B;排针部分引脚分别为ENA、IN1、IN2、IN3、IN4、ENB,其中IN1~4为逻辑输入,ENA和ENB为PWM使能,已经默认被接到5V,若要使用PWM调速
可取下跳帽使用。
在这里插入图片描述
2.stm32c8t6
(1) STM32F103C8T6是一款由意法半导体公司(ST)推出的基于Cortex-M3内核的32位微控制器,硬件采用LQFP48封装,属于ST公司微控制器中的STM32系列。
在这里插入图片描述
(2)程序下载方法
stm32f103c8t6的TX引脚为PA9 RX引脚为PA10。

串口下载的引脚

在这里插入图片描述

stm32f103c8t6的引脚

在这里插入图片描述

接法的说明

STM32 cp2102
3.3V 3.3V
PA9(TXD引脚) RXD引脚
PA9(RXD引脚) TXD引脚
GND GND

下载程序:

打开flymcu,设置如下
下载前将 boot0 = 1

在这里插入图片描述

然后就可以下载成功了
注意:下载程序完毕后,把boot0跳线帽复位即boot0 = 0
3.循迹模块
循迹原理非常简单,模块上配有一个输出指示灯,部分模块还有电源指示灯,我们主要关注输出指示灯。红外发射器一直发射红外线,红外线经发射后被接收,此时输出低电平,输出指示灯点亮。黑色是不反射红外线的,也就是说循迹模块遇到黑线,模块输出高电平,输出指示灯熄灭。当然除了遇到黑线熄灭,当距离太远红外线反射后检测不到,此时指示灯也会熄灭。那么如果要循迹,模块离地面要近,在没有遇到黑线时确保指示灯长亮,一旦指示灯熄灭就说明遇到黑线了。
在这里插入图片描述
如上图中4个管脚的,分别是VCC、GND、A0、D0。A0是模拟信号输出,D0是TTL电平输出。使用TCRT5000主要就是用来循迹,只需要连接VCC、GND、D0就可以了。

三.代码详细介绍

首先是主函数(main.c):


#include "stm32f10x.h"
#include "motor.h"
#include "delay.h"

 



 void Delay(u32 count)
 {
   u32 i=0;
   for(;i<count;i++);
 }
 int main(void)
 {	

 motor_gpio();
 xunji_gpio();
 pwm();             
	 delay_init();
	 if(GO==  0) //这里也是一个循迹,用来作无接触启动,若不需要可以删除
	 {
  while(1)
	{

//LEFT_ONE LEFT_TWO RIGHT_ONE RIGHT_TWO代表的是四个循迹
      if(LEFT_ONE==0&&LEFT_TWO==0&&RIGHT_ONE==0&&RIGHT_TWO==0)
			{
					 run();
			}
					else if(LEFT_ONE==0&&LEFT_TWO==1&&RIGHT_ONE==0&&RIGHT_TWO==0)
			{
			
			  left();
			}
						else if(LEFT_ONE==0&&LEFT_TWO==0&&RIGHT_ONE==0&&RIGHT_TWO==1)
			{
			
			 right();
			}
			else if(LEFT_ONE==1&&LEFT_TWO==1&&RIGHT_ONE==1&&RIGHT_TWO==1)
			{
			 
			  turn();
				delay_ms(200);
				stop();
				delay_ms(5000);	
			}

				
				
				
			
			
	}
}
 }

其次是pwm,循迹,及电机的初始化:
.h 文件


#ifndef __motor_H
#define __motor_H 			   
#include "sys.h"  
//可以按照此处接线 IN1~4对应L298n上的IN1~4
#define      IN1         PAout(6)
#define      IN2         PAout(5)
#define      IN3         PAout(4)
#define      IN4         PAout(3)

//可以按照此处接线 LEFT_ONE—— RIGHT_TWO 以及go 对应循迹模块上的D0
#define      LEFT_ONE      PBin(4)  
#define      LEFT_TWO      PBin(6) 
#define      RIGHT_ONE      PBin(7) 
#define      RIGHT_TWO      PBin(8) 
#define      GO        PBin(5) 
void run(void);
void left(void);
void right(void);
void back(void);
void qleft(void);
void qight(void);
void stop(void);
void turn(void);
void motor_gpio(void);
void xunji_gpio(void);
void pwm(void);
#endif



.c文件


#include "motor.h"  
#include "stm32f10x.h"

void motor_gpio()
{

  GPIO_InitTypeDef  GPIO_InitStructure;
	 
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);	  
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_4|GPIO_Pin_3;		
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; 	 
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;	 
  GPIO_Init(GPIOA, &GPIO_InitStructure);			     

}

void xunji_gpio()
{
//这里是对五个循迹进行的引脚初始化
  GPIO_InitTypeDef  GPIO_InitStructure;
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);	  
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4|GPIO_Pin_6|GPIO_Pin_7|GPIO_Pin_8|GPIO_Pin_5;		
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; 
  GPIO_Init(GPIOB, &GPIO_InitStructure);		

}
void pwm()
{
//初始化pwm,PA1,PA2分别接L298N的EN1,EN2
	GPIO_InitTypeDef GPIO_InitStructure;
	TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
	TIM_OCInitTypeDef  TIM_OCInitStructure;
	
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);	
 	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA  | RCC_APB2Periph_AFIO, ENABLE); 
	  
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1|GPIO_Pin_2;		
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; 
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_Init(GPIOA, &GPIO_InitStructure);	

	
	TIM_TimeBaseStructure.TIM_Period = 899; 
	TIM_TimeBaseStructure.TIM_Prescaler =0; 
	TIM_TimeBaseStructure.TIM_ClockDivision = 0; 
	TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; 
	TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure); 
	
	TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2;
 	TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; 
	TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; 

	
	TIM_OC2Init(TIM2, &TIM_OCInitStructure);  
	TIM_OC3Init(TIM2, &TIM_OCInitStructure);  
	

	TIM_OC2PreloadConfig(TIM2, TIM_OCPreload_Enable); 
	TIM_OC3PreloadConfig(TIM2, TIM_OCPreload_Enable); 

	
	TIM_Cmd(TIM2, ENABLE);
}
//TIM_SetCompare2 TIM_SetCompare3的数值分别对应左右两边的速度,可自行调整
void run()
{

		TIM_SetCompare2(TIM2,380);
   	TIM_SetCompare3(TIM2,380);
   IN1 = 1;
	 IN2 = 0;
	
	 IN3 = 1;
	 IN4 = 0;
}
void back()
{
	TIM_SetCompare2(TIM2,300);
	TIM_SetCompare3(TIM2,300);
	
   IN1 = 0;
	 IN2 = 1;
	
	 IN3 = 0;
	 IN4 = 1;
}
void right()
{
	TIM_SetCompare2(TIM2,400);
	TIM_SetCompare3(TIM2,400);
	
   IN1 = 1;
	 IN2 = 0;
	
	 IN3 = 0;
	 IN4 = 0;
}
void left()
{
	TIM_SetCompare2(TIM2,400);
	TIM_SetCompare3(TIM2,400);
	
   IN1 = 0;
	 IN2 = 0;
	
	 IN3 = 1;
	 IN4 = 0;
}
void turn()
{
	TIM_SetCompare2(TIM2,250);
	TIM_SetCompare3(TIM2,250);
	
   IN1 = 0;
	 IN2 = 1;
	
	 IN3 = 1;
	 IN4 = 0;
}
void stop()
{

   IN1 = 0;
	 IN2 = 0;
	
	 IN3 = 0;
	 IN4 = 0;
}

四.效果展示

请添加图片描述
请添加图片描述
请添加图片描述

stm32循迹小车系列文章:
1.stm32循迹小车详细制作过程(附加完全版代码)
2.L298n电机驱动详细介绍(stm32循迹小车中L298n的用法)
3.超声波模块详细介绍(stm32循迹小车中超声波的介绍)

寻迹程序在群资料,有问题可以直接在群里问,互相交流学习。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

stm32循迹小车详细制作过程(附加完全版代码) 的相关文章

  • ARM NEON:如何实现 256 字节查找表

    我正在使用内联汇编将我编写的一些代码移植到 NEON 我需要的一件事是将范围 0 128 的字节值转换为表中采用完整范围 0 255 的其他字节值 该表很短 但其背后的数学并不容易 因此我认为不值得每次 即时 计算它 所以我想尝试查找表 我
  • 如何创建具有自定义外设和内存映射的 QEMU ARM 机器?

    我正在为 Cortex M3 cpu 编写代码 并且正在使用以下命令执行单元测试qemu arm二进制 现在一切都很好 但我想知道我是否能够使用测试整个系统qemu system arm 我的意思是 我想为 qemu 编写自定义 机器 我将
  • 将ELF文件加载到内存中

    我正在尝试将 elf 文件放入内存然后执行它 步骤如下 1 要放入内存的文件 int main printf Hello world n return 0 2 编译它gcc o hello hello c static ELF Header
  • 嵌入式 C++ (ARM9) 单元测试

    我来自 Java 和 JUnit 的世界 我演示了 Hudson 以及我使用 JUnit 取得的所有成果 我想在嵌入式设备上对 C 代码执行相同的操作 但找不到从哪里开始 该项目使用 iccarm exe IAR 编译器 进行编译 现在使用
  • 适用于arm(cortex-m3)的位置独立可执行文件(-pie)

    我正在使用codesourcery g lite 基于gcc4 7 2版本 为stm32 Cortex m3 编程 我希望动态加载可执行文件 我知道我有两个选择 1 可重定位的elf 需要一个elf解析器 2 具有全局偏移寄存器的位置无关代
  • HAL_Delay() 陷入无限循环

    我被 HAL Delay 函数困住了 当我调用此函数 HAL Delay 时 控制陷入无限循环 在寻找问题的过程中 我发现了这个 http www openstm32 org forumthread2145 threadId2146 htt
  • 在 ARM 处理器上执行存储在外部 SPI 闪存中的程序

    我有一个 ARM 处理器 能够与外部闪存芯片连接 写入芯片的是为 ARM 架构编译的程序 可供执行 我需要知道如何将这些数据从外部闪存获取到 ARM 处理器上以供执行 我可以提前运行某种复制例程 将数据复制到可执行内存空间吗 我想我可以 但
  • ARM架构中不同处理器模式下如何使用内核堆栈?

    据我了解 每个进程都有一个用户堆栈和内核堆栈 除此之外 ARM 架构中的每种模式都有一个堆栈 所以我想知道不同的堆栈和堆栈指针在 ARM 模式下如何工作 另外 何时会使用与进程关联的内核堆栈 何时会使用与进程关联的内核堆栈 当您进行系统调用
  • DSP 库 - RFFT - 奇怪的结果

    最近我一直在尝试在我的STM32F4 Discovery评估板上进行FFT计算 然后将其发送到PC 我已经调查了我的问题 我认为我对制造商提供的 FFT 函数做错了 我正在使用 CMSIS DSP 库 现在我一直在用代码生成样本 如果工作正
  • 将 GCC 内联汇编与采用立即值的指令结合使用

    问题 我正在为 ARM Cortex M3 处理器开发定制操作系统 为了与我的内核交互 用户线程必须生成 SuperVisor Call SVC 指令 以前称为 SWI 用于软件中断 该指令在ARM ARM中的定义是 这意味着该指令需要即时
  • 交叉编译 Qt 4.7 时出现“非法指令”

    我已经在这个问题上苦苦挣扎了一个多星期了 但仍然找不到解决方案 我正在尝试为 ARM 设备交叉编译 Qt 4 7 嵌入式开源版本 构建过程本身可以顺利完成 但生成的二进制文件似乎包含处理器无法理解的指令 构建主机是 i386 上的 Debi
  • 分析 Cortex-M7 (stm32f7) 上的 memcpy 性能

    简洁版本 从 GNU ARM 工具链中提取的 memcpy 的性能指标在 ARM Cortex M7 上对于不同的副本大小似乎差异很大 即使复制数据的代码始终保持不变 这可能是什么原因造成的 长版 我是使用 GNU Arm 工具链 11 2
  • 移动数组中的元素

    我需要一点帮助 我想将数组中的元素向上移动一个元素 以便新位置 1 包含位置 1 中的旧值 new 2 包含 old 1 依此类推 旧的最后一个值被丢弃 第一个位置的新值是我每秒给出的新值 我使用大小为 10 的数组 uint32 t TE
  • 是否可以将 SpaCy 安装到 Raspberry Pi 4 Raspbian Buster

    我一整天都在安装 SpaCy sudo pip install U spacy Looking in indexes https pypi org simple https www piwheels org simple Collectin
  • 基于 Windows 8 ARM 的平板电脑上的 VB6

    随着 Windows 8 将支持 VB6 我的问题是 Microsoft 是否在任何地方表示 是或否 VB6 应用程序将在基于 ARM 的平板电脑上运行 如果没有 是否有任何 ARM 模拟器 以便我们可以在 Windows 8 ARM 平板
  • 如何设置 CMake 与 clang 交叉编译 Windows 上的 ARM 嵌入式系统?

    我正在尝试生成 Ninja makefile 以使用 Clang 为 ARM Cortex A5 CPU 交叉编译 C 项目 我为 CMake 创建了一个工具链文件 但似乎存在错误或缺少一些我无法找到的东西 当使用下面的工具链文件调用 CM
  • saber sd 如何在没有 SPL 的情况下直接从 uboot 启动

    sabre sd 基于 imx 6 最大内部 RAM 约为 150Kb 然而 uboot 足够大 可以容纳在这个空间中 在这个场景中事情是如何进行的 https community freescale com docs DOC 95015
  • 使用 NEON 内在函数除以浮点数

    我当时正在处理四个像素的图像 这是在armv7对于 Android 应用程序 我想分一个float32x4 t向量由另一个向量组成 但其中的数字与大约不同0 7 to 3 85 在我看来 除法的唯一方法是使用右移 但这是针对一个数字2 n
  • 直接在 ARM 目标上调试单声道应用程序

    我最近在 BeagleBone 嵌入式 ARM 设备上安装了 Mono 希望通过 USB 连接 Kinnect 传感器并使用 C Mono 控制它 我想知道 Mono 我正在使用 MonoDevelop 但我想这个问题也适用于 VS 是否允
  • stm32l0: 执行MI命令失败。使用 vFlashErase 数据包擦除闪存时出错

    我正在使用 Nucleo STM32L031 和 AC6 STM32 工作台 eclipse 我编写应用程序并进入调试模式 一切正常 直到我在应用程序中添加另一个功能 我注意到当我删除 评论 新函数 软件可以再次进入调试模式 但是当我添加

随机推荐

  • 【数据库复习】第二章关系数据库

    目录 一 关系数据结构及形式化定义 1 1关系 1 2关系模式 1 3关系数据库 1 4关系模型的存储结构 二 关系操作 三 关系的完整性 四 关系代数 4 1传统的集合运算 4 2专门的关系运算 4 2 1选择 selection 4 2
  • const int & a = 1;

    int a 1 报错 引用需要一个合法的内存空间 const int a 1 正确 类似于int temp 1 const int a temp
  • String时间类型转换为ZonedDateTime时间类型

    搞了一个早上 不知道怎么弄这个东西 最后发现没有必要将ZonedDateTime写的很全 可以精简的封装 public static ZonedDateTime changeShanghaiToUTC String beijingDateT
  • 【MIUI9】小米平板1MIPAD1欧版ROM历史ROM下载地址-另附挥泪典藏版V9系统

    费劲整理来的 上边是 小米平板1 MIPAD1的 ROM 下边是MI3W小米3联通版的ROM 欧版xiaomi eu系统的好处就是省电 miui MIPAD V9 2 4 0 KXFCNEK 97354839c6 4 4 zip 这个是小米
  • com.mongodb.MongoSocketReadTimeoutException: Timeout while receiving message

    报错 com mongodb MongoSocketReadTimeoutException Timeout while receiving message at com mongodb connection InternalStreamC
  • C++ list容器详解

    C list容器 list容器的基本概念 1 list的构造函数 2 list的赋值和交换 3 list的大小操作 4 list的插入和删除 5 list的数据存取 6 list的反转与排序 7 list的排序案例 list容器的基本概念
  • Vue 源码解读(12)—— patch

    当学习成为了习惯 知识也就变成了常识 感谢各位的 关注 点赞 收藏和评论 新视频和文章会第一时间在微信公众号发送 欢迎关注 李永宁lyn 文章已收录到 github 仓库 liyongning blog 欢迎 Watch 和 Star 前言
  • linux系统提示只读文件系统,无法创建文件

    可能磁盘写保护 第一步 df h 确定文件夹对应的磁盘 第二步 mount ro为只读 rw为可读可写 可以用mount命令看看ro的分区 如果发现有ro 就重新mount 如 umount dev sda1 mount dev sda1
  • 备战2022,Android中高级面试必知必会

    在过去不久的金九银十 有些小伙伴已经找到了理想的工作 当然也有很多小伙伴因为准备不充分 面试挂了 临近年关 最近有很多网友都在求大厂面试题 正好我在9月份和10月份整理和收集了 Android 中高级面试真题解析 于是就发上来分享给大家 这
  • 如何使用matlab读取excel中的表格数据

    如何使用matlab读取excel中的表格数据 设备系统 win10 操作软件 matlab2020b 1 首先打开matlab软件 点击 新建 脚本 2 在脚本中输入代码 A xlsread C Users Administrator D
  • [附源码]java毕业设计订单管理系统

    项目运行 环境配置 Jdk1 8 Tomcat7 0 Mysql HBuilderX Webstorm也行 Eclispe IntelliJ IDEA Eclispe MyEclispe Sts都支持 项目技术 SSM mybatis Ma
  • 【操作系统】虚拟内存的最大容量和实际容量的区别(以一道例题开头)

    实际内存为什么是2GB 512MB 因为实际容量是取CPU寻址 2 32B 与内存与外存之和 2GB 512MB 的最小值 就是相当于 数学里面两个值取最小值一样
  • gdbserver配置、远程调试以及ssh配置

    引言 GDB调试主要有两种方法 1 直接在目标板上通过gdb调试程序 2 在目标板上通过gdbserver运行程序 在宿主机上通过gdb调试程序 本篇文章主要来说明一下gdbserver远程调试的方法 主要以VScode举例说明 步骤 一
  • idea下载Scala插件(详细)

    目录 1 idea下载Scala 2 点击 Restart IDE 重启IDEA即可 3 创建scala目录 4 Mark scala目录为 source root 5 在windows的电脑安装scala jdk并且配置 环境变量 6 在
  • labelImg支持中文标注的文件

    链接 https pan baidu com s 1XCuLTlKRN7gVxJdQkcKnUw 密码 iaws
  • 读者-写者问题 (操作系统-进程)

    读者 写者问题 读进程优先算法 写者优先算法 问题描述 有读者和写者两组并发进程 共享一个文件 当两个或两个以上的读进程同时访问共享数据时不会产生副作用 但若某个写进程和其他进程 读进程或写进程 同时访问共享数据时则可能导致数据不一致的错误
  • 用vue3+elementplus做的一个滚动菜单栏的组件

    目录 起因 概览 设计及解决思路 1 滚动条竖起来 2 绑定菜单 3 吸附 优化 组件全部代码 起因 在elementplus中看到了滚动条绑定了slider 但是这个感觉很不实用 在底部 而且横向滚动 最常见的应该是那种固定在左上角的带着
  • 交叉编译适配mips架构的GDB

    交叉编译GDB 交叉编译GDB 1 下载GDB源码 2 解压并创建安装目录 3 编译安装 4 可能遇到的错误解决方法 1 下载termcap 2 将上面的编译安装gdb的脚本改一下 3 对于最后的权限不够无法删除PC机上termcap h文
  • 使用UE4(UnrealEngine)创建工程

    UE4系列文章目录 文章目录 UE4系列文章目录 前言 一 步骤 1 打开UE4软件 2 新建工程 3 选择游戏类型模板 4 项目设置 运行游戏 前言 使用UE4 UnrealEngine 创建工程 我这里的ue4版本是4 27 2 一 步
  • stm32循迹小车详细制作过程(附加完全版代码)

    stm32循迹小车详细制作过程 一 材料准备 1 主控板 Stm32f103c8t6 推荐 便宜够用 2 下载器 USB转TTL串口模块 3 电源 12v锂电池组 配套充电器 推荐下图这种 方便 好接线 12v 12v 12v 4 电机驱动