热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

基于STM32的智能循迹小车设计(基础版)

基于STM32的智能循迹小车设计(基础版)硬件准备1、小车底盘+四直流电机(带轮)2、STM32F103C8T6核心板3、12V8700mAh锂电池(可以用几节18650锂电池)4
基于STM32的智能循迹小车设计(基础版)

硬件准备

1、小车底盘+四直流电机(带轮)

《基于STM32的智能循迹小车设计(基础版)》

2、STM32F103C8T6核心板

《基于STM32的智能循迹小车设计(基础版)》

3、12V 8700mAh锂电池(可以用几节18650锂电池)

《基于STM32的智能循迹小车设计(基础版)》

4、循迹模块

选择的是TCRT500L,五路集成在一起,集成度比较高,但是可能不如五个单独的循迹模块好用
《基于STM32的智能循迹小车设计(基础版)》
5、L298N电机驱动模块
四驱车为啥用L298N电机驱动模块?
可以把左边的两个电机并联,用输出A控制。把右边的两个电机并联,用输出B控制。
《基于STM32的智能循迹小车设计(基础版)》
12V供电接电源正极,供电GND接电源负极和核心板GND,5V供电接核心板5V和循迹模块5V,然后循迹模块GND接核心板GND,所有设备就都可以上电了。(最好设置几个开关,安全且方便调试)
另外,接线最好先试触,避免短路。

6、杜邦线、开关若干

软件设计

1、电机调速

通过输出PWM控制电机转速

PWM初始化(以A1为例)

void TIM2_CH2_PWM_Init(void)
{
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_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
//A1 GPIO初始化
TIM_TimeBaseStructure.TIM_Period = 199;
TIM_TimeBaseStructure.TIM_Prescaler =7199;
TIM_TimeBaseStructure.TIM_ClockDivision = 0;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);
// 定时器初始化
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low;
TIM_OC2Init(TIM2, &TIM_OCInitStructure);
//定时器通道初始化
TIM_OC2PreloadConfig(TIM3, TIM_OCPreload_Enable);
//预装值初始化
TIM_Cmd(TIM2, ENABLE);
//打开定时器
}

初始化完后,输出PWM控制电机转速,注意,TIM_SetCompare2(TIM2,n);n越小占空比越大,点假转速越快,一下代码就是A1输出PWM占空比更大,它所对应的电机转速就越快。 具体的数据是多少,需要自己根据不同的场地去摸索,不停地调试。

void left()
{
TIM_SetCompare2(TIM2,20);
TIM_SetCompare3(TIM2,120);
}

2、循迹模块检测

GPIOB初始化,同时将B4 B5 B6 B7 B8设置为上拉输入

void GPIOB_Init()
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOB, ENABLE);

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7| GPIO_Pin_8;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;//上拉输入
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);
}

宏定义,少打字,B4 B5 B6 B7 B8 分别对应L1 L2 M R2 R1

#define L1 GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_4)
#define L2 GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_5)
#define M GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_6)
#define R2 GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_7)
#define R1 GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_8) // L1 L2 M R2 R1

读取函数

void Read_Date(void)
{
L1;
L2;
M;
R2;
R1;
}

3、主函数(用读取的循迹数据控制电机)

用了一个比较笨的但是很直接的方法,将所有的情况都罗列出来。
思路:如果L1检测到,那必须bigright;如果R1检测到,那必须bigleft;
那中间的那三位,还有8种,将这8种枚举就可。

int main()
{
SysTick_Init(72);
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
USART1_Init(9600);
GPIOB_Init();
TIM2_CH2_PWM_Init();
TIM2_CH3_PWM_Init();
while(1)
{
Read_Date();
if(L1==0&&L2==0&&M==0&&R2==0&&R1==0)
{
go();
delay_ms(10);
}

if(L1==0&&L2==1&&M==1&&R2==1&&R1==0)
{
go();
delay_ms(10);
}
if(L1==0&&L2==0&&M==1&&R2==0&&R1==0)
{
go();
delay_ms(10);
}
if(L1==0&&L2==1&&M==0&&R2==0&&R1==0)
{
right();
delay_ms(10);
}
if(L1==0&&L2==0&&M==0&&R2==1&&R1==0)
{
left();
delay_ms(10);
}
if(L1==0&&L2==1&&M==1&&R2==0&&R1==0)
{
right();
delay_ms(10);
}
if(L1==0&&L2==1&&M==0&&R2==1&&R1==0)
{
go();
delay_ms(10);
}
if(L1==0&&L2==0&&M==1&&R2==1&&R1==0)
{
left();
delay_ms(10);
}
if(R1==1)
{
bigleft();
delay_ms(10);
}
if(L1==1)
{
bigright();
delay_ms(10);
}
}
}

