使用STM32 HAL库实现蓝牙遥控小车

一.cubemx配置

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

                                                       

 打开串口1的中断,中断优先级根据自己的实际需求选择。

 这样就配置完了,连线的时候,注意蓝牙的RX连接PA9,TX连接PA10,不要连错了。

二.代码部分

代码直接从keil5里复制粘贴中文注释部分会乱码,过两天我再给修改一下,主函数循环前不要忘了开启串口1的接收中断。

HAL_UART_Receive_IT(&huart1,(uint8_t *)&USART1_NewData,1);

 Car_Move.c

#include "tim.h"
#include "Car_Move.h"
#include "gpio.h"


void Motor1Forward(int16_t speed)
{
	HAL_TIM_PWM_Start(&htim8, TIM_CHANNEL_1);
  
  HAL_GPIO_WritePin(GPIOB, GPIO_PIN_9, GPIO_PIN_SET);
  HAL_GPIO_WritePin(GPIOB, GPIO_PIN_8, GPIO_PIN_RESET);

  __HAL_TIM_SET_COMPARE(&htim8, TIM_CHANNEL_1, speed);
}

void Motor2Forward(int16_t speed)
{
	HAL_TIM_PWM_Start(&htim8, TIM_CHANNEL_2);
	
	HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4,GPIO_PIN_RESET);
	HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5,GPIO_PIN_SET);
	
	__HAL_TIM_SET_COMPARE(&htim8, TIM_CHANNEL_2, speed);
}
void Motor3Forward(int16_t speed)
{
	HAL_TIM_PWM_Start(&htim8, TIM_CHANNEL_3);
	
	HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13,GPIO_PIN_RESET);
	HAL_GPIO_WritePin(GPIOC, GPIO_PIN_12,GPIO_PIN_SET);
	
	__HAL_TIM_SET_COMPARE(&htim8, TIM_CHANNEL_3, speed);
}
void Motor4Forward(int16_t speed)
{
	HAL_TIM_PWM_Start(&htim8, TIM_CHANNEL_4);
	
	HAL_GPIO_WritePin(GPIOB, GPIO_PIN_0,GPIO_PIN_RESET);
	HAL_GPIO_WritePin(GPIOB, GPIO_PIN_1,GPIO_PIN_SET);
	
	__HAL_TIM_SET_COMPARE(&htim8, TIM_CHANNEL_4, speed);
}
/************************************************/
void Motor1Stop(void)
{
	HAL_GPIO_WritePin(GPIOB, GPIO_PIN_8,0);
	HAL_GPIO_WritePin(GPIOB, GPIO_PIN_9,0);
}
void Motor2Stop(void)
{
	HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4,0);
	HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5,0);
}
void Motor3Stop(void)
{
	HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13,0);
	HAL_GPIO_WritePin(GPIOC, GPIO_PIN_12,0);
}
void Motor4Stop(void)
{
	HAL_GPIO_WritePin(GPIOB, GPIO_PIN_0,0);
	HAL_GPIO_WritePin(GPIOB, GPIO_PIN_1,0);
}
/*********************************************/
void Motor1Back(int16_t speed)
{
	HAL_TIM_PWM_Start(&htim8, TIM_CHANNEL_1);
  
  HAL_GPIO_WritePin(GPIOB, GPIO_PIN_8, GPIO_PIN_SET);
  HAL_GPIO_WritePin(GPIOB, GPIO_PIN_9, GPIO_PIN_RESET);

  __HAL_TIM_SET_COMPARE(&htim8, TIM_CHANNEL_1, speed);
}
void Motor2Back(int16_t speed)
{
	HAL_TIM_PWM_Start(&htim8, TIM_CHANNEL_2);
	
	HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5,GPIO_PIN_RESET);
	HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4,GPIO_PIN_SET);
	
	__HAL_TIM_SET_COMPARE(&htim8, TIM_CHANNEL_2, speed);
}
void Motor3Back(int16_t speed)
{
	HAL_TIM_PWM_Start(&htim8, TIM_CHANNEL_3);
	
	HAL_GPIO_WritePin(GPIOC, GPIO_PIN_12,GPIO_PIN_RESET);
	HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13,GPIO_PIN_SET);
	
	__HAL_TIM_SET_COMPARE(&htim8, TIM_CHANNEL_3, speed);
}
void Motor4Back(int16_t speed)
{
	HAL_TIM_PWM_Start(&htim8, TIM_CHANNEL_4);
	
	HAL_GPIO_WritePin(GPIOB, GPIO_PIN_1,GPIO_PIN_RESET);
	HAL_GPIO_WritePin(GPIOB, GPIO_PIN_0,GPIO_PIN_SET);
	
	__HAL_TIM_SET_COMPARE(&htim8, TIM_CHANNEL_4, speed);
}
/*********************************************/
void Move_Forward(uint16_t speed)
{	
	Motor1Forward(speed);
	Motor2Forward(speed);
	Motor3Forward(speed);
	Motor4Forward(speed);	 				
}
void Move_Back(uint16_t speed)
{
	Motor1Back(speed);
	Motor2Back(speed);
	Motor3Back(speed);
	Motor4Back(speed);	 				
}
void TurnLeft(uint16_t speed)
{
	Motor1Back(speed);	
	Motor2Forward(speed);
	Motor3Back(speed);	
	Motor4Forward(speed);					
}
void TurnRight(uint16_t speed)
{
	Motor1Forward(speed);
	Motor2Back(speed);
	Motor3Forward(speed);
	Motor4Back(speed); 				
}	
void Move_Stop(void)
{
	Motor1Stop();
	Motor2Stop();
	Motor3Stop();
	Motor4Stop(); 				
}
void Move_Right(uint16_t speed)
{
	Motor1Forward(speed);
	Motor2Back(speed);
	Motor3Back(speed);
	Motor4Forward(speed); 
}
void Move_Left(uint16_t speed)
{
	Motor1Back(speed);
	Motor2Forward(speed);
	Motor3Forward(speed);
	Motor4Back(speed); 		
}
void Move_UpRight(uint16_t speed)
{
	Motor1Forward(speed);
	
	Motor4Forward(speed);		
}
void Move_UpLeft(int16_t speed)
{
	Motor2Forward(speed);
	
	Motor3Forward(speed);		
}
void Move_DownLeft(int16_t speed)
{
	Motor1Back(speed);
	
	Motor4Back(speed);		
}
void Move_DownRight(int16_t speed)
{
	Motor2Back(speed);
	
	Motor3Back(speed);		
}

 

 Car_Move.h

