智能小车STM32——蓝牙循迹

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

1、功能介绍

蓝牙切换功能:智能小车内置了蓝牙模块,可以通过手机或其他蓝牙设备与之连接。用户可以通过手机发送指令控制小车的运动方向,实现远程控制。

循迹功能:智能小车配备了红外线传感器,可以实现循迹功能。通过检测地面上的黑线或白线,小车能够自动沿着线路行驶,实现自动导航功能。

1.硬件准备

小车底盘一个(两驱),5号4节电池盒一个,STM32f103c8t6最小系统板,红外光电反射传感器两个,ST-LINK下载器,HC-05蓝牙模块、CH340模块、L298N电机驱动模块,焊接设备、一些杜邦线、也可以再准备一个面包板。

硬件搭设

基于stm32单片机的蓝牙智能小车,stm32,嵌入式硬件,单片机

硬件及程序

1.电机驱动

基于stm32单片机的蓝牙智能小车,stm32,嵌入式硬件,单片机

1.主电源正极接12v,主电源负极接GND。

 2.先将5V的跳线帽短接,这样不用额外通过5V输入端外加电源在给单片机供电,可直接有5V输入端连接导线直接给单片机供电,如不将跳线帽短接,则5V输入端输出的电压为12V,连接单片机会导致单片机烧毁

3.A相使能,B相使能是对输入1.2.3.4的控制,如果使能A和使能B加上跳线帽的话,则只需要通过控制输入1.2(一个电机),3.4(另外一个电机)分别给两个电机的两端0和1实现正反转,都给0或者都给1则电机不会转,如果使能A和使能B不加上跳线帽的话,当AB为低电平时,输入1.2.3.4都不会工作,所以可以通过控制使能A和使能B的开和关的周期来控制产生PWM波。
 

2.小车运动

  • 当IN1、IN3为高电平,IN2、IN4为低电平时,电机正转
  • 当IN1、IN3为低电平,IN2、IN4为高电平时,电机反转
  • 都为高电平时,电机不转
  • 电机的正转和反转与跟电机的接线不同而不同,注意自己调试

motor.c

#include "stm32f10x.h"  
#include "pwm.h"
 
void motor_init()
{
	GPIO_InitTypeDef GPIO_InitStructure;
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
	
	//2.设置GPIO模式
	//PB12~PB15 通用推挽输出
 
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7 |GPIO_Pin_8 |GPIO_Pin_11;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOA, &GPIO_InitStructure);
	  PWM_Init();
	
}
 
 
void car_go()
{
		//左轮
	GPIO_SetBits( GPIOA, GPIO_Pin_6);
	GPIO_ResetBits( GPIOA,GPIO_Pin_7);
	TIM_SetCompare3(TIM3, 90  );
 
	//右轮
	GPIO_SetBits( GPIOA, GPIO_Pin_8);
	GPIO_ResetBits( GPIOA,GPIO_Pin_11);
	TIM_SetCompare4(TIM3, 90  );
	
}
void car_back()
{
	//左轮
	GPIO_ResetBits( GPIOA, GPIO_Pin_6);
	GPIO_SetBits( GPIOA,GPIO_Pin_7);
	TIM_SetCompare3(TIM3, 90  );
	
	//右轮
	GPIO_ResetBits( GPIOA, GPIO_Pin_8);
	GPIO_SetBits( GPIOA,GPIO_Pin_11);
	TIM_SetCompare4(TIM3, 90  );
 
}
void car_right()
{
	//左轮
	GPIO_ResetBits( GPIOA, GPIO_Pin_6);
	GPIO_ResetBits( GPIOA,GPIO_Pin_7);
		TIM_SetCompare3(TIM3, 90  );
	
	//右轮
	GPIO_SetBits( GPIOA, GPIO_Pin_8);
	GPIO_ResetBits( GPIOA,GPIO_Pin_11);
	TIM_SetCompare4(TIM3, 75);
	
}
void car_left ()
{
	//左轮
	GPIO_SetBits( GPIOA, GPIO_Pin_6);
	GPIO_ResetBits( GPIOA,GPIO_Pin_7);
	TIM_SetCompare3(TIM3, 75 );
 
	//右轮
	GPIO_ResetBits( GPIOA, GPIO_Pin_8);
	GPIO_ResetBits( GPIOA,GPIO_Pin_11);
	TIM_SetCompare4(TIM3, 90 );
 
}
void car_stop ()
{
	//左轮
	GPIO_ResetBits( GPIOA, GPIO_Pin_6);
	GPIO_ResetBits( GPIOA,GPIO_Pin_7);
 
	//右轮
	GPIO_ResetBits( GPIOA, GPIO_Pin_8);
	GPIO_ResetBits( GPIOA,GPIO_Pin_11);
 
}

