基于STM32,TB6612,TCRT5000的简易红外循迹小车

这篇具有很好参考价值的文章主要介绍了基于STM32,TB6612,TCRT5000的简易红外循迹小车。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

        提醒:本文章只叙述此小车相关大概内容(如模块的设置,C语言基础实现等),单片机详细教学不涉及。

摘要

        循迹小车是学习单片机的“地基”,它能够让初学者认识单片机内部硬件结构及其功能,熟悉单片机的一些基础操作,如I/O的应用,定时中断与外部中断的应用等,同时也能让初学者对于C语言编程有更深的认识。我采用STM32F103C8T6、TB6612、TCRT5000三个主要模块进行小车组装,刚开始确实有很多问题,随着进一步深入,问题也迎刃而解了,所以我们学习这个小车,主要在于思想的转变和善于去研究,我相信很多过程中遇到的难题都会被我们解决的。

目录

摘要

一、材料选择

二、模块思维导图

三、主要材料概述

1、STM32F103C8T6最小系统板

2、TB6612电机驱动

3、LM2596S DC-DC直流可调降压模块

 4、TCRT5000红外循迹模块

5、显示屏模块

三、相关代码


一、材料选择

        最近也是参加电赛,所以所有的材料都是运用学校实验室提供的。

  1. 单片机:STM32F103C8T6;
  2. 电机驱动:TB6612或者L298(我选用TB6612);
  3. 降压模块:(可随意)LM2596;
  4. 循迹模块:TCRT5000(5个);
  5. 显示屏模块:四针脚I²C版本OLED;
  6. 四个电机加轮子;
  7. 杜邦线若干;
  8. 开关一个;
  9. 电池(12V)。

二、模块思维导图

tb6612驱动的循迹小车代码,c语言,stm32    

         注意:本思维导图只针对于代码中各模块部分。

三、主要材料概述

1、STM32F103C8T6最小系统板

tb6612驱动的循迹小车代码,c语言,stm32

        STM32是一个微控制器产品系列的总称,目前这个系列中已经包含了多个子系列,分别是: STM32 小容量产品、STM32 中容量产品、 STM32 大容量产品和 STM32 互联型产品;按照功能上的划分,又可分为STM32F101xx、 STM32F102xx STM32F103xx 系列。
        STM32F103 C8T6引脚定义图:
tb6612驱动的循迹小车代码,c语言,stm32
        注意:
        (1)单片机有些引脚对应功能是特有的,如定时器的通道输出口,它们在使用的时候只需要初始化I/O即可;
        (2)单片机最大承受电压为5V,注意通电之前一定要查看降压模块的连接是否正确或者是否有降压模块。

2、TB6612电机驱动

tb6612驱动的循迹小车代码,c语言,stm32tb6612驱动的循迹小车代码,c语言,stm32

        TB6612电机驱动共有16个个引脚。

        VM最大接15V电源,本博客接12V足以;

        VCC接3.3V或5V;

        GND不用说了吧,接地就行;

        PWMA、PWMB需要PWM波(方波),以控制A电机或B电机的速度,连接单片机时要注意PWM波输出的端口对应好,本文采用的是定时器TIM2的3、4通道,所以PWMA、PWMB分别连接PA2、PA3口,具体要参考你用的哪个定时器,然后根据引脚定义图对应好引脚位置;

        AIN1、AIN2、BIN1、BIN2用来控制电机的正反转,需要连接单片机的I/O口来给予它们高低电平,AIN控制A电机,BIN控制B电机,具体控制如下表(以控制A电机为例):

AIN1 0 1 0
AIN2 0 0 1
停止 正转 反转

        AO1、A02、BO1、BO2可以驱动电机,所以直接连接电机来让它们转起来!(注意别连反了,不然你的电机总是逆天的反转或者转圈~)

        其实对于电机驱动模块最麻烦的就是PWM波的输入以及脉宽调制,具体体现在代码中。

3、LM2596S DC-DC直流可调降压模块

        因为在电路中有许多器件不能承受12V电压,所以我们需要将电源电压降到5V或者3.3V,这时我们就要用到降压模块,具体连接方法很明显,以LM2596为例,IN+连接电源正极,IN-连接电源负极,OUT+输出3.3V或者5V电压,OUT-输出GND。

