stm32蓝牙模块控制小车_51单片机蓝牙控制小车

stm32蓝牙模块控制小车_51单片机蓝牙控制小车STM32库函数开发系列文章目录第一篇:STM32F103ZET6单片机双串口互发程序设计与实现第二篇:最简单DIY基于STM32单片机的蓝牙智能小车设计方案文章目录STM32库函数开发系列文章目录前言一、最简单DIY基于STM32单片机的蓝牙智能小车设计方案是什么?二、使用步骤1.准备硬件2.准备一个串口通信的代码3.修改源码三、运行与调试总结前言    daodanjishui物联网核心原创技术之最简单DIY基于STM32单片机的蓝牙智能小车设计方案。    市面上有各种开源STM3

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE稳定放心使用

STM32库函数开发系列文章目录

第一篇:STM32F103ZET6单片机双串口互发程序设计与实现
第二篇:最简单DIY基于STM32单片机的蓝牙智能小车设计方案



前言

    daodanjishui物联网核心原创技术之最简单DIY基于STM32单片机的蓝牙智能小车设计方案。
    市面上有各种开源STM32蓝牙智能小车,但是有复杂的有简单的,如果想快速入门STM32蓝牙智能小车,这个方案会给你一个快捷高效的方案。


一、最简单DIY基于STM32单片机的蓝牙智能小车设计方案是什么?

    单片机初学者用串口来调试程序是非常方便的,用什么仿真器,用什么寄存器等等都不如串口打印来得方便快捷。在第一篇就是介绍了STM32串口互发程序,现在用串口蓝牙模块与单片机构成串口通信,调试的方式就涉及到第一篇的技术。
    在51单片机智能小设计专栏中的第一篇博文:最简单DIY的51蓝牙遥控小车设计方案讲述了用51单片机如何制作无线蓝牙智能小车。有些读者也觉得拿个51来做智能小车可扩展程度太低了,所以我这次推出了开源收费版的STM32蓝牙智能小车,采用双层透明亚克力板结构,使用带有数码管显示的电源,带有独立开关的L298N模块,一片STM32F103C8T6作为主控,两个18650高能锂电池供电,一个HC05串口蓝牙模块,三根铜柱把第二层的亚克力板撑起来了,整个小车结构都由我手工设计和搭建,看起来就像是一个艺术品。下面请看全家福:
在这里插入图片描述
再来第一个侧身照:
在这里插入图片描述
功能描述:这次的小车功能拓展提高了很多,首先支持三个串口同时使用,我定义串口一接蓝牙模块,串口二作为调试使用,串口三留给买家自行扩展,需要注意的是:stm32触发串口中断需要加入 \r\n,串口1是与蓝牙模块链接的,stm32的串口1中断必须接收到\r\n 才能触发串口中断,十六进制就是 0d 0a,串口1收到的数据会通过串口2输出到电脑调试助手,这样用串口2可以调试程序,看看串口1的蓝牙是否接收到数据另外给串口2发送数据的话,串口2会返回相同的数据,同时串口2也往串口1发送数据,这样也可以测试蓝牙模块是否能回复给蓝牙调试助手。

优酷视频演示地址:https://v.youku.com/v_show/id_XNDk2MjQ4MTM3Mg==.html

直接观看

最简单DIY基于STM32单片机的蓝牙智能小车设计方案

二、使用步骤

1.准备硬件

这个STM32智能蓝牙小车其实跟51智能蓝牙智能小车唯一区别的是核心板更换了,其他硬件保持一致,所以不懂的买家可以看看最简单DIY的51蓝牙遥控小车设计方案
现在还是列出硬件的列表:按照实物图购买响应的模块组装成小车,L298N,电源模块,电池夹和18650电池两个,电源变压器、STM32F103C8T6单片机最小系统板、HC05串口蓝牙模块、小车底座。

2.准备一个串口通信的代码

我采用库函数开发,所以代码直接使用第一篇中的开源源码。

代码如下(示例):

#include "led.h"
#include "delay.h"
#include "key.h"
#include "sys.h"
#include "usart.h"
#include "usart2.h"