pwm.c

#include "stm32f10x.h"
 
void PWM_Init(void)
{
	
	
	GPIO_InitTypeDef GPIO_InitStructure;
	TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
	TIM_OCInitTypeDef TIM_OCInitStructure;
	//1.打开时钟
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
	
	//PB8,PB9 复用推挽输出
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOB, &GPIO_InitStructure);
	
	//初始化TIM4 100us
	TIM_InternalClockConfig(TIM3);
	
	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(TIM3, &TIM_TimeBaseInitStructure);
	
	//初始化PWM波形
	TIM_OCStructInit(&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_OC3Init(TIM3, &TIM_OCInitStructure);//初始化右轮
	
	
	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(TIM3, &TIM_TimeBaseInitStructure);
 
 
	TIM_OCStructInit(&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(TIM3, &TIM_OCInitStructure);//初始化左轮
	
	//使能定时器
	TIM_Cmd(TIM3, ENABLE);
 
}
 
void PWM_SetCompare3(uint16_t Compare)
{
	TIM_SetCompare3(TIM3, Compare);
}
void PWM_SetCompare4(uint16_t Compare)
{
	TIM_SetCompare3(TIM3, Compare);
}

2.循迹模块

基于stm32单片机的蓝牙智能小车,stm32,嵌入式硬件,单片机

循迹模块通常具有两个红外传感器,可以通过连接线将其与单片机的GPIO口相连。确保连接正确且稳固。首先,初始化单片机的相关引脚,并设置为输入模式。然后,循迹模块的红外传感器将会输出高低电平信号,根据这些信号判断当前位置是否在黑线上。可以使用if语句或逻辑判断来处理不同的情况,例如当传感器检测到黑线时小车继续前进,当传感器检测到白线时小车停止或转向等。


track.c


#include "stm32f10x.h"
#include "motor.h"
 
#define track_left  GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_6)
#define track_right  GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_8)
 
void track_Init(){
	GPIO_InitTypeDef GPIO_InitStructure;
 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
	
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_8;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOB, &GPIO_InitStructure);
 
}
 
void track(){
 if(track_left==0 && track_right==0 ){
   car_go();
    }
 else if(track_left==1 && track_right==0){
  car_left();
  }
 else if(track_left==0 && track_right==1){
 
 car_right();
  }
 else {
  car_stop();
  }
 
 
}	

3.蓝牙模块

蓝牙模块的前期调试,可用usb转ttl模块连接蓝牙模块,RXD-TX TXD-RX VCC-VCC GND-GND。

如果上电了,蓝牙指示灯默认是2s闪烁就是进入了AT指令模式,可通过上位机向蓝牙发送指令。如果上电不是AT指令模式,就摁着蓝牙的按键再上电。

AT指令集(建议改名字就好,密码不要改)

AT+NAME=Bluetooth-Master  蓝牙主机名称为Bluetooth-Master

AT+ROLE=1                蓝牙模式为主模式

AT+CMODE=0               蓝牙连接模式为任意地址连接模式

AT+PSWD=1234             蓝牙配对密码为1234

AT+UART=9600,0,0       蓝牙通信串口波特率为9600,停止位1位,无校验位

AT+RMAAD                 清空配对列表

usart.c

#include "stm32f10x.h"
#include "usart.h"	
#include "pwm.h"
#include "motor.h"
#include "track.h"
 
//
//加入以下代码,支持printf函数,而不需要选择use MicroLIB	  
#if 1
#pragma import(__use_no_semihosting)             
//标准库需要的支持函数                 
struct __FILE 
{ 
	int handle; 
 
}; 
 
FILE __stdout;       
//定义_sys_exit()以避免使用半主机模式    
void _sys_exit(int x) 
{ 
	x = x; 
} 
//重定义fputc函数 
int fputc(int ch, FILE *f)
{      
	while((USART1->SR&0X40)==0);//循环发送,直到发送完毕   
    USART1->DR = (u8) ch;      
	return ch;
}
#endif 
 
 
 
