基于STM32的蓝牙遥控避障小车

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

文章目录

  • 前言
  • 一、组成部分及功能介绍
  • 二、代码实例
    • 1.main函数
    • 2.定时器初始化
    • 3.串口部分
    • 4.超声波部分
    • 5.舵机
  • 三、实物效果
  • 总结

前言

    这是笔者第一次尝试在CSDN这个平台上编写文章,主要是想借此来记录一下自己做过的一些小项目,算是为生活添加乐趣叭~(^&^)

 本文介绍的是基于STM32的蓝牙遥控避障小车,其主要实现两个功能,分别为遥控模式以及自主避障模式。                         基于STM32的蓝牙遥控避障小车


提示:以下是本篇文章正文内容,下面案例可供参考

一、组成部件及功能介绍

1.采用STM32F103系列为主控芯片

基于STM32的蓝牙遥控避障小车

2.采用C-SR04超声波模块避障。

基于STM32的蓝牙遥控避障小车

  1. SR04超声波测距模块可提供约2cm到400厘米的非接触式距离感测功能,测距精度可达高到3毫米;模块包括超声波发射器,接收器与控制电路像智能小车的测距以及转向,或是一些项目中,常常会用到。智能小车测距可以及时发现前方的障碍物,使智能小车可以及时转向,避开障碍物。给超声波模块接入电源和地给脉冲触发引脚(trig)输入一个长为20us的高电平方波输入方波后,模块会自动发射8个40KHz的声波,与此同时回波引脚(echo)端的电平会由0变为1;当超声波返回被模块接收到时,回波引脚端的电平会由1变为0;(此时应该停止定时器计数),定时器记下的这个时间即为超声波由发射到返回的总时长根据声音中的速度为344米/秒,即可计算出所测的距离。
  2. 基于STM32的蓝牙遥控避障小车

 在一些初始化函数调用后,对Echo的引脚进行测量。倘若改引脚变为高,则是开始推测。当它变成0的时候,则是探测结束。之后对于时间进行计算便可以得到距离。

3.采用HC-05蓝牙模块进行远程遥控控制小车的行进方向。

基于STM32的蓝牙遥控避障小车

此模块实现了无线电远距离控制小车的停启、方向行驶的功能,在整个小车系统中起到不可忽视的作用。

无线遥控工作原理

此蓝牙的型号是HC-05

工作简化图如下:

基于STM32的蓝牙遥控避障小车

HC-05蓝牙串口通讯模块具有两种工作模式:命令响应工作模式(AT)和自动连接工作模式。在自动连接工作模式下模块又可分为主(Master)、从(Slave)和回环(Loopback)三种工作角色。当模块处于自动连接工作模式时,将自动根据事先设定的方式连接的数据传输;当模块处于命令响应工作模式时能执行AT命令,用户可向模块发送各种AT 指令,为模块设定控制参数或发布控制命令。

模块上电,未配对情况下就是AT模式,波特率为模块本身的波特率,默认:9600,发送一次AT指令时需要置高一次PIO11;

PIO11 置高电平后,再给模块上电,此时模块进入AT 模式,波特率固定为:38400,可以直接发送AT指令。

在蓝牙模块中有一个小按键,按一下就置高一次PIO11。也就是说,第一种方法需要每发送一次AT指令按一次;而第二种方式是长按的过程中上电,之后就无需再管了,直接发送AT命令即可。

在蓝牙模块上有灯,当灯快闪的时候,就是自动连接工作模式;当灯慢闪的时候,就是命令响应工作模式。

配置好相应的PWM后,直接通过手机蓝牙与他相接,通过相应的软件进行调节发送指令,单片机通过串口会得到指令,产生相应的动作。

HC-05的状态现象很明显,操作也很方便。

4.采用SG90舵机辅助超声波模块进行转向避障

 基于STM32的蓝牙遥控避障小车基于STM32的蓝牙遥控避障小车

基于STM32的蓝牙遥控避障小车