//串口实验 
//技术支持:daodanjishui 
 int main(void)
 { 
   		
 	u8 t;
	u8 len;	
  u8 len2;	
	delay_init();	    	 //延时函数初始化 
	NVIC_Configuration(); 	 //设置NVIC中断分组2:2位抢占优先级,2位响应优先级
	uart_init(9600);	 //串口初始化为9600
	
  uart2_init(9600);
 	//LED_Init(); //LED端口初始化
	//KEY_Init(); //初始化与按键连接的硬件接口
 	while(1)
	{ 
   
		if(USART_RX_STA&0x8000)
		{ 
   					   
			len=USART_RX_STA&0x3fff;//得到此次接收到的数据长度
			
			/* //因为我这里要把气象站的数据传回来,所以不能直接返回数据给气象站,否则可能出错 printf("电脑 send to串口1的数据为:\r\n"); for(t=0;t<len;t++) { USART_SendData(USART1, USART_RX_BUF[t]);//单片机通过串口1发送数据给电脑 while(USART_GetFlagStatus(USART1,USART_FLAG_TC)!=SET);//等待发送结束 //printf("\r\n发送成功\r\n");//插入换行 } printf("\r\n");//插入换行 */
			
			
			
			
      u2_printf("电脑 send to串口2的数据为:\r\n");		
			for(t=0;t<len;t++)
			{ 
   
				USART_SendData(USART2, USART_RX_BUF[t]);//将串口1收到的数据转发给串口2输出
				while(USART_GetFlagStatus(USART2,USART_FLAG_TC)!=SET);//等待发送结束
			}
			u2_printf("\r\n");//插入换行

			
			USART_RX_STA=0;
		} 
		
		
		
		
		if(USART2_RX_STA&0x8000)
		{ 
   					   
			len2=USART2_RX_STA&0x3fff;//得到此次接收到的数据长度
			
      u2_printf("电脑 send to串口2的数据为:\r\n");
			for(t=0;t<len2;t++)
			{ 
   
				USART_SendData(USART2, USART2_RX_BUF[t]);//单片机通过串口2给电脑发数据
				while(USART_GetFlagStatus(USART2,USART_FLAG_TC)!=SET);//等待发送结束
			}
			u2_printf("\r\n");//插入换行 
			
			
			
			
      //printf("电脑 send to串口1的数据为:\r\n");
      printf("\r\n");//作为指令响应的开头 
			for(t=0;t<len2;t++)
			{ 
   
				USART_SendData(USART1, USART2_RX_BUF[t]);//将串口2收到的数据转发给串口1输出
				while(USART_GetFlagStatus(USART1,USART_FLAG_TC)!=SET);//等待发送结束
			}			
			printf("\r\n");//插入换行
			
			USART2_RX_STA=0;
		} 
	}	 
 }


3.修改源码

因为智能小车不仅仅是设计到串口信息的收发,还涉及到指令的解析和车轮电机的执行。所以需要在原来代码的基础上加上:
(1)指令解析的代码如下

if(USART_RX_STA&0x8000)
		{ 
   					   
			len=USART_RX_STA&0x3fff;//得到此次接收到的数据长度
			//printf("电脑 send to串口1的数据为:\r\n");
			for(t=0;t<len;t++)// 这里要将电脑给串口发送的东西全部返回
			{ 
   
				USART_SendData(USART1, USART_RX_BUF[t]);//单片机通过串口1发送数据给电脑?
				while(USART_GetFlagStatus(USART1,USART_FLAG_TC)!=SET);//等待发送结束
			// printf("\r\n发送成功\r\n");//插入换行

			}
			printf("\r\n");//插入换行
			//在这里加入控制车的逻辑
			//p1=strstr((const char*)USART3_RX_BUF,(const char*)"ID0:");
					if(strstr((const char*)USART_RX_BUF,"FFF")!=NULL){ 
   
						flag=0;
					}else if(strstr((const char*)USART_RX_BUF,"BBB")!=NULL){ 
   
						flag=1;
					}else if(strstr((const char*)USART_RX_BUF,"LLL")!=NULL){ 
   
						flag=2;
					}else if(strstr((const char*)USART_RX_BUF,"RRR")!=NULL){ 
   
						flag=3;
					}else if(strstr((const char*)USART_RX_BUF,"SSS")!=NULL){ 
   
						flag=4;
					}else  flag=4;
				switch (flag)
				{ 
   
				 case 0: { 
   front(); u2_printf("FFF\r\n");printf("FFF\r\n");break;}//串口收到前进
				 case 1: { 
   back();u2_printf("BBB\r\n");printf("BBB\r\n");break;}
			   case 2: { 
   left();u2_printf("LLL\r\n");printf("LLL\r\n");break; }
				 case 3: { 
   right();u2_printf("RRR\r\n");printf("RRR\r\n");break;}
				 case 4: { 
   stop();u2_printf("SSS\r\n"); printf("SSS\r\n");break;}	
					 default: 
						 stop();
					   u2_printf("SSS\r\n");
					   break;
				}
			  //USART_RX_STA=0;
			
			//车控制结束
				
				
      u2_printf("单片机串口2发出的数据为:\r\n");
			for(t=0;t<len;t++)
			{ 
   
				USART_SendData(USART2, USART_RX_BUF[t]);//单片机通过串口2给电脑发送数据
				while(USART_GetFlagStatus(USART2,USART_FLAG_TC)!=SET);//等待发送结束
			}
			u2_printf("\r\n");	
		
			
		   USART_RX_STA=0;
		} 

