当前位置:   article > 正文

STM32灌溉系统(蓝牙模块与上位机部分)_蓝牙与上位机通讯协议

蓝牙与上位机通讯协议

蓝牙模块部分

1.硬件部分与初始设置

        使用的是HC-05,或者随便哪一种都行,按照个人需求配置AT指令,一般波特率9600就行了,也不是什么需要高精度的东西。配置AT指令时需要一个USB转TTL模块。

连接:TXD → RXD   RXD → TXD    GND ↔ GND     5V ↔ VCC

USB部分与电脑连接即可,长按按钮再上电,再然后用串口调试程序进行配置

1.1.AT指令配置:先按住HC05蓝牙模块上面的按键,再给蓝牙模块通电。蓝牙模块上面的LED进入慢闪模式,继续进行AT配置

1.2.修改蓝牙模块名称:
输入AT+NAME=STM之后按一下回车键发送,蓝牙返回OK,表示蓝牙名字修改为STM

1.3.蓝牙模块配对密码:
输入AT+PSWD="1234"之后按一下回车键发送,蓝牙返回OK,表示蓝牙配对密码修改为1234

1.4.修改波特率:
输入AT+UART=9600,0,0之后按一下回车键发送,蓝牙返回OK,表示蓝牙通信波特率修改为9600

1.5.返回蓝牙模块的地址:
键入AT + ADDR?,将返回蓝牙模块的地址,因为是和手机软件配对使用,就不用进行主机从机的配置了。配置好在蓝牙模块通电时就可以手机端搜索连接该蓝牙。

2.软件部分通信设置

初始化配置STM32的USART1串口通信功能。

USART1是一种通用异步收发器,可以用于实现串行数据通信。

该代码确保了USART1的初始化和相关外设的配置正确完成。 在函数`MX_USART1_UART_Init`中,通过`HAL_UART_Init`函数初始化了USART1串口的设置,并指定了波特率(要和前面蓝牙硬件部分设置的波特率相同,不然数据传输不了)、数据长度、停止位、校验位等参数。

在函数`HAL_UART_MspInit`中,进行外设GPIO端口的初始化设置,将USART1的TX引脚和RX引脚配置成对应的功能,并通过`HAL_GPIO_Init`函数进行初始化。 同时还进行了DMA的初始化和设置,通过DMA实现了USART1的数据传输。分别配置了接收数据的DMA和发送数据的DMA,并将其与USART1串口相关联。 在最后通过`HAL_NVIC_SetPriority`函数和`HAL_NVIC_EnableIRQ`函数设置了USART1的中断优先级和使能。

函数`HAL_UART_MspDeInit`是对USART1串口和相关外设进行反初始化的函数,在函数内部将与USART1相关的外设和中断进行了禁用和反初始化的操作。

