HC-05蓝牙控制STM32小车代码
时间: 2023-06-27 07:08:05 浏览: 126
以下是一个简单的 HC-05 蓝牙模块控制STM32小车的代码示例:
```c
#include "stm32f10x.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define USART_RX_BUF_SIZE 128
uint8_t USART_RX_BUF[USART_RX_BUF_SIZE];
uint8_t USART_RX_STA = 0;
void USART_Configuration(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
USART_InitTypeDef USART_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1|RCC_APB2Periph_GPIOA, ENABLE);
// USART1_TX GPIOA.9
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_Init(GPIOA, &GPIO_InitStructure);
// USART1_RX GPIOA.10
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(GPIOA, &GPIO_InitStructure);
// USART1 配置
USART_InitStructure.USART_BaudRate = 9600;
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
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);
USART_Cmd(USART1, ENABLE);
USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);
}
/**
* @brief 发送一个字节
* @param USARTx: 串口号
* @param ch: 发送的字节
* @retval None
*/
void USART_SendByte(USART_TypeDef* USARTx, uint8_t ch)
{
while((USARTx->SR&USART_FLAG_TXE)==0);
USARTx->DR = (uint16_t) ch;
}
/**
* @brief 发送字符串
* @param USARTx: 串口号
* @param str: 发送的字符串
* @retval None
*/
void USART_SendString(USART_TypeDef* USARTx, char* str)
{
while(*str)
{
USART_SendByte(USARTx,*str++);
}
}
/**
* @brief USART1中断服务函数
* @param None
* @retval None
*/
void USART1_IRQHandler(void)
{
if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)
{
uint8_t data = USART_ReceiveData(USART1);
if((USART_RX_STA & 0x80) == 0)
{
if(USART_RX_STA & 0x40)
{
if(data != 0x0a)
{
USART_RX_STA = 0;
}
else
{
USART_RX_STA |= 0x80;
}
}
else
{
if(data == 0x0d)
{
USART_RX_STA |= 0x40;
}
else
{
USART_RX_BUF[USART_RX_STA & 0x3f] = data;
USART_RX_STA++;
if(USART_RX_STA > (USART_RX_BUF_SIZE-1))
{
USART_RX_STA = 0;
}
}
}
}
}
}
/**
* @brief 初始化小车
* @param None
* @retval None
*/
void Car_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_OCInitTypeDef TIM_OCInitStructure;
// PA.8 - TIM1_CH1
// PA.9 - TIM1_CH2
// PA.10 - TIM1_CH3
// PA.11 - TIM1_CH4
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_AFIO, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10 | GPIO_Pin_11;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_Init(GPIOA, &GPIO_InitStructure);
uint16_t arr = 2000;
uint16_t psc = 71;
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(TIM1, &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_OC1Init(TIM1, &TIM_OCInitStructure);
TIM_OC1PreloadConfig(TIM1, TIM_OCPreload_Enable);
TIM_SetCompare1(TIM1, 0);
TIM_OC2Init(TIM1, &TIM_OCInitStructure);
TIM_OC2PreloadConfig(TIM1, TIM_OCPreload_Enable);
TIM_SetCompare2(TIM1, 0);
TIM_OC3Init(TIM1, &TIM_OCInitStructure);
TIM_OC3PreloadConfig(TIM1, TIM_OCPreload_Enable);
TIM_SetCompare3(TIM1, 0);
TIM_OC4Init(TIM1, &TIM_OCInitStructure);
TIM_OC4PreloadConfig(TIM1, TIM_OCPreload_Enable);
TIM_SetCompare4(TIM1, 0);
TIM_Cmd(TIM1, ENABLE);
}
/**
* @brief PWM控制
* @param ch: 通道(1-4)
* pulse: 脉宽(0-2000)
* @retval None
*/
void SetPWM(uint8_t ch, uint16_t pulse)
{
switch(ch)
{
case 1: TIM_SetCompare1(TIM1, pulse); break;
case 2: TIM_SetCompare2(TIM1, pulse); break;
case 3: TIM_SetCompare3(TIM1, pulse); break;
case 4: TIM_SetCompare4(TIM1, pulse); break;
default: break;
}
}
/**
* @brief 解析命令并控制小车
* @param cmd: 命令字符串
* @retval None
*/
void ParseCommand(char* cmd)
{
char* p = cmd;
char* q = cmd;
uint8_t ch = 0;
uint16_t pulse = 0;
while(*p)
{
if(*p == ':')
{
ch = atoi(q);
q = p + 1;
}
else if(*p == ',')
{
pulse = atoi(q);
SetPWM(ch, pulse);
q = p + 1;
}
else if(*p == ';')
{
pulse = atoi(q);
SetPWM(ch, pulse);
USART_SendString(USART1, "OK\r\n");
return;
}
p++;
}
}
int main(void)
{
USART_Configuration();
Car_Init();
while(1)
{
if(USART_RX_STA & 0x80)
{
USART_RX_BUF[USART_RX_STA & 0x3f] = 0;
ParseCommand((char*)USART_RX_BUF);
USART_RX_STA = 0;
}
}
}
```
在该代码中,我们使用了STM32的USART1串口与HC-05蓝牙模块进行通信。当串口接收到数据时,会触发USART1_IRQHandler中断服务函数,并将数据存储到USART_RX_BUF缓冲区中。当接收到一个完整的命令后,ParseCommand函数将解析命令并控制小车。在本例中,命令格式为“通道号:脉宽,”,并以“;”结尾。例如:“1:1500,2:1000,3:500,4:0;”表示将第1个通道的脉宽设置为1500,第2个通道的脉宽设置为1000,第3个通道的脉宽设置为500,第4个通道的脉宽设置为0。
阅读全文