(2)动作执行的代码如下

#include "output.h"
#include "delay.h"

void Motor_GPIO_Init(void)
{ 
   
GPIO_InitTypeDef Init_Instructure;
	RCC_APB2PeriphClockCmd(Motor_GPIO_CLK ,ENABLE );
	Init_Instructure.GPIO_Mode=GPIO_Mode_Out_PP;
	Init_Instructure.GPIO_Pin=Motor_PIN0;
	Init_Instructure.GPIO_Speed=GPIO_Speed_50MHz;
	GPIO_Init(Motor_PORT,&Init_Instructure );

	Init_Instructure.GPIO_Pin=Motor_PIN1;
	GPIO_Init(Motor_PORT,&Init_Instructure );
	
	Init_Instructure.GPIO_Pin=Motor_PIN2;
	GPIO_Init(Motor_PORT,&Init_Instructure );
	
	Init_Instructure.GPIO_Pin=Motor_PIN3;
	GPIO_Init(Motor_PORT,&Init_Instructure );
	
}

void back(void)
{ 
   
Motor_PIN0_0;
Motor_PIN1_1;
	
Motor_PIN2_1 ;
Motor_PIN3_0;
	
	delay_ms(1000);
	stop();


}

//PA0~3接到L298N的IN1~4

void front(void)
{ 
   
Motor_PIN0_1;//PA0置1
Motor_PIN1_0;//PA1置0 
Motor_PIN2_0;//PA2置0
Motor_PIN3_1;//PA3置1
	
	 delay_ms(1000);
	stop();
}

void left(void)
{ 
   

Motor_PIN0_1;
Motor_PIN1_0;
	
Motor_PIN2_0;
Motor_PIN3_0;
	
	delay_ms(200);
	stop();

}

void right(void)
{ 
   

	
Motor_PIN0_0;
Motor_PIN1_0;
	
Motor_PIN2_0;
Motor_PIN3_1;
	
  	delay_ms(200);
	  stop();

}


void stop(void)
{ 
   
Motor_PIN0_0;
Motor_PIN1_0;
	
Motor_PIN2_0;
Motor_PIN3_0;
}


三、运行与调试

  1. 根据源码接线在这里插入图片描述

  2. 在这里插入图片描述

  3. 按照实物图购买响应的模块组装成小车,L298N,电源模块,电池夹和18650电池两个,电源变压器、51单片机最小系统板、HC05串口蓝牙模块、小车底座

  4. 根据源码接线,烧录程序进单片机
    大概的接线关系是蓝牙模块接单片机的串口:蓝牙模块rxd接单片机PA9
    Txd接单片机PA10,L298N四个in管脚接单片机PA4,PA5,PA6,PA7四个管脚

  5. 安装手机安卓蓝牙调试助手

  6. 小车通电

  7. 打开手机蓝牙和蓝牙调试助手

  8. 搜索小车的蓝牙模块,链接上小车蓝牙

  9. 发送十六进制指令,因为小车接收指令 要加\r\n作为结束符号
    所以指令后面要加上十六进制0d 0a

比如FFF\r\n是前进,指令转化为十六进制是 4646460d0a
在这里插入图片描述

下面是后退:BBB\r\n 指令转化为十六进制是
在这里插入图片描述

下面是左转: LLL\r\n
在这里插入图片描述

最后是右转: RRR\r\n

现在重点介绍串口互发的调试过程:
1.启动小车电源,用USB转TTL线接到stm32单片机的串口2,用手机蓝牙调试助手控制小车前进,发送FFF,然后在串口2就会打印出FFF,再发送SSS,就打印SSS。说明串口1接收蓝牙指令和串口2发出指令,电脑收到串口2的信息再打印出来。
在这里插入图片描述