选择使用SG90舵机,其性能强且不易于损坏。而且舵机本身十分轻巧方便组装,能够实现0~180度范围的转向。

舵机是一种根据输入PWM信号占空比来控制输出角度的装置输入PWM信号要求:周期为20ms,高电平宽度为0.5ms~2.5ms。通过输入不同占空比的PWM来控制舵机的不同转向角度,从而带动超声波模块旋转以实现避障功能。

二、代码实列

1.main函数

    主函数里面其实主要就做了一个事情,那就是在while(1)中不断判断串口传来的数据是多少,小车再通过传过来的数据来具体做出对应的判断

#include "stm32f10x.h"                  // Device header
#include "oled.h"
#include "timer.h"
#include "DELAY.h"
#include "YunTai.h"
#include "Dianji.h"
#include "CaoSenBo.h"
#include "USART.h"

int g_USART1_FLAG = 0; //蓝牙标志位
int Mode = 0; //模式标志位

extern int dis;
int main(void)
{

	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);   
	
	Dianji_Init();
	OLED_Init();
	OLED_Clear();
	//SR04_GPIO_Init(); // Trign PC10
	
	ultrasonic_Init();
	
	Init_TIM5_PWM(19999 ,71);//云台
	Init_TIM8_PWM(899,7);//电机
	uart_init(115200); //蓝牙
	TIME3_Init();//超声波
	//TIM2_Cap_Init(0XFFFF,72-1);//以1MHZ的频率计数
	SERVO_SetAng(90);
	
	while(1)
	{
		
		if(Mode == 1) //避障模式
		{
				HC_SR04_Avoid();
				OLED_ShowNum(1,1,dis,3);			

		}
	
		if(Mode == 2)//遥控模式
		{
			
			SERVO_SetAng(90);
			
			if(g_USART1_FLAG == 1)
			{
				run(); //前进
				g_USART1_FLAG = 0;
			}
			if(g_USART1_FLAG == 2)
			{
				Retreat(); //后退
				g_USART1_FLAG = 0;

			}
			if(g_USART1_FLAG == 3)
			{
				go_left(); //左转
				
				g_USART1_FLAG = 0;

			}
			if(g_USART1_FLAG == 4)
			{
				go_right(); //右转
				
				g_USART1_FLAG = 0;

			}
			if(g_USART1_FLAG ==5)
			{
				Stop(); //停车
				g_USART1_FLAG = 0;
			}

		}
	

	}
}

2.定时器初始化

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


void Init_TIM5_PWM(u16 arr ,u16 psc) //云台即舵机
{
	
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
	GPIO_InitTypeDef GPIO_InitStructure;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOA, &GPIO_InitStructure);

	
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM5, ENABLE);
	
	TIM_InternalClockConfig(TIM5); 
	
	TIM_TimeBaseInitTypeDef TIM_TimrBaseInitStructure;
	
	TIM_TimrBaseInitStructure.TIM_ClockDivision =  TIM_CKD_DIV1; 
	TIM_TimrBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up ; 
	

	TIM_TimrBaseInitStructure.TIM_Period = arr ; 
	TIM_TimrBaseInitStructure.TIM_Prescaler = psc; 
	
	TIM_TimrBaseInitStructure.TIM_RepetitionCounter = 0 ; 
	
	TIM_TimeBaseInit(TIM5, &TIM_TimrBaseInitStructure); 
	
	TIM_ClearFlag(TIM5, TIM_FLAG_Update); 
	
	TIM_OCInitTypeDef TIM_OCInitStructure;
	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(TIM5, &TIM_OCInitStructure);
	//TIM_OC2Init(TIM2, &TIM_OCInitStructure);

	
	TIM_Cmd(TIM5, ENABLE);
	
}

