【嵌入式协议外设篇】- HC08蓝牙模块

一、适用场景
适用场景:手机/平板与 MCU 的短距离无线串口通信(遥控、数据上报、参数配置)、蓝牙遥控小车/机器人、无线调试串口、低功耗传感器节点与交互原型、课堂蓝牙通信实验。
二、器材清单
HC-08 BLE 模块(常见基于 TI CC2540/CC2541 的模块) ×1
stm32f103 / 其他 STM32 开发板 ×1
若干杜邦线(公对母)×1组
三、工作原理(要点)
模式:模块既支持 AT 命令模式(用于修改名称、波特率、主/从角色等),也支持连接后进入串口透传模式进行透明数据通信。通常 AT 命令在模块未配对前或特定波特下可直接使用。
接口与性能:主接口为 UART(常见默认波特 9600,但可配置 1200–115200),模块典型发射功率约 4dBm,空旷环境下厂商宣称可达几十米至 80m 的参考距离(视天线和环境决定)。
四、接线示意(常见 4/5 引脚模块)
VCC → +5V
GND → GND
标准库
PA9→RX
PA10→TX
HAL库
PA2→RX
PA3→TX
五、示例代码(HAL / UART)
标准库
#include "stm32f10x.h"
#include "forward_direction.h"
extern char mask;
int main()
{
pwm_init();
usart_init();
while(1)
{
switch(mask)
{
case 'f':TIM_SetCompare1(TIM3,1000);break;
case 'b':TIM_SetCompare1(TIM3,1500);break;
case 'r':TIM_SetCompare1(TIM3,2000);break;
case 'l':TIM_SetCompare1(TIM3,2500);break;
case 's':TIM_SetCompare1(TIM3,500);break;
}
}
// return 0;
}
#include "forward_direction.h"
char mask=0;
void usart_init()
{
GPIO_InitTypeDef PB;
USART_InitTypeDef usart;
NVIC_InitTypeDef nvic;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3,ENABLE);
PB.GPIO_Pin = GPIO_Pin_10;
PB.GPIO_Mode = GPIO_Mode_AF_PP;
PB.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB,&PB);
PB.GPIO_Pin = GPIO_Pin_11;
PB.GPIO_Mode = GPIO_Mode_IPD;
GPIO_Init(GPIOB,&PB);
usart.USART_BaudRate = 9600;
usart.USART_WordLength = USART_WordLength_8b;
usart.USART_StopBits = USART_StopBits_1;
usart.USART_Parity = USART_Parity_No;
usart.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
usart.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
USART_Init(USART3,&usart);
USART_ITConfig(USART3,USART_IT_RXNE,ENABLE);
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
nvic.NVIC_IRQChannel = USART3_IRQn;
nvic.NVIC_IRQChannelPreemptionPriority = 1;
nvic.NVIC_IRQChannelSubPriority = 1;
nvic.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&nvic);
USART_Cmd(USART3,ENABLE);
}
void Usart_SendByte(USART_TypeDef * USARTx,uint8_t ch)
{
USART_SendData(USARTx,ch);
while(USART_GetFlagStatus(USARTx,USART_FLAG_TC) == RESET);
}
void Usart_SendString(USART_TypeDef * USARTx,char * str)
{
int k=0;
do
{
Usart_SendByte(USARTx,*(str+k));
k++;
}while((*(str+k))!='\0');
while(USART_GetFlagStatus(USARTx,USART_FLAG_TC) == RESET);
}
void USART3_IRQHandler()
{
if(USART_GetFlagStatus(USART3,USART_FLAG_RXNE) == SET)
{
mask = USART_ReceiveData(USART3);
Usart_SendString(USART3,"ok");
}
}
void pwm_init()
{
GPIO_InitTypeDef PA;
TIM_TimeBaseInitTypeDef tim;
TIM_OCInitTypeDef oc;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);
PA.GPIO_Pin = GPIO_Pin_6;
PA.GPIO_Mode = GPIO_Mode_AF_PP;
PA.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA,&PA);
tim.TIM_Period = (20000-1);
tim.TIM_Prescaler = (72-1);
tim.TIM_ClockDivision = TIM_CKD_DIV1;
tim.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM3,&tim);
oc.TIM_OCMode = TIM_OCMode_PWM1;
oc.TIM_OutputState = TIM_OutputState_Enable;
oc.TIM_OCPolarity = TIM_OCPolarity_High;
oc.TIM_Pulse = 500;
TIM_OC1Init(TIM3,&oc);
TIM_OC1PreloadConfig(TIM3,TIM_OCPreload_Enable);
TIM_Cmd(TIM3,ENABLE);
}
HAL库