工程文件现已上传到资源,2积分即可下载。


推荐阅读
  • 在金融和会计领域,准确无误地填写票据和结算凭证至关重要。这些文件不仅是支付结算和现金收付的重要依据,还直接关系到交易的安全性和准确性。本文介绍了一种使用C语言实现小写金额转换为大写金额的方法,确保数据的标准化和规范化。 ... [详细]
  • 本文将介绍如何编写一些有趣的VBScript脚本,这些脚本可以在朋友之间进行无害的恶作剧。通过简单的代码示例,帮助您了解VBScript的基本语法和功能。 ... [详细]
  • 深入解析Android自定义View面试题
    本文探讨了Android Launcher开发中自定义View的重要性,并通过一道经典的面试题,帮助开发者更好地理解自定义View的实现细节。文章不仅涵盖了基础知识,还提供了实际操作建议。 ... [详细]
  • UNP 第9章:主机名与地址转换
    本章探讨了用于在主机名和数值地址之间进行转换的函数,如gethostbyname和gethostbyaddr。此外,还介绍了getservbyname和getservbyport函数,用于在服务器名和端口号之间进行转换。 ... [详细]
  • 本文深入探讨了Linux系统中网卡绑定(bonding)的七种工作模式。网卡绑定技术通过将多个物理网卡组合成一个逻辑网卡,实现网络冗余、带宽聚合和负载均衡,在生产环境中广泛应用。文章详细介绍了每种模式的特点、适用场景及配置方法。 ... [详细]
  • ImmutableX Poised to Pioneer Web3 Gaming Revolution
    ImmutableX is set to spearhead the evolution of Web3 gaming, with its innovative technologies and strategic partnerships driving significant advancements in the industry. ... [详细]
  • 扫描线三巨头 hdu1928hdu 1255  hdu 1542 [POJ 1151]
    学习链接:http:blog.csdn.netlwt36articledetails48908031学习扫描线主要学习的是一种扫描的思想,后期可以求解很 ... [详细]
  • 优化ListView性能
    本文深入探讨了如何通过多种技术手段优化ListView的性能,包括视图复用、ViewHolder模式、分批加载数据、图片优化及内存管理等。这些方法能够显著提升应用的响应速度和用户体验。 ... [详细]
  • 本文基于刘洪波老师的《英文词根词缀精讲》,深入探讨了多个重要词根词缀的起源及其相关词汇,帮助读者更好地理解和记忆英语单词。 ... [详细]
  • 数据管理权威指南:《DAMA-DMBOK2 数据管理知识体系》
    本书提供了全面的数据管理职能、术语和最佳实践方法的标准行业解释,构建了数据管理的总体框架,为数据管理的发展奠定了坚实的理论基础。适合各类数据管理专业人士和相关领域的从业人员。 ... [详细]
  • 深入解析Spring Cloud Ribbon负载均衡机制
    本文详细介绍了Spring Cloud中的Ribbon组件如何实现服务调用的负载均衡。通过分析其工作原理、源码结构及配置方式,帮助读者理解Ribbon在分布式系统中的重要作用。 ... [详细]
  • 题目Link题目学习link1题目学习link2题目学习link3%%%受益匪浅!-----&# ... [详细]
  • 本实验主要探讨了二叉排序树(BST)的基本操作,包括创建、查找和删除节点。通过具体实例和代码实现,详细介绍了如何使用递归和非递归方法进行关键字查找,并展示了删除特定节点后的树结构变化。 ... [详细]
  • 本文详细介绍了VMware的多种认证选项,帮助你根据职业需求和个人技能选择最合适的认证路径,涵盖从基础到高级的不同层次认证。 ... [详细]
  • Codeforces Round #566 (Div. 2) A~F个人题解
    Dashboard-CodeforcesRound#566(Div.2)-CodeforcesA.FillingShapes题意:给你一个的表格,你 ... [详细]
author-avatar
c72586051
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有