void Init_TIM8_PWM(u16 arr, u16 psc) //电机
{
	GPIO_InitTypeDef GPIO_InitStructure;
	TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
	TIM_OCInitTypeDef TIM_OCInitStructure;

	RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM8, ENABLE);  
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);

	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9 | GPIO_Pin_8 | GPIO_Pin_7 | GPIO_Pin_6; 
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;									 
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOC, &GPIO_InitStructure);

	TIM_TimeBaseStructure.TIM_Period = arr;						
	TIM_TimeBaseStructure.TIM_Prescaler = psc;					
	TIM_TimeBaseStructure.TIM_ClockDivision = 0;				
	TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; 
	TIM_TimeBaseInit(TIM8, &TIM_TimeBaseStructure);				

	TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;			  
	TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; 
	TIM_OCInitStructure.TIM_Pulse = 0;							  
	TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;	  
	TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Enable;
	TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_High;
	TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Set;
	TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCIdleState_Reset;
	TIM_OC1Init(TIM8, &TIM_OCInitStructure);		  
	TIM_OC1PreloadConfig(TIM8, TIM_OCPreload_Enable); // CH1 ----A PC6
	TIM_OC2Init(TIM8, &TIM_OCInitStructure);
	TIM_OC2PreloadConfig(TIM8, TIM_OCPreload_Enable); // CH2 ----B PC7
	TIM_OC3Init(TIM8, &TIM_OCInitStructure);
	TIM_OC3PreloadConfig(TIM8, TIM_OCPreload_Enable); // CH3 ----C PC8
	TIM_OC4Init(TIM8, &TIM_OCInitStructure);
	TIM_OC4PreloadConfig(TIM8, TIM_OCPreload_Enable); // CH4 ----D PC9
	TIM_CtrlPWMOutputs(TIM8, ENABLE);				  
	TIM_ARRPreloadConfig(TIM8, ENABLE);				  

	TIM_Cmd(TIM8, ENABLE); 

	TIM_SetCompare1(TIM8, 0); // BL	
	TIM_SetCompare2(TIM8, 0); // FL	
	TIM_SetCompare3(TIM8, 0); // FR	
	TIM_SetCompare4(TIM8, 0); // BR	
}

void TIME3_Init(void) //超声波
{
	NVIC_InitTypeDef NVIC_InitStructure;
	TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
	
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);
	
	NVIC_InitStructure.NVIC_IRQChannel=TIM3_IRQn;
	NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=1;
	NVIC_InitStructure.NVIC_IRQChannelSubPriority=0;
	NVIC_Init(&NVIC_InitStructure);
	
	TIM_TimeBaseInitStructure.TIM_Period=99;    //ARR                   
	TIM_TimeBaseInitStructure.TIM_Prescaler=17;  //PSC                  
	TIM_TimeBaseInitStructure.TIM_CounterMode=TIM_CounterMode_Up;
	TIM_TimeBaseInitStructure.TIM_ClockDivision=1;
	TIM_TimeBaseInitStructure.TIM_RepetitionCounter=1;
	TIM_TimeBaseInit(TIM3,&TIM_TimeBaseInitStructure);
	
  TIM_ITConfig(TIM3,TIM_IT_Update,ENABLE);                       
}


//下面注释的部分是我尝试用定时器输入捕获的方式来运行超声波
//结果发现效果并不理想就放弃了


//TIM_ICInitTypeDef  TIM2_ICInitStructure;

//void TIM2_Cap_Init(u16 arr,u16 psc) //超声波
//{	 
//	GPIO_InitTypeDef GPIO_InitStructure;
//	TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
//   	NVIC_InitTypeDef NVIC_InitStructure;