#if EN_USART1_RX   //如果使能了接收
//串口1中断服务程序
//注意,读取USARTx->SR能避免莫名其妙的错误   	
u8 USART_RX_BUF[USART_REC_LEN];     //接收缓冲,最大USART_REC_LEN个字节.
//接收状态
//bit15,	接收完成标志
//bit14,	接收到0x0d
//bit13~0,	接收到的有效字节数目
u16 USART_RX_STA=0;       //接收状态标记	  
  
void usart_Init(void)
{
	
  //GPIO端口设置
  GPIO_InitTypeDef GPIO_InitStructure;
	USART_InitTypeDef USART_InitStructure;
	NVIC_InitTypeDef NVIC_InitStructure;
	 
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_USART1, ENABLE);	//使能USART1,GPIOA时钟
	
	//USART1_TX   GPIOA.9
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; //PA.9
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;	//复用推挽输出
  GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOA.9
   
  //USART1_RX	  GPIOA.10初始化
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;//PA10
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//浮空输入
  GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOA.10  
 
  //Usart1 NVIC 配置
  NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=3 ;//抢占优先级3
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;		//子优先级3
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;			//IRQ通道使能
	NVIC_Init(&NVIC_InitStructure);	//根据指定的参数初始化VIC寄存器
  
   //USART 初始化设置
 
	USART_InitStructure.USART_BaudRate = 9600;//串口波特率
	USART_InitStructure.USART_WordLength = USART_WordLength_8b;//字长为8位数据格式
	USART_InitStructure.USART_StopBits = USART_StopBits_1;//一个停止位
	USART_InitStructure.USART_Parity = USART_Parity_No;//无奇偶校验位
	USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//无硬件数据流控制
	USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;	//收发模式
 
  USART_Init(USART1, &USART_InitStructure); //初始化串口1
  USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);//开启串口接受中断
  USART_Cmd(USART1, ENABLE);               
}
 
 
 
#endif	
 
void USART1_IRQHandler(void)
{
	int res;
	if(USART_GetITStatus( USART1, USART_IT_RXNE)==SET)
	
	res=USART_ReceiveData(USART1);
	switch(res){
		
		case '1': car_go();break;	
		case '2': car_back();break;
		case '3': car_left();break;
		case '4': car_right();break;
		case '5': car_stop();break;
 
	USART_ClearITPendingBit( USART1, USART_IT_RXNE);
	}
}

usart.h

#ifndef __USART_H
#define __USART_H
#include "stdio.h"	
#include "stm32f10x.h"
#define USART_REC_LEN  			200  	//定义最大接收字节数 200
#define EN_USART1_RX 			1		//使能(1)/禁止(0)串口1接收
	  	
extern u8  USART_RX_BUF[USART_REC_LEN]; //接收缓冲,最大USART_REC_LEN个字节.末字节为换行符 
extern u16 USART_RX_STA;         		//接收状态标记	
//如果想串口中断接收,请不要注释以下宏定义
void uart_init();
#endif

Delay.c

#include "stm32f10x.h"
 
/**
  * @brief  微秒级延时
  * @param  xus 延时时长,范围:0~233015
  * @retval 无
  */
void Delay_us(uint32_t xus)
{
	SysTick->LOAD = 72 * xus;				//设置定时器重装值
	SysTick->VAL = 0x00;					//清空当前计数值
	SysTick->CTRL = 0x00000005;				//设置时钟源为HCLK,启动定时器
	while(!(SysTick->CTRL & 0x00010000));	//等待计数到0
	SysTick->CTRL = 0x00000004;				//关闭定时器
}
 
/**
  * @brief  毫秒级延时
  * @param  xms 延时时长,范围:0~4294967295
  * @retval 无
  */
void Delay_ms(uint32_t xms)
{
	while(xms--)
	{
		Delay_us(1000);
	}
}
 
/**
  * @brief  秒级延时
  * @param  xs 延时时长,范围:0~4294967295
  * @retval 无
  */
void Delay_s(uint32_t xs)
{
	while(xs--)
	{
		Delay_ms(1000);
	}
}

main.c

#include "stm32f10x.h"
#include "Delay.h"
#include "motor.h"
#include "pwm.h"
#include "track.h"
#include "usart.h"
 
#define key  GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_3)
 
 
uint8_t Speed;
 
void delay_s(int s);
void USART1_IRQHandler(void);
void usart_Init();
 