tb6612驱动的循迹小车代码,c语言,stm32

 4、TCRT5000红外循迹模块

        相较于其它循迹方法,红外循迹较为简单,但也无法做到十分精准,本文以红外循迹为例,讲述循迹方法,希望各位同学能举一反三,继续学习!

        tb6612驱动的循迹小车代码,c语言,stm32

       它有四个引脚:VCC(接3~5V电压)、GND(接地)、D0(接单片机I/O口)、A0(模拟信号输出,一般不接)

        话不多说,直接讲原理:当检测到黑线时,传感器上的指示灯灭掉,D0输出高电平返回到单片机上;当未检测到黑线时,传感器上的指示灯亮,D0输出低电平返回到单片机上。

5、显示屏模块

tb6612驱动的循迹小车代码,c语言,stm32


三、相关代码

motor.c

#include "stm32f10x.h"                  // Device header
#include "pwm.h"

//注意:增加某个函数要在对应.h文件中声明,否则会报错。

void Motor_Init(void)
{
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
	
	GPIO_InitTypeDef GPIO_InitStructure;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;		//推挽输出
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7;	//定义I/O口
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOA, &GPIO_InitStructure);
	
	PWM_Init();
}

void Motor_LEFT_SetSpeed(int8_t Speed)		//左电机正反转
{
	if (Speed >= 0)
	{
		GPIO_SetBits(GPIOA, GPIO_Pin_4);
		GPIO_ResetBits(GPIOA, GPIO_Pin_5);
		PWM_SetCompare3(Speed);
	}
	else
	{
		GPIO_ResetBits(GPIOA, GPIO_Pin_4);
		GPIO_SetBits(GPIOA, GPIO_Pin_5);
		PWM_SetCompare3(-Speed);
	}
}
void Motor_RIGHT_SetSpeed(int8_t Speed)		//右电机正反转
{
	if (Speed >= 0)
	{
		GPIO_SetBits(GPIOA, GPIO_Pin_6);
		GPIO_ResetBits(GPIOA, GPIO_Pin_7);
		PWM_SetCompare4(Speed);
	}
	else
	{
		GPIO_ResetBits(GPIOA, GPIO_Pin_6);
		GPIO_SetBits(GPIOA, GPIO_Pin_7);
		PWM_SetCompare4(-Speed);
	}
}

pwm.c

#include "stm32f10x.h"                  // Device header

extern uint16_t Num;			//调用.c文件定义的Num变量
extern uint16_t t;
extern int FLAG;
void PWM_Init(void)
{
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
	TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
	TIM_OCInitTypeDef TIM_OCInitStructure;
	
	GPIO_InitTypeDef GPIO_InitStructure;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2 | GPIO_Pin_3;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOA, &GPIO_InitStructure);
	
	TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;
	TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;
	TIM_TimeBaseInitStructure.TIM_Period = 100 - 1;		//ARR
	TIM_TimeBaseInitStructure.TIM_Prescaler = 36 - 1;		//PSC
	TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0;
	TIM_TimeBaseInit(TIM2, &TIM_TimeBaseInitStructure);
	
	
	TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
	TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
	TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
	TIM_OCInitStructure.TIM_Pulse = 0;		//CCR
	
	
	TIM_OC3Init(TIM2, &TIM_OCInitStructure);

	TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
	TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
	TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
	TIM_OCInitStructure.TIM_Pulse = 0;		//CCR
	
	TIM_OC4Init(TIM2, &TIM_OCInitStructure);
	
	
  
	TIM_Cmd(TIM2, ENABLE);
}
void Timer_Init(void)
{
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);

	
	TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
	TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;
	TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;
	TIM_TimeBaseInitStructure.TIM_Period = 10000 - 1;
	TIM_TimeBaseInitStructure.TIM_Prescaler = 7200 - 1;
	TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0;
	TIM_TimeBaseInit(TIM3, &TIM_TimeBaseInitStructure);
	
	TIM_ClearFlag(TIM3, TIM_FLAG_Update);
	TIM_ITConfig(TIM3, TIM_IT_Update, ENABLE);
	
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_3);
	
	NVIC_InitTypeDef NVIC_InitStructure;
	NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn;
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
	NVIC_Init(&NVIC_InitStructure);
	
	TIM_Cmd(TIM3, ENABLE);
}
void TIM3_IRQHandler(void)
{
	if (TIM_GetITStatus(TIM3, TIM_IT_Update) == SET)
	{
		Num ++;
		if(FLAG == 3)
		{
			t = Num;
		}
		TIM_ClearITPendingBit(TIM3, TIM_IT_Update);
	}
}