//	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);	
// 	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);  
//	
//	GPIO_InitStructure.GPIO_Pin  = GPIO_Pin_2;  
//	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD;  
//	GPIO_Init(GPIOA, &GPIO_InitStructure);
//	GPIO_ResetBits(GPIOA,GPIO_Pin_2);						 
//	
//	 
//	TIM_TimeBaseStructure.TIM_Period = arr; 
//	TIM_TimeBaseStructure.TIM_Prescaler =psc; 	  
//	TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; 
//	TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;  
//	TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure); 
//	
//	TIM2_ICInitStructure.TIM_Channel = TIM_Channel_3; 
//  	TIM2_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising;	
//  	TIM2_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI; 
//  	TIM2_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;	
//  	TIM2_ICInitStructure.TIM_ICFilter = 0x00;
//  	TIM_ICInit(TIM2, &TIM2_ICInitStructure);
//	
//	
//	NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn ;  
//	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;  
//	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;  
//	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; 
//	NVIC_Init(&NVIC_InitStructure);  
//	
//	TIM_ITConfig(TIM2,TIM_IT_Update|TIM_IT_CC3,ENABLE);	
//	
//   	TIM_Cmd(TIM2,ENABLE ); 	

//}

//u8  TIM5CH1_CAPTURE_STA=0;		    				
//u16	TIM5CH1_CAPTURE_VAL;	
// 
//	 
//void TIM2_IRQHandler(void)
//{ 

// 	if((TIM5CH1_CAPTURE_STA&0X80)==0)
//	{	  
//		if (TIM_GetITStatus(TIM2, TIM_IT_Update) != RESET)
//		 
//		{	    
//			if(TIM5CH1_CAPTURE_STA&0X40)
//			{
//				if((TIM5CH1_CAPTURE_STA&0X3F)==0X3F)
//				{
//					TIM5CH1_CAPTURE_STA|=0X80;
//					TIM5CH1_CAPTURE_VAL=0XFFFF;
//				}else TIM5CH1_CAPTURE_STA++;
//			}	 
//		}
//	if (TIM_GetITStatus(TIM2, TIM_IT_CC3) != RESET)
//		{	
//			if(TIM5CH1_CAPTURE_STA&0X40)				
//			{	  			
//				TIM5CH1_CAPTURE_STA|=0X80;		
//				TIM5CH1_CAPTURE_VAL=TIM_GetCapture3(TIM2);
//		   		TIM_OC3PolarityConfig(TIM2,TIM_ICPolarity_Rising); 
//			}else  								
//			{
//				TIM5CH1_CAPTURE_STA=0;			
//				TIM5CH1_CAPTURE_VAL=0;
//	 			TIM_SetCounter(TIM2,0);
//				TIM5CH1_CAPTURE_STA|=0X40;		
//		   		TIM_OC3PolarityConfig(TIM2,TIM_ICPolarity_Falling);		
//			}		    
//		}			     	    					   
// 	}
// 
//    TIM_ClearITPendingBit(TIM2, TIM_IT_CC3|TIM_IT_Update); 
// 
//}


3.串口部分

串口部分只需要再其数据接收部分添加对接收信号的判断并赋值就行了,其他的程序可以参考引用正点原子关于串口部分的模板

void USART1_IRQHandler(void)                	//串口1中断服务程序
	{
	u8 Res;
#if SYSTEM_SUPPORT_OS 		//如果SYSTEM_SUPPORT_OS为真,则需要支持OS
	OSIntEnter();        
#endif
	if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)  //接收中断(数据必须是0xod 0xoa结尾)

		{
		Res =USART_ReceiveData(USART1);	//读取接收到的数据
		
		if(Res == 'A') g_USART1_FLAG = 1;//前进
		if(Res == 'B') g_USART1_FLAG = 2;//后退
		if(Res == 'C') g_USART1_FLAG = 3;//左
		if(Res == 'D') g_USART1_FLAG = 4;//右
		if(Res == 'E') g_USART1_FLAG = 5;//停
		if(Res == 'F') Mode = 1;//打开避障模式
		if(Res == 'G') Mode = 2;//打开遥控模式
		
			
		if((USART_RX_STA&0x8000)==0)//接收未完成
			{
			if(USART_RX_STA&0x4000)//接收到了0x0d
				{
				if(Res!=0x0a)USART_RX_STA=0;//接收错误重新开始
				else USART_RX_STA|=0x8000;	//接收完成了
				}
			else //还没接收到0X0D
				{	
				if(Res==0x0d)USART_RX_STA|=0x4000;
				else
					{
					USART_RX_BUF[USART_RX_STA&0X3FFF]=Res ;
					USART_RX_STA++;
					if(USART_RX_STA>(USART_REC_LEN-1))USART_RX_STA=0;//如果SYSTEM_SUPPORT_OS为真,则需要支持OS
					}		 
				}
			}   		 
     } 

