核心板: STM32F103C8T6。
蓝牙模块:SPP-CA 蓝牙串口通讯模块。
实验目的:通过串口助手发送指令,接收蓝牙返回的指令并打印在串口助手,实现对蓝牙相关数据
的更改。
说明:usart1用于串口通讯,usart3用于蓝牙通讯;本程序使用的串口中断模式发送与接收。
第一步:进行对串口的配置。
选择异步通信,开启中断,设置波特率为115200,数据传输长度8 bit,无奇偶校验位,停止位为1,使能接收与发送(usart1与usart3配置相同)。配置好后生成代码。
第二步:重定向printf函数。
打开 usart.c,在 /* USER CODE BEGIN 0 */ 和 /* USER CODE END 0 */加入以下代码:
#include
#ifdef __GNUC__
/* With GCC/RAISONANCE, small printf (option LD Linker->Libraries->Small printf
set to 'Yes') calls __io_putchar() */
#define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
#else
#define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
#endif /* __GNUC__ */
在 /* USER CODE BEGIN 1 */ 和 /* USER CODE END 1 */ 之间加入以下代码:
/**
* @brief Retargets the C library printf function to the USART.
* @param None
* @retval None
*/
PUTCHAR_PROTOTYPE
{
/* Place your implementation of fputc here */
/* e.g. write a character to the EVAL_COM1 and Loop until the end of transmission */
HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, 0xFFFF);
return ch;
}
第三步:编写回调函数。
首先我对此表示一下个人对回调函数的一个理解,因为没有系统的学习过HAL库,第一次写这个串口通信的内容,可能理解有误,欢迎大家指正。
在标准库中,我们需要使能接收中断,当有数据发来时,会进入中断函数,我们在中断函数中编写我们的逻辑程序;而在HAL库中,这个回调函数充当了在标准库中的中断函数,不过方便的是不需要我们要清除什么中断标志等操作,而是只需要判断一下是哪个串口的接收中断。(发送同理)
首先我们需要开启接收中断函数,即调用一次HAL_UART_Receive_IT(),之后会进入USARTx_IRQHandler()中断服务函数,这个函数中有这样一个函数HAL_UART_IRQHandler(),在这个函数中会判断这个中断是由接收引起的还是发送引起的,判断后(假设为接收引起的)会调用UART_Receive_IT(),最后会回到我们编写的回调函数,即我们编写我们逻辑程序的地方:回调函数HAL_UART_RxCpltCallback()。(发送同理)
看了一些文章对这些函数的叫法是这样的:
中断接收函数:HAL_UART_Receive_IT() 【也有对应的中断发送函数】
中断服务函数:USARTx_IRQHandler() 【x为对应的串口编号】
中断处理函数:HAL_UART_IRQHandler() 【判断是接收还是发送引起中断】
接收函数 :UART_Receive_IT() 【也有对应的发送函数】
接收处理函数:HAL_UART_RxCpltCallback()【也有对应的发送处理函数】
(以上函数中的参数均未写出)
回到我们的实验,在main.c中,在主函数上面编写如下代码
/* USER CODE BEGIN 0 */
char Buff[255];//存储数据
uint8_t Data; //暂存数据
int Cnt = 0; //计数
/* 回调函数 */
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
if(huart == &huart1)
{
Buff[Cnt++] = (char)Data;
if(Buff[Cnt-1] == 0x0A && Buff[Cnt-2] == 0x0D)//判断是否为回车结尾
{
printf("\n接收到的数据为:\n");
HAL_UART_Transmit_IT(&huart1, (uint8_t *)Buff, Cnt);//显示在串口助手
HAL_UART_Transmit_IT(&huart3, (uint8_t *)Buff, Cnt);//发送给蓝牙
Cnt = 0;
}
HAL_UART_Receive_IT(&huart1, &Data, sizeof(Data));//继续接收数据
}
if(huart == &huart3)
{
Buff[Cnt++] = (char)Data;
if(Buff[Cnt-1] == 0x0A && Buff[Cnt-2] == 0x0D)//判断是否为回车结尾
{
printf("\n蓝牙返回的数据为:\n");
HAL_UART_Transmit_IT(&huart1, (uint8_t *)Buff, Cnt);//显示在串口助手
Cnt = 0;
}
HAL_UART_Receive_IT(&huart3, &Data, sizeof(Data));//继续接收数据
}
}
/* USER CODE END 0 */
在主函数中需要开启接收中断,所以我们只需要主函数中加入一下代码
/* 建议放在while(1)上面 */
HAL_UART_Receive_IT(&huart1, &Data, sizeof(Data));//开启中断接收数据
HAL_UART_Receive_IT(&huart3, &Data, sizeof(Data));//开启中断接收数据
第四步:验证实验
首先要清楚发送什么给蓝牙才能进行对蓝牙的操作。
(1)测试指令
记得在发送指令时需要回车,不仅仅是接收数据时的约定,更是蓝牙接收数据的约定。
(2)获取版本号指令
更改蓝牙名称为“DDD”
查询蓝牙名称
手机中打开蓝牙设备查询
以上仅供自己与大家学习积累,欢迎各位大佬批评与指正!