总结就是代码是由STMicroelectronics提供的HAL库生成的,用于快速配置和使用USART1。可读性有点差劲但是用起来方便。

  1. #include "usart.h"
  2. UART_HandleTypeDef huart1;
  3. DMA_HandleTypeDef hdma_usart1_rx;
  4. DMA_HandleTypeDef hdma_usart1_tx;
  5. void MX_USART1_UART_Init(void)
  6. {
  7. huart1.Instance = USART1;
  8. huart1.Init.BaudRate = 9600;
  9. huart1.Init.WordLength = UART_WORDLENGTH_8B;
  10. huart1.Init.StopBits = UART_STOPBITS_1;
  11. huart1.Init.Parity = UART_PARITY_NONE;
  12. huart1.Init.Mode = UART_MODE_TX_RX;
  13. huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
  14. huart1.Init.OverSampling = UART_OVERSAMPLING_16;
  15. if (HAL_UART_Init(&huart1) != HAL_OK)
  16. {
  17. Error_Handler();
  18. }
  19. }
  20. void HAL_UART_MspInit(UART_HandleTypeDef* uartHandle)
  21. {
  22. GPIO_InitTypeDef GPIO_InitStruct = {0};
  23. if(uartHandle->Instance==USART1)
  24. {
  25. __HAL_RCC_USART1_CLK_ENABLE();
  26. __HAL_RCC_GPIOA_CLK_ENABLE();
  27. GPIO_InitStruct.Pin = GPIO_PIN_9;
  28. GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
  29. GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
  30. HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
  31. GPIO_InitStruct.Pin = GPIO_PIN_10;
  32. GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
  33. GPIO_InitStruct.Pull = GPIO_NOPULL;
  34. HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
  35. hdma_usart1_rx.Instance = DMA1_Channel5;
  36. hdma_usart1_rx.Init.Direction = DMA_PERIPH_TO_MEMORY;
  37. hdma_usart1_rx.Init.PeriphInc = DMA_PINC_DISABLE;
  38. hdma_usart1_rx.Init.MemInc = DMA_MINC_ENABLE;
  39. hdma_usart1_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
  40. hdma_usart1_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
  41. hdma_usart1_rx.Init.Mode = DMA_NORMAL;
  42. hdma_usart1_rx.Init.Priority = DMA_PRIORITY_LOW;
  43. if (HAL_DMA_Init(&hdma_usart1_rx) != HAL_OK)
  44. {
  45. Error_Handler();
  46. }
  47. __HAL_LINKDMA(uartHandle,hdmarx,hdma_usart1_rx);
  48. hdma_usart1_tx.Instance = DMA1_Channel4;
  49. hdma_usart1_tx.Init.Direction = DMA_MEMORY_TO_PERIPH;
  50. hdma_usart1_tx.Init.PeriphInc = DMA_PINC_DISABLE;
  51. hdma_usart1_tx.Init.MemInc = DMA_MINC_ENABLE;
  52. hdma_usart1_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
  53. hdma_usart1_tx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
  54. hdma_usart1_tx.Init.Mode = DMA_NORMAL;
  55. hdma_usart1_tx.Init.Priority = DMA_PRIORITY_LOW;
  56. if (HAL_DMA_Init(&hdma_usart1_tx) != HAL_OK)
  57. {
  58. Error_Handler();
  59. }
  60. __HAL_LINKDMA(uartHandle,hdmatx,hdma_usart1_tx);
  61. HAL_NVIC_SetPriority(USART1_IRQn, 0, 0);
  62. HAL_NVIC_EnableIRQ(USART1_IRQn);
  63. }
  64. }
  65. void HAL_UART_MspDeInit(UART_HandleTypeDef* uartHandle)
  66. {
  67. if(uartHandle->Instance==USART1)
  68. {
  69. __HAL_RCC_USART1_CLK_DISABLE();
  70. /**USART1 GPIO Configuration
  71. PA9 ------> USART1_TX
  72. PA10 ------> USART1_RX
  73. */
  74. HAL_GPIO_DeInit(GPIOA, GPIO_PIN_9|GPIO_PIN_10);
  75. /* USART1 DMA DeInit */
  76. HAL_DMA_DeInit(uartHandle->hdmarx);
  77. HAL_DMA_DeInit(uartHandle->hdmatx);
  78. /* USART1 interrupt Deinit */
  79. HAL_NVIC_DisableIRQ(USART1_IRQn);
  80. /* USER CODE BEGIN USART1_MspDeInit 1 */
  81. /* USER CODE END USART1_MspDeInit 1 */
  82. }
  83. }

手机软件部分

一开始想自己写一个app,不过还是太懒了,还是现成的好,手机端下载的是一个叫蓝牙调试器的软件。

该软件通信协议简单,界面设置简单,以下简单介绍数据包协议。

根据数据包协议设置数据包结构,设置界面并链接设置变量。为了简单变量全部设置为byte型。

两模块连接及功能实现代码

  1. uint8_t data[50]; //数据包
  2. uint8_t per; //湿度
  3. uint32_t top = 75; //湿度报警阈值
  4. uint32_t bot = 15;
  5. void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size)
  6. {
  7. char extracted1[10];
  8. char extracted2[10];
  9. char jiaoyan;//校验位
  10. uint8_t hum[4];
  11. int number1;
  12. const unsigned char constper;
  13. int number2;
  14. {
  15. //根据软件描述,校验位为数据和的低八位
  16. jiaoyan=data[1]+data[2]+data[3]+data[4];
  17. //data的1234位分别是阈值上下限,湿度接收,浇水控制
  18. hum[0]=0xa5;//包头
  19. hum[1]=per;
  20. hum[2]=per;
  21. hum[3]=0x5a;//包尾
  22. if(data[4]==0x01)
  23. {
  24. HAL_GPIO_WritePin(GPIOB, GPIO_PIN_5,0);
  25. //如果按下浇水按键, 则GPIO操作对应继电器进行浇水,即手动模式
  26. }
  27. else if(data[4]==0x00)
  28. {
  29. HAL_GPIO_WritePin(GPIOB, GPIO_PIN_5,1);
  30. //浇水手动关闭
  31. }
  32. if(data[3]==0x01)
  33. {
  34. HAL_UART_Transmit_DMA(&huart1, hum, 4);
  35. //接收按键点击立即给软件发送当前土壤湿度,当然也可以改为实时自动发送
  36. }
  37. if((data[0]==0xa5)&&(data[6]==0x5a)&&(data[5]==jiaoyan))
  38. {
  39. number1 = data[1];
  40. number2 = data[2];
  41. top = number1;
  42. bot = number2;
  43. HAL_UARTEx_ReceiveToIdle_DMA(&huart1, data, 50);
  44. //软件端设置湿度阈值上下限
  45. }
  46. }
  47. }

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/不正经/article/detail/622889
推荐阅读
相关标签
  

闽ICP备14008679号