4.超声波部分

#include "stm32f10x.h"                  // Device header
#include "CaoSenBo.h"
#include "timer.h"
#include "oled.h"
#include "Dianji.h"
#include "YunTai.h"
#include "DELAY.h"


int time = 0;
unsigned int delay_u;;
int Count = 0;
int Distance0 = 0;
int Distance1 = 0;

int dis = 0;
 

//extern u8  TIM5CH1_CAPTURE_STA;		//??????		    				
//extern u16	TIM5CH1_CAPTURE_VAL;	//?????	


//void SR04_GPIO_Init(void)
//{
//  GPIO_InitTypeDef GPIO_InitStructure;
//	
//	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC,ENABLE);
//	GPIO_InitStructure.GPIO_Pin=GPIO_Pin_12; //trio
//	GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;
//	GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
//	GPIO_Init(GPIOC,&GPIO_InitStructure);
//	
//	GPIO_SetBits(GPIOC,GPIO_Pin_0);
//}

//int SR04_Distance(void)
//{
//			Trign = 0;
//			Delay(13);
//			Trign = 1;
//			
//			if(TIM5CH1_CAPTURE_STA&0X80)
//			{
//				time=TIM5CH1_CAPTURE_STA&0X3F;
//				time*=65536; 
//				time+=TIM5CH1_CAPTURE_VAL; 
//				Distance = time*0.034/2;
//				//printf("HIGH:%d us\r\n",time);
//				TIM5CH1_CAPTURE_STA=0;
//			}
//			return Distance;
//}

//上面注释掉的这段是原本用输入捕获方式来运行的程序


void ultrasonic_Init(void)
{
  GPIO_InitTypeDef GPIO_InitStructure;
	
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC,ENABLE);
	
	GPIO_InitStructure.GPIO_Pin=GPIO_Pin_12; //trio
	GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;
	GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
	GPIO_Init(GPIOC,&GPIO_InitStructure);
	
	GPIO_InitStructure.GPIO_Pin=GPIO_Pin_10;  //echo
	GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IN_FLOATING;
	GPIO_Init(GPIOC,&GPIO_InitStructure);
	
	GPIO_ResetBits(GPIOB,GPIO_Pin_12);
}

int GetDistance(void)
{
	int i;
	
  for(i=5;i>0;i--)                                    //循环6次采集距离
	{
		GPIO_ResetBits(GPIOC,GPIO_Pin_12);
		GPIO_SetBits(GPIOC,GPIO_Pin_12);                     //拉高trig
		Delay(13);                                       //保持10us
		GPIO_ResetBits(GPIOC,GPIO_Pin_12);                   //拉低trig
		while(GPIO_ReadInputDataBit(GPIOC,GPIO_Pin_10)==0);  //等待echo管脚输出高电平后打开TIM3计时
		TIM_Cmd(TIM3,ENABLE);                               //打开TIM3,捕获时间
		while(GPIO_ReadInputDataBit(GPIOC,GPIO_Pin_10)==1);  //等待声音信号结束
		TIM_Cmd(TIM3,DISABLE);                              //关闭TIM3
		Count=TIM_GetCounter(TIM3);                         //获取TIM3的该次计数值,即读取TIM3寄存器CNT
		Distance0=calculer(Count);	                        //调用函数计算距离
		Distance1=Distance1+Distance0;                      //距离的累加,用于后续计算平均距离                                
	}	
		
	Distance1=Distance1/6;                                //平均距离
	                                
	return Distance1;
}