void PWM_SetCompare3(uint16_t Compare)
{
	TIM_SetCompare3(TIM2, Compare);
}

void PWM_SetCompare4(uint16_t Compare)
{
	TIM_SetCompare4(TIM2, Compare);
}

main.c

#include "stm32f10x.h"
#include "delay.h"
#include "motor.h"
#include "tcrt5000.h"
#include "OLED.h"
#include "pwm.h"

uint16_t t;
uint16_t Num;
uint16_t LEFT1,RIGHT1,LEFT2,RIGHT2,MIDDLE;
int FLAG = 0;
int main(void)
{	
	Timer_Init();	//初始化计时函数
	OLED_Init();	//初始化显示屏函数
	Motor_Init();	//初始化电机驱动函数
	tcrt5000_init();	//初始化红外循迹函数
    while (1)
    {
		OLED_ShowString(2, 1, "TIME:");
		OLED_ShowNum(2, 6, Num, 5);
		RIGHT1 = GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_5);
		LEFT1 = GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_6);
		RIGHT2 = GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_7);
		LEFT2 = GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_8);
		MIDDLE = GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_9);
		if(LEFT1 == 0 && LEFT2 == 0 && MIDDLE == 1 && RIGHT2 == 0 && RIGHT1 == 0)				//直走
		{
			Motor_LEFT_SetSpeed(65);
			Motor_RIGHT_SetSpeed(65);
		}

		else if((LEFT1 == 1 || LEFT2 == 1) && MIDDLE == 0 && RIGHT2 == 0 && RIGHT1 == 0)		//左转
		{
			Motor_LEFT_SetSpeed(-50);
			Motor_RIGHT_SetSpeed(65);
		}

		else if(LEFT1 == 0 && LEFT2 == 0 && MIDDLE == 0 && (RIGHT1 == 1 || RIGHT2 == 1))		//右转
		{
			Motor_LEFT_SetSpeed(65);
			Motor_RIGHT_SetSpeed(-50);
		}

		else if(LEFT1 == 0 && LEFT2 == 1 && MIDDLE == 1 && RIGHT2 == 0 && RIGHT1 == 0)			//左转(增加灵敏度)
		{
			Motor_LEFT_SetSpeed(-50);
			Motor_RIGHT_SetSpeed(65);
		}
		
		else if(LEFT1 == 1 && LEFT2 == 1 && MIDDLE == 1 && RIGHT2 == 0 && RIGHT1 == 0)			//左转(增加灵敏度)
		{
			Motor_LEFT_SetSpeed(-50);
			Motor_RIGHT_SetSpeed(65);
		}
		else if(LEFT1 == 0 && LEFT2 == 0 && MIDDLE == 1 && RIGHT2 == 1 && RIGHT1 == 0)			//右转(增加灵敏度)
		{
			Motor_LEFT_SetSpeed(65);
			Motor_RIGHT_SetSpeed(-50);
		}
		else if(LEFT1 == 0 && LEFT2 == 0 && MIDDLE == 1 && RIGHT2 == 1 && RIGHT1 == 1)			//右转(增加灵敏度)
		{
			Motor_LEFT_SetSpeed(65);
			Motor_RIGHT_SetSpeed(-50);
		}
		
		else if(LEFT1 == 0 && LEFT2 == 0 && MIDDLE == 0 && RIGHT2 == 0 && RIGHT1 == 0)			//未探测到黑线的时候直走(防止未检测到黑线时不动)
		{	
			Motor_LEFT_SetSpeed(65);
			Motor_RIGHT_SetSpeed(65);
		}

		else if(LEFT1 == 1 && LEFT2 == 1 && MIDDLE == 1 && RIGHT2 == 1 && RIGHT1 == 1)			//检测到横线
		{	
			if(FLAG == 0)							//标志位1(停止5秒后前进)
			{
				Motor_LEFT_SetSpeed(0);
				Motor_RIGHT_SetSpeed(0);
				delay_init();
				OLED_Clear();
				OLED_ShowString(1,7,"READY");
				OLED_ShowNum(3,1,5,1);
				delay_ms(1000);
				OLED_ShowNum(3,3,4,1);
				delay_ms(1000);
				OLED_ShowNum(3,5,3,1);
				delay_ms(1000);
				OLED_ShowNum(3,7,2,1);
				delay_ms(1000);
				OLED_Clear();
				OLED_ShowString(3,8,"GO!");
				delay_ms(1000);
				OLED_Clear();
				Motor_LEFT_SetSpeed(30);
				delay_ms(100);
				Motor_RIGHT_SetSpeed(30);
				delay_ms(100);
				FLAG ++;
			}
			else if(FLAG == 1)					//标志位2(停止5秒后前进)
			{
				Motor_LEFT_SetSpeed(0);
				Motor_RIGHT_SetSpeed(0);
				delay_init();
				OLED_Clear();
				OLED_ShowString(1,7,"READY");
				OLED_ShowNum(3,1,5,1);
				delay_ms(1000);
				OLED_ShowNum(3,3,4,1);
				delay_ms(1000);
				OLED_ShowNum(3,5,3,1);
				delay_ms(1000);
				OLED_ShowNum(3,7,2,1);
				delay_ms(1000);
				OLED_Clear();
				OLED_ShowString(3,8,"GO!");
				delay_ms(1000);
				OLED_Clear();
				Motor_LEFT_SetSpeed(80);
				delay_ms(500);
				Motor_RIGHT_SetSpeed(80);
				delay_ms(500);
				FLAG ++;
			}
			else if(FLAG == 2)					//标志位3(直走)
			{
				delay_init();
				OLED_ShowString(1,5,"STRINGHT");
				OLED_ShowString(2, 1, "TIME:");
				OLED_ShowNum(2, 6, Num, 5);
				Motor_LEFT_SetSpeed(85);
				Motor_RIGHT_SetSpeed(85);
				delay_ms(500);
				OLED_Clear();
				FLAG ++;
			}
			else if(FLAG == 3)					//标志位4(比赛结束,停止)
			{	
				FLAG = 0;
				int i;
				for(i = 0;i >= 0;i++)
				{
					OLED_ShowString(1,5,"STOP");
					OLED_ShowString(2, 1, "TIME:");
					OLED_ShowNum(2, 6, t, 5);
					Motor_LEFT_SetSpeed(0);
					Motor_RIGHT_SetSpeed(0);
				}
			}
		}	
    }
}

        代码中有很多冗余,由于时间紧张所以就没有仔细去改写,各位同学可以根据实际情况去修改内容。

       ( 另附:想要工程文件的同学可以评论邮箱,内含小车视频哦~转载请标明出处。)


        本次分享就到这里了,博主其实也是初学者,所以也非常希望各路大佬来批评指正,当然,如果我的文章能帮到您,请在评论区积极发言(手动狗头),这也是对我最大的鼓舞,谢谢!文章来源地址https://www.toymoban.com/news/detail-591158.html