#include "usart.h"
/* USER CODE BEGIN 0 */
#include "string.h"
#define USART2_RX_BUFFER_MAXSIZE 256 //DMA接收的最大长度
uint8_t USART2_rx_buffer[USART2_RX_BUFFER_MAXSIZE]; //数据存放的内存
uint8_t CO2_Data[6];
extern Data DataSendStr;
extern uint8_t DataSend[16];
/* USER CODE END 0 */
UART_HandleTypeDef huart1;
UART_HandleTypeDef huart2;
DMA_HandleTypeDef hdma_usart1_rx;
DMA_HandleTypeDef hdma_usart2_rx;
/* USART1 init function */
void MX_USART1_UART_Init(void)
{
/* USER CODE BEGIN USART1_Init 0 */
/* USER CODE END USART1_Init 0 */
/* USER CODE BEGIN USART1_Init 1 */
/* USER CODE END USART1_Init 1 */
huart1.Instance = USART1;
huart1.Init.BaudRate = 115200;
huart1.Init.WordLength = UART_WORDLENGTH_8B;
huart1.Init.StopBits = UART_STOPBITS_1;
huart1.Init.Parity = UART_PARITY_NONE;
huart1.Init.Mode = UART_MODE_TX_RX;
huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
huart1.Init.OverSampling = UART_OVERSAMPLING_16;
if (HAL_UART_Init(&huart1) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN USART1_Init 2 */
/* USER CODE END USART1_Init 2 */
}
/* USART2 init function */
void MX_USART2_UART_Init(void)
{
/* USER CODE BEGIN USART2_Init 0 */
/* USER CODE END USART2_Init 0 */
/* USER CODE BEGIN USART2_Init 1 */
/* USER CODE END USART2_Init 1 */
huart2.Instance = USART2;
huart2.Init.BaudRate = 115200;
huart2.Init.WordLength = UART_WORDLENGTH_8B;
huart2.Init.StopBits = UART_STOPBITS_1;
huart2.Init.Parity = UART_PARITY_NONE;
huart2.Init.Mode = UART_MODE_TX_RX;
huart2.Init.HwFlowCtl = UART_HWCONTROL_NONE;
if (HAL_UART_Init(&huart2) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN USART2_Init 2 */
if(HAL_UARTEx_ReceiveToIdle_DMA(&huart2, (uint8_t *)USART2_rx_buffer, USART2_RX_BUFFER_MAXSIZE) != HAL_OK)
{
Error_Handler();
}
/* USER CODE END USART2_Init 2 */
}
void HAL_UART_MspInit(UART_HandleTypeDef* uartHandle)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
if(uartHandle->Instance==USART1)
{
/* USER CODE BEGIN USART1_MspInit 0 */
/* USER CODE END USART1_MspInit 0 */
/* USART1 clock enable */
__HAL_RCC_USART1_CLK_ENABLE();
__HAL_RCC_GPIOA_CLK_ENABLE();
/**USART1 GPIO Configuration
PA9 ------> USART1_TX
PA10 ------> USART1_RX
*/
GPIO_InitStruct.Pin = GPIO_PIN_9;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
GPIO_InitStruct.Pin = GPIO_PIN_10;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
// /* USART1 DMA Init */
// /* USART1_RX Init */
// hdma_usart1_rx.Instance = DMA1_Channel5;
// hdma_usart1_rx.Init.Direction = DMA_PERIPH_TO_MEMORY;
// hdma_usart1_rx.Init.PeriphInc = DMA_PINC_DISABLE;
// hdma_usart1_rx.Init.MemInc = DMA_MINC_ENABLE;
// hdma_usart1_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
// hdma_usart1_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
// hdma_usart1_rx.Init.Mode = DMA_NORMAL;
// hdma_usart1_rx.Init.Priority = DMA_PRIORITY_LOW;
// if (HAL_DMA_Init(&hdma_usart1_rx) != HAL_OK)
// {
// Error_Handler();
// }
// 中断配置
HAL_NVIC_SetPriority(USART1_IRQn, 2, 2);
HAL_NVIC_EnableIRQ(USART1_IRQn);
__HAL_UART_ENABLE_IT(&huart1, UART_IT_RXNE); // 使能接收中断
/* USER CODE BEGIN USART1_MspInit 1 */
/* USER CODE END USART1_MspInit 1 */
}
else if(uartHandle->Instance==USART2)
{
/* USER CODE BEGIN USART2_MspInit 0 */
/* USER CODE END USART2_MspInit 0 */
/* USART2 clock enable */
__HAL_RCC_USART2_CLK_ENABLE();
__HAL_RCC_GPIOA_CLK_ENABLE();
/**USART2 GPIO Configuration
PA2 ------> USART2_TX
PA3 ------> USART2_RX
*/
GPIO_InitStruct.Pin = GPIO_PIN_2;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
GPIO_InitStruct.Pin = GPIO_PIN_3;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
/* USART2 DMA Init */
/* USART2_RX Init */
hdma_usart2_rx.Instance = DMA1_Channel6;
hdma_usart2_rx.Init.Direction = DMA_PERIPH_TO_MEMORY;
hdma_usart2_rx.Init.PeriphInc = DMA_PINC_DISABLE;
hdma_usart2_rx.Init.MemInc = DMA_MINC_ENABLE;
hdma_usart2_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
hdma_usart2_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
hdma_usart2_rx.Init.Mode = DMA_NORMAL;
hdma_usart2_rx.Init.Priority = DMA_PRIORITY_HIGH;
if (HAL_DMA_Init(&hdma_usart2_rx) != HAL_OK)
{
Error_Handler();
}
__HAL_LINKDMA(uartHandle,hdmarx,hdma_usart2_rx);
/* USART2 interrupt Init */
HAL_NVIC_SetPriority(USART2_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(USART2_IRQn);
/* USER CODE BEGIN USART2_MspInit 1 */
/* USER CODE END USART2_MspInit 1 */
}
}
void HAL_UART_MspDeInit(UART_HandleTypeDef* uartHandle)
{
if(uartHandle->Instance==USART1)
{
/* USER CODE BEGIN USART1_MspDeInit 0 */
/* USER CODE END USART1_MspDeInit 0 */
/* Peripheral clock disable */
__HAL_RCC_USART1_CLK_DISABLE();
/**USART1 GPIO Configuration
PA9 ------> USART1_TX
PA10 ------> USART1_RX
*/
HAL_GPIO_DeInit(GPIOA, GPIO_PIN_9|GPIO_PIN_10);
// /* USART1 DMA DeInit */
// HAL_DMA_DeInit(uartHandle->hdmarx);
/* USART1 interrupt Deinit */
// HAL_NVIC_DisableIRQ(USART1_IRQn);
/* USER CODE BEGIN USART1_MspDeInit 1 */
/* USER CODE END USART1_MspDeInit 1 */
}
else if(uartHandle->Instance==USART2)
{
/* USER CODE BEGIN USART2_MspDeInit 0 */
/* USER CODE END USART2_MspDeInit 0 */
/* Peripheral clock disable */
__HAL_RCC_USART2_CLK_DISABLE();
/**USART2 GPIO Configuration
PA2 ------> USART2_TX
PA3 ------> USART2_RX
*/
HAL_GPIO_DeInit(GPIOA, GPIO_PIN_2|GPIO_PIN_3);
/* USART2 DMA DeInit */
HAL_DMA_DeInit(uartHandle->hdmarx);
/* USART2 interrupt Deinit */
HAL_NVIC_DisableIRQ(USART2_IRQn);
/* USER CODE BEGIN USART2_MspDeInit 1 */
/* USER CODE END USART2_MspDeInit 1 */
}
}
/* USER CODE BEGIN 1 */
//void USART1_DMA_STATR(void)
//{
// HAL_UARTEx_ReceiveToIdle_DMA(&huart1, (uint8_t*)USART1_rx_buffer, USART1_RX_BUFFER_MAXSIZE);
//}
//void USART1_CallBack(void)
//{
// uint16_t len ;
// len = USART1_RX_BUFFER_MAXSIZE- __HAL_DMA_GET_COUNTER(&hdma_usart1_rx);
// if(len)
// {
// printf("DMA接收到的数据是%s\r\n",USART1_rx_buffer);
// memset(USART1_rx_buffer,0,len);
// }
//}
void USART2_DMA_STATR(void)
{
HAL_UARTEx_ReceiveToIdle_DMA(&huart2, (uint8_t*)USART2_rx_buffer, USART2_RX_BUFFER_MAXSIZE);
}
//接收ESP8266的数据
void USART2_CallBack(void)
{
uint16_t len ;
char show[20]={0};
len = USART2_RX_BUFFER_MAXSIZE- __HAL_DMA_GET_COUNTER(&hdma_usart2_rx);//获取得到的数据的长度
if(len)
{
//第一个字节是AA,第16个字节是DD校验位,第二是按键1,第三是按键2,第四是按键3,第四是按键4,第五是模式
if(USART2_rx_buffer[0] == 0xAA && USART2_rx_buffer[15] == 0xDD)
{
//接收到的数据放在数据结构体
DataSendStr.MODE = USART2_rx_buffer[1];
DataSendStr.LED1 = USART2_rx_buffer[2];
DataSendStr.LED2 = USART2_rx_buffer[3];
DataSendStr.XUANZE = USART2_rx_buffer[4];
}
memset(USART2_rx_buffer,0,16);
}
}
void USART1_CallBack(void)
{
uint8_t receive = (uint8_t)(huart1.Instance->DR & 0xFF);
HAL_UART_Transmit(&huart1, "ok2\n", strlen("ok2\n"), HAL_MAX_DELAY);
}
struct __FILE
{
int a;
};
FILE __stdout;
/*****************************************************
*function: 写字符文件函数
*param1: 输出的字符
*param2: 文件指针
*return: 输出字符的 ASCII 码
******************************************************/
int fputc(int ch, FILE *f)
{
HAL_UART_Transmit(&huart1, (uint8_t*)&ch, 1, 10);
return ch;
}
六、讲解视频
https://www.bilibili.com/video/BV1rekDBnEnz/?spm_id_from=333.1387.upload.video_card.click&vd_source=b035825fef3be39bc47a9c50b324d086
https://www.bilibili.com/video/BV1vNkDBgEYN/?spm_id_from=333.1387.upload.video_card.click&vd_source=b035825fef3be39bc47a9c50b324d086
更多推荐


所有评论(0)