2.通过电脑调试助手给串口2发送BBB,发现手机蓝牙调试助手收到了BBB,说明了串口2接收串口1发出。串口1发出的信息传到手机蓝牙显示收到了BBB。
在这里插入图片描述

总结:通过1和2,我们通过双串口实现了互发来调试了智能小车。


总结

    通过上面运行与调试证明了小车运行状态良好,达到博文提出的要求。
    有些读者说:为什么不用手机app来控制智能小车而是要用蓝牙调试助手发指令去控制呢?其实我已经推出万能蓝牙遥控器,它可以安装在安卓手机上控制这个stm32智能小车,也能控制51智能小车和钢铁爱国者机关枪。支持三种方式控制:第一种是指令控制;第二种是方向键控制;第三种是重力传感器控制,配备蓝牙智能搜索和链接,指令反馈显示等功能,有需求的读者请访问我:最简单DIY基于Android系统的万能蓝牙设备智能遥控器

观看优酷视频地址:https://v.youku.com/v_show/id_XNDk2MDk5NDE5Ng==.html?spm=a2hbt.13141534.app.55!25!2555!255!25!25!255!25A

直接观看

stm32智能蓝牙小车控制

小车源码工程截图:
在这里插入图片描述

最后附上本博文代码下载地址:https://www.cirmall.com/circuit/21240/
直接跳转

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/183536.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

  • 深度强化学习——DQN「建议收藏」

    DQN(DeepQ-Learning)可谓是深度强化学习(DeepReinforcementLearning)的开山之作,是将深度学习与增强学习结合起来从而实现从感知(Perception)到动作(Action)的端对端(End-to-end)学习的一种全新的算法。

  • 拉格朗日三次插值公式_差值函数

    拉格朗日三次插值公式_差值函数第一部分:问题分析(1)实验题目:拉格朗日插值算法具体实验要求:要求学生运用拉格朗日插值算法通过给定的平面上的n个数据点,计算拉格朗日多项式Pn(x)的值,并将其作为实际函数f(x)的估计值。用matlab编写拉格朗日插值算法的代码,要求代码实现用户输入了数据点(xi,f(xi))、插值点之后,程序能够输出插值点对应的函数估值。(2)实验目的:让同学们进一步掌握拉格朗日插值算法的原理以及运算过程,并且通过matlab编程培养实际的上机操作能力和代码能力。第二部分:数学原理要估计任一点..

    2022年10月31日
  • office2013产品密钥_office365激活密钥

    office2013产品密钥_office365激活密钥HV7BJ-R6GCT-VHBXD-YH4FD-GTH2T87XPX-M3D6G-W4D39-VKVKR-DB8C7HM7R6-FP6QB-XTDC3-MT442-FVPKMXJBYM-62WK4-RCT9Y-XG3HQ-M2CMKHMYY4-TR62Q-9TT76-BDBHK-WPRPTHV7BJ-R6GCT-VHBXD-YH4FD-GTH2Thttp://zhida…

  • navicat premium15激活码(JetBrains全家桶)

    (navicat premium15激活码)最近有小伙伴私信我,问我这边有没有免费的intellijIdea的激活码,然后我将全栈君台教程分享给他了。激活成功之后他一直表示感谢,哈哈~IntelliJ2021最新激活注册码,破解教程可免费永久激活,亲测有效,下面是详细链接哦~https://javaforall.cn/100143.htmlS3…

  • 关于 UART 和 USART 的区别

    关于 UART 和 USART 的区别UART(universalasynchronousreceiverandtransmitter)通用异步收发器,信号包含TX,RX USART(universalsynchronousasynchronousreceiverandtransmitter)通用同步异步收发器,信号包含TX,RX,CK 区别:USART同时支持同步模式/异步模式,支持同步模式时需要同步时钟信USART_CK。UART只支持异步模式。 相同:在US…

  • 集合转数组的方法_数组的定义方式

    集合转数组的方法_数组的定义方式数组转集合在java中的数组有两种情况,一种是存放基本数据类型的数组,一种是存放对象类型的数组。对于存放对象类型的数组,直接使用Arrays.asList方法即可对于存放基本数据类型的,如果我们单纯使用Arrays.toList的方法去转换,只会得到对象类型为int[]的集合。这样子每一个元素都是一个基本数据类型数组的对象,而不是我们要存放的数据。publicstaticvoidmain([]args){ int[]a=newint[10]; for(inti=0;i<a.

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号