#ifndef __car_move_h__
#define __car_move_h__

void Motor1Forward(int16_t speed);
void Motor2Forward(int16_t speed);
void Motor3Forward(int16_t speed);
void Motor4Forward(int16_t speed);

void Motor1Stop(void);
void Motor2Stop(void);
void Motor3Stop(void);
void Motor4Stop(void);

void Motor1Back(int16_t speed);
void Motor2Back(int16_t speed);
void Motor3Back(int16_t speed);
void Motor4Back(int16_t speed);

void Move_Forward(uint16_t speed);
void Move_Back(uint16_t speed);
void TurnLeft(uint16_t speed); //ÆÕͨÂÖ×Ó
void TurnRight(uint16_t speed); //ÆÕͨÂÖ×Ó
void Move_Stop(void);
/*Âó¿ËÄÉÄ·ÂÖ*/
void Move_Right(uint16_t speed);
void Move_Left(uint16_t speed);
void Move_UpRight(uint16_t speed);
void Move_UpLeft(int16_t speed);
void Move_DownLeft(int16_t speed);
void Move_DownRight(int16_t speed);


#endif

 bluetooth.c

#include "bluetooth.h"
#include "control.h"


uint8_t USART1_RX_BUF[USART1_REC_LEN];//接收缓冲,最大USART1_REC_LEN个字节
uint16_t USART1_RX_STA=0;//接收状态标记//bit15:接收完成标志,bit14~0:接收到的有效数字
uint8_t USART1_NewData;//当前串口中断接收的1个字节数据缓存