u32 calculer(u32 count)
{
  u32 Distance;
	Distance=((float)(count+100*time)*0.425)/100;   //距离计算公式
	time=0;                                     //清空TIM3的中断次数
	
	return Distance;
	
}

void TIM3_IRQHandler(void)
{
  if(TIM_GetFlagStatus(TIM3,TIM_FLAG_Update)!=RESET)
	{
	  time++;                                    //中断标志自加1
		TIM_ClearFlag(TIM3,TIM_FLAG_Update);	     //清楚中断标志位
	}
}

void HC_SR04_Avoid(void) //根据距离来进行转向判断
{
	dis = GetDistance();
	if(dis>60)
	{
		run();
	}
	else if(dis<40)
	{
		Stop();
		Delay_ms(1000);
		SERVO_SetAng(180); //此为舵机角度函数
		Delay_ms(1000);
		dis = GetDistance();
		if(dis>=60)
		{
			go_left();
			Delay_ms(625);
			SERVO_SetAng(90);
			Delay_ms(20);
			run();
		}
		else if(dis<60)
		{
			SERVO_SetAng(0);
			Delay_ms(20);
			go_right();
			Delay_ms(625);
			SERVO_SetAng(90);
			Delay_ms(20);
			run();
		}
	}
}

5.舵机

#include "stm32f10x.h"                  // Device header

void SERVO_SetAng(float Angle) 
{
	TIM_SetCompare4(TIM5, Angle/180*2000+500);   
}

6.电机转向

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


void Dianji_Init(void)//电机初始化
{
	GPIO_InitTypeDef GPIO_InitStructure;
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); //使能GPIOB时钟
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;             //端口配置
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;      //推挽输出
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;     // 50Mhz速度
    GPIO_Init(GPIOB, &GPIO_InitStructure);
		RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB | RCC_APB2Periph_GPIOA | RCC_APB2Periph_AFIO, ENABLE);    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;         //端口配置
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;  //推挽输出
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; // 50Mhz速度
    GPIO_Init(GPIOB, &GPIO_InitStructure);
    GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable, ENABLE);
	
}

void run(void)
{
		GPIO_ResetBits(GPIOB, GPIO_Pin_2); //右轮
	  GPIO_SetBits(GPIOB, GPIO_Pin_3); //左轮

		TIM_SetCompare1(TIM8, 600); // 右	
	  TIM_SetCompare2(TIM8, 610); // 左	
	
}

	void go_left(void)
	{
			GPIO_ResetBits(GPIOB, GPIO_Pin_2); //右轮
		  GPIO_ResetBits(GPIOB, GPIO_Pin_3); //左轮

		  TIM_SetCompare1(TIM8, 500); // 右	
		  TIM_SetCompare2(TIM8, 500); // 左	
	}

	void go_right(void)
	{
			GPIO_SetBits(GPIOB, GPIO_Pin_2); //右轮
		  GPIO_SetBits(GPIOB, GPIO_Pin_3);   //左轮

		  TIM_SetCompare1(TIM8, 500); // 右	
		  TIM_SetCompare2(TIM8, 500); // 左	
	}

	void Stop(void)
{
		GPIO_ResetBits(GPIOB, GPIO_Pin_2); //右轮
	  GPIO_SetBits(GPIOB, GPIO_Pin_3); //左轮

		TIM_SetCompare1(TIM8, 0); // 右	
	  TIM_SetCompare2(TIM8, 0); // 左	
	
}

void Retreat(void) //后退
{
		GPIO_SetBits(GPIOB, GPIO_Pin_2); //右轮
	  GPIO_ResetBits(GPIOB, GPIO_Pin_3); //左轮

		TIM_SetCompare1(TIM8, 545); // 右	
	  TIM_SetCompare2(TIM8, 550); // 左	
	
}


以上便是代码部分的内容了(^^)

三、实物展示


 基于STM32的蓝牙遥控避障小车

 基于STM32的蓝牙遥控避障小车

注:这里用来连接蓝牙的手机软件随便在网上就可以找到的。