void delay_s(int s)
{
	uint8_t b;
	for( b = s;b>0;b--)
	{
		delay_ms(1000);
	}
}
 
 
int main(void) 
{
	
	motor_init();
  usart_Init();
	track_Init();
 
	while(1)
	{   
		if(key==0)
		{
  	USART1_IRQHandler();
		}
		else
		{
		track();
		}
   }
}



 文章来源地址https://www.toymoban.com/news/detail-803496.html

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

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

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

相关文章

  • 基于stm32的智能小车(远程控制、避障、循迹)

    学完stm32,总是想做点东西“大显身手”一下,智能小车就成了首选项目,其核心只是就是PWM输出,I/O口引脚电平判断。 制作智能小车的硬件名单: 由于我们做的控制功能可以使用2.4G控制,也可以使用蓝牙进行控制, 两种传输方式所需购买的模块不同,已在硬件名单中加以

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

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

    2024年02月11日
    浏览(49)
  • STM32超级蓝牙小车——基于STM32F103C8T6的多功能蓝牙小车(PID循迹、跟踪、有源蜂鸣器播放音乐、蓝牙遥控、AD采集+DMA转运等超多元素小车)

    一、项目时间:2023.7.24~11.26 二、实现效果:通过蓝牙控制小车运动与模式转换                         模式一:循迹模式                         模式二:跟踪模式                         模式三:音乐模式                         模式四:控制运动模式 三、使

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

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

    2024年02月06日
    浏览(58)
  • 基于STM32的智能巡检小车系统设计--循迹模块设计

    作者:车 邮箱:692604135@qq.com 学校:西安工程大学硕士研究生 方向:机器视觉、图像分割、深度学习 灰度循迹传感器是主要 用于小车沿黑色赛道循迹 的传感器。 灰度传感器利用不同颜色的检测面对光的反射程度不同,灰度感应接收管对不同检测面返回的光,其阻值也不同

    2024年02月07日
    浏览(61)
  • 70、基于STM32单片机的蓝牙智能热水器控制系统设计温度温控水温水位检测

    毕设帮助、开题指导、技术解答(有偿)见文末。 目录 摘要 一、硬件方案 二、设计功能 三、实物图 四、原理图 五、PCB图 六、硬件框图 七、程序源码 八、资料包括 随着社会的发展,人类科技的进步,各行各业都在使自己的产品智能化、数字化,因老式的热水器使用煤气

    2024年02月05日
    浏览(107)
  • [STM32F103C8T6]基于stm32的循迹,跟随,避障智能小车

    目录 1.小车驱动主要是通过L9110S模块来驱动电机 motor.c 2.我们可以加入串口控制电机驱动(重写串口接收回调函数,和重定向printf) Uart.c main.c  3.点动功能 uart.c main.c 为什么使用的是HAL_Delay()要设置滴答定时器的中断优先级呢? 4.小车PWM调速,  6.跟随功能 7.避障功能 超声波测距

    2024年02月13日
    浏览(57)
  • 基于STM32的智能循迹避障小车实验(超声波部分)

    接上一篇基于STM32的智能循迹避障小车实验(舵机旋转部分) 最后这部分我们实现超声波部分和最后代码的整合 本部分实验采用的是 超声波模块 HC-SR04 ,它长这样:   买这个的时候最好再买一个支架,可以直接架在舵机上,探查周围的距离。 超声波模块有 4 个引脚 ,分别

    2024年02月07日
    浏览(48)
  • STM32单片机智能小车一PWM方式实现小车调速和转向

    目录 1. 电机模块开发 2. 让小车动起来 3. 串口控制小车方向 4. 如何进行小车PWM调速 5. PWM方式实现小车转向 L9110s概述 接通VCC,GND 模块电源指示灯亮, 以下资料来源官方,具体根据实际调试 IA1输入高电平,IA1输入低电平,【OA1 OB1】电机正转; IA1输入低电平,IA1输入高电平,

    2024年02月07日
    浏览(59)
  • 单片机设计:基于stm32智能语音识别蓝牙音响(ld3320语音识别模块+mp3模块+喇叭+点阵屏+OLED+蓝牙+手机app)

    单片机设计:基于stm32智能语音识别蓝牙音响(ld3320语音识别模块+mp3模块+喇叭+点阵屏+OLED+蓝牙+手机app) 一、主要功能: 1.手机app播放内存卡的音乐、同时点阵屏随音乐进行跳动 2.0LED、手机app显示当前音量以及当前状态 3.手机app远程调节音量阈值,可以切换上一首、下一首,音乐

    2024年02月07日
    浏览(58)

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

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

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

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

二维码1

领取红包

二维码2

领红包