void  HAL_UART_RxCpltCallback(UART_HandleTypeDef  *huart)//串口中断回调函数
{
    if(huart ==&huart1)
    {
        if((USART1_RX_STA&0x8000)==0)//接收未完成
        {
            if(USART1_NewData==0x5A)//接收到了0x5A
            {
                 USART1_RX_STA|=0x8000;   //接收完成了,将USART1_RX_STA中的bit15置1
            }
            else
            {
                   USART1_RX_BUF[USART1_RX_STA&0X7FFF]=USART1_NewData; //将接收到的数据放入数组
                   USART1_RX_STA++;  //数据长度计数加1
                   if(USART1_RX_STA>(USART1_REC_LEN-1))USART1_RX_STA=0;//接收数据错误,重新开始接收
            }
        }
        HAL_UART_Receive_IT(&huart1,(uint8_t *)&USART1_NewData,1); //因为每执行完一次中断回调函数会将接收功能关闭,所以最后要再次开启中断
    }
		if(USART1_RX_STA&0x8000)         //判断中断接受标志位(蓝牙模块使用USART1)    
		{
		 if((USART1_RX_STA&0x7FFF)==5 //判断接收数量	                    
				&& USART1_RX_BUF[0]==0xA5 	//判断接接收第一个数据是不是包头0xA5
				&& USART1_RX_BUF[4]==(USART1_RX_BUF[1]+USART1_RX_BUF[2]+USART1_RX_BUF[3])%0x100)	//判断接受校验码是不是原数据之和低8位
			{
				X=USART1_RX_BUF[1];     //接受并读取蓝牙发送过来的数据
				Y=USART1_RX_BUF[2];
				Z=USART1_RX_BUF[3];
			} 
		 USART1_RX_STA=0;		 //标志位清0,准备下一次接收
		}

}

bluetooth.h

#ifndef __BLUETOOTH_H__
#define __BLUETOOTH_H__

#include "main.h" //HAL库文件声明

extern UART_HandleTypeDef huart1;//声明USART2的HAL库结构体

#define USART1_REC_LEN  200//定义USART2最大接收字节数

extern uint8_t  USART1_RX_BUF[USART1_REC_LEN];//接收缓冲,最大USART_REC_LEN个字节.末字节为校验和
extern uint16_t USART1_RX_STA;//接收状态标记
extern uint8_t USART1_NewData;//当前串口中断接收的1个字节数据的缓存


void  HAL_UART_RxCpltCallback(UART_HandleTypeDef  *huart);//串口中断回调函数声明

#endif 

蓝牙部分代码参考自这篇文章蓝牙小车(基于stm32f103c8t6/HAL库/CubeMX/超详细,包含代码讲解和原理图)

Control.c

#include "gpio.h"
#include "Car_Move.h"
#include "Control.h"
#include "bluetooth.h"

int X,Y,Z;

void Control(void)
{

	if(Y==1)
		{
			Move_Forward(3000);
		}
		else if(Y==2)
		{
			Move_Back(3000);
		}
		else if(Z==1)
		{
			TurnRight(3000);
		}
		else if(Z==2)
		{
			TurnLeft(3000);
		}			
		else if(X==1)
		{
			Move_Right(3000);
		}
		else if(X==2)
		{
			Move_Left(3000);
		}				
		else
		{
			Move_Stop();
		}
}

Control.h

#ifndef __CONTROL_H
#define __CONTROL_H

extern int X,Y,Z;

void Control(void);

#endif

以上就是主要的代码了,主要我还是新手,代码有很多要改进的地方,后期我会再慢慢修改完善代码。

三.手机蓝牙调试app使用方法

蓝牙小车(基于stm32f103c8t6/HAL库/CubeMX/超详细,包含代码讲解和原理图)

还是这篇文章,文章后半部分详细地讲解了app的使用方法。

(本片文章主要用于记录我的代码和其他一些东西以提醒我自己)

物联沃分享整理
物联沃-IOTWORD物联网 » 使用STM32 HAL库实现蓝牙遥控小车

发表评论