总结

     以上便是这篇文章的全部内容啦!呼~想不到还是有些累的(**)

笔者在这里也是想对看到这篇文章的朋友说几句话,或许你现在正因为各种程序呀电路呀等等等等。。问题所困扰,请一定不要着急,慢慢来仔细想,冷静面对问题才能将其迎刃而解哦!!

收工!文章来源地址https://www.toymoban.com/news/detail-415314.html

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

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

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

相关文章

  • STM32蓝牙遥控小车

    前言 一、STM32小车效果图 二、硬件设计 1.电机驱动对比 2.蓝牙模块 3.电机 三、小车程序 总结 STM32小车一直以来都还是众多STM32爱好者的入门设计,门槛不高,值得玩一下。         这是刚开始弄的印度风的小车,丑不拉几。         这个小车结构是:STM32C8T6为主控,1

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

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

    2024年02月04日
    浏览(42)
  • stm32蓝牙遥控小车(hal库)

     我使用的板子是stm32f103rct6,这里我们使用串口1,选择异步模式,注意波特率的选择,一般是9600或者115200,如果波特率选择不对的话是不能进行通讯的(我小车怎么也动不了搞了好久最后发现是波特率选错了,气死了),我用的蓝牙模块是HC-05(ps:我的stm32f103rct6的板子的串

    2024年02月06日
    浏览(34)
  • 100、基于STM32单片机自动跟随小车 红外遥控控制小车避障模式 跟随模式设计(程序+原理图+PCB源文件+流程图+硬件设计资料+元器件清单等)

    智能小车通过各种感应器获得外部环境信息和内部运动状态,实现在复杂环境背景下的自主运动,从而完成具有特定功能的机器人系统。而随着智能化电器时代的到来,它们在为人们提供的舒适的生活环境的同时,也提高了制造智能化电器对于人才要求的门槛。智能小车是集

    2024年02月15日
    浏览(62)
  • 5.39 综合案例2.0 - STM32蓝牙遥控小车1(手机APP遥控)

    APP遥控) 点 击 跳 转 点击跳转HaaS506官方最新案例 用STM32单片机做了一辆蓝牙控制的麦轮小车,分享一下小车的原理和制作过程。 控制部分分为手机APP,语音模块控制,Haas506开发板三种。 本文介绍手机APP的控制的方法以及小车的制作。 器件说明 器件 数量 说明 STM32F103C8T6单片

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

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

    2024年01月20日
    浏览(31)
  • 5.39 综合案例2.0 - STM32蓝牙遥控小车2(语音控制)

    点 击 跳 转 点击跳转HaaS506官方最新案例 用语音识别当stm32智能车的遥控器,还能这样玩 用STM32单片机做了一辆蓝牙控制的麦轮小车,分享一下小车的原理和制作过程。 控制部分分为手机APP,语音模块控制,Haas506开发板三种。 本文介绍语音模块控制的方法以及小车的制作。

    2024年02月16日
    浏览(34)
  • 5.39 综合案例2.0 - STM32蓝牙遥控小车4(体感控制)

    点 击 跳 转 点击跳转HaaS506官方最新案例 用STM32单片机做了一辆蓝牙控制的麦轮小车,分享一下小车的原理和制作过程。 控制部分分为手机APP,语音模块控制,Haas506开发板(遥感 + 体感)三种。 本文介绍Haas506(体感)控制的方法以及小车的制作。 器件说明 器件 数量 说明 STM32F

    2023年04月11日
    浏览(25)
  • 《基于STM32的红外避障小车》

    本文主要讲解基于 STM32的红外避障小车的实现(标准库) 基于 stm32 实现的一个简单智能避障小车,具有“直行”、转弯、“避障”的功能。 直行、转弯:基于 stm32 的通用定时器TIM3输出 PWM 方波信号实现 避障:使用到 stm32 的外部中断以及通用定时器(使用红外中断), 代码

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

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

    2024年02月06日
    浏览(45)

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

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

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

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

二维码1

领取红包

二维码2

领红包