到了这里,关于基于STM32,TB6612,TCRT5000的简易红外循迹小车的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • stm32平衡小车--(1)JGB-520减速电机+tb6612(附测试代码)

                                        这是我用的电机,红色框框中的就是 编码器 。 编码器是将信号(如比特流)或数据进行编制、转换为可用以通讯、传输和存储的信号形式的设备。编码器把角位移或直线位移转换成电信号,前者称为码盘,后者称为码尺。按照读出方

    2024年02月04日
    浏览(305)
  • 【 STM32实例 】 智能小车的红外循迹

    这篇文章我主要讲的是让基于stm32单片机下的智能小车实现红外循迹功能,智能小车的项目非常多,比如说循迹避障、蓝牙遥控、视觉控制等等,我将会一步一步带大家走进stm32单片机的项目当中。 项目源码置文章底部,可自提 在硬件部分,与前几节我所介绍的51智能小车大

    2024年02月02日
    浏览(43)
  • STM32循迹寻光避障小车(二)(红外循迹部分)

    目录 TRCT5000寻迹模块介绍 1. 模块介绍: 2. 管脚介绍: 3. 使用原理: 4. 代码部分: Tracing.c文件全部代码(附带注释) Tracing.h文件全部代码 首先介绍一下使用到的红外寻迹模块,我们采用了TRCT5000的三路红外寻迹模 我从网上找到如下的图片和资料: 1、采用TCRT5000红外反射传感

    2024年02月17日
    浏览(49)
  • 保姆级的Arduino循迹小车研发日志及一些坑(其中包含L298N、Arduino、TCRT5000以及1:48的TT电机的使用)

    开发要求如下: 引言:为什么会用到 米思齐 这个青少年编程软件是有两个原因: 接到了某所小学的研发项目需求,研发成果给小学生参加无人车循迹比赛。 实验室的师弟师妹并不是所有都有编程基础,因此米思齐可以作为简单的编程引入课程。 首先我认为 TCRT5000红外循迹

    2023年04月08日
    浏览(45)
  • STM32单片机PWM控制实现电机调速度(小车运动,STM32F103C8T6&TB6612&TT电机)

    作者:公子易平 时间:2023/6/6 前段时间做一个智能小车的相关项目时,发现很少有人能够将STM32的PWM控制讲清楚,故而书此文,希望对后来的学习者有所帮助。 STM32F103C8T6最小系统板 直流TT电机 电机驱动芯片(TB6612) 杜邦线若干 接线情况: TB6612引脚说明: STM32主控芯片与TB6612接

    2024年02月15日
    浏览(48)
  • STM32蓝牙小车、红外循迹小车、超声波避障小车项目设计

    本文旨在分享我学习STM32的过程中,为了强化学习成果,试着制作一些实训项目。最开始做的就是STM32蓝牙小车、STM32红外循迹小车、STM32超声波避障小车。 相信看完本文的你,一定可以亲手制作一辆属于自己的智能小车! 注:文末附源码工程,需要的读者可以至文末下载 如

    2024年01月20日
    浏览(42)
  • stm32+TB6612驱动直流电机

            因为单片机的不可以直接的驱动电机,所以需要在他们之间加上一个电机的驱动模块,之前的文章里面用过L298N电机驱动模块,现在再给大家推荐一个新的电机驱动模块,他比L298N好用许多,而且占用体积小,发热也少。TB6612可以一次驱动两个直流电机,输出PWM也

    2024年02月15日
    浏览(47)
  • STM32外设系列—TB6612FNG

    🎀 文章作者:二土电子 🌸 关注文末公众号获取其他资料和工程文件! 🐸 期待大家一起学习交流! 本文涉及到定时器和串口的知识,详细内容可见博主STM32速成笔记专栏。 TB6612FNG是东芝半导体的一款驱动电机的IC。一个TB6612FNG可以驱动两个电机,每一个驱动都有两个逻辑

    2024年02月14日
    浏览(48)
  • 基于STM32的智能循迹避障小车实验(循迹部分)

    接上一部分基于STM32的智能循迹避障小车实验(小车运动部分) 上一篇我们成功让小车动起来了,现在我们试着让小车听话地运动。 这一部分主要利用了循迹模块两个 图 1循迹模块 就是这个东西: 一共三个引脚 VCC :电源线,连接单片机的 3.3V-5V GND :地线,连接单片机的接

    2024年02月11日
    浏览(49)
  • 基于STM32的智能循迹避障小车实验(小车运动部分)

    写在前面 这个实验是关于智能小车的实验,现在的想法就是先做出一个循迹和避障功能,后续可能会再添加一些其他的模块。 我在做这个实验之前基本了解了F1系列开发板的大部分模块,如果没有学习之前的模块,建议先学习下开发板的基本模块。 实验所需的硬件 本来是想

    2024年02月06日
    浏览(58)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包