• SDI-12协议与STM32 进行uart通信


    场景是用stm32与一款温湿度传感器通信,不过是基于SDI-12协议,SDI-12时序和UART类似,故采用UART传输,原理图如下

    其中DIR_OUT_SDI是一个IO引脚,控制UART_TX_SDI是否使能,U10是三态门IC,即拉低DIR_OUT_SDI使能stm32输出,拉高DIR_OUT_SDI失能输出,串口配置8位数据位,偶校验,1位停止位,1200波特率。

    下面给出发送一个激活命令的示例:

    1. #define SDI_BREAK_TIME 13
    2. #define SDI_BREAK_QUIET_TIME 20
    3. //@brief 发送确认激活命令
    4. //@param addr 传感器地址 ascii码 低7位有效
    5. void sdi12SendAckActive(uint8_t addr)
    6. {
    7. uint8_t cmd[]={'0'+addr,'!'};
    8. switchToIoConfig();
    9. HAL_GPIO_WritePin(SDI_DIR_GPIO_Port,SDI_DIR_Pin,GPIO_PIN_RESET); //使能 SDI_OUT_PIN 输出
    10. sdi12SendBreak();
    11. switchToUartConfig();
    12. //HAL_UART_AbortReceive(&huart3);
    13. HAL_UART_Transmit(&huart3,cmd,2,0xFFFF);
    14. HAL_GPIO_WritePin(SDI_DIR_GPIO_Port,SDI_DIR_Pin,GPIO_PIN_SET); //失能 SDI_OUT_PIN 输出
    15. g_SdiReceiveMessage.receiveFlag=0;
    16. g_SdiReceiveMessage.messageTop =0;
    17. HAL_UART_Receive_IT(&huart3, g_SdiReceiveMessage.message, 1);
    18. return;
    19. }
    20. //@brief 将tx引脚配置为输出模式,作输出唤醒信号使用
    21. void switchToIoConfig()
    22. {
    23. GPIO_InitTypeDef GPIO_InitStruct={0};
    24. /*Configure GPIO pin Output Level */
    25. HAL_GPIO_WritePin(SDI_OUT_PORT, SDI_OUT_PIN, GPIO_PIN_SET);
    26. /*Configure GPIO pin : SPI_DIR_Pin */
    27. GPIO_InitStruct.Pin = SDI_OUT_PIN;
    28. GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
    29. GPIO_InitStruct.Pull = GPIO_NOPULL;
    30. GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
    31. HAL_GPIO_Init(SDI_OUT_PORT, &GPIO_InitStruct);
    32. return;
    33. }
    34. //@brief 发送唤醒信号
    35. void sdi12SendBreak()
    36. {
    37. HAL_GPIO_WritePin(SDI_OUT_PORT,SDI_OUT_PIN,GPIO_PIN_RESET);
    38. HAL_Delay(SDI_BREAK_TIME);
    39. HAL_GPIO_WritePin(SDI_OUT_PORT,SDI_OUT_PIN,GPIO_PIN_SET);
    40. HAL_Delay(SDI_BREAK_QUIET_TIME);
    41. }
    42. //@brief 将tx引脚配置为复用模式,作串口输出使用
    43. void switchToUartConfig()
    44. {
    45. GPIO_InitTypeDef GPIO_InitStruct={0};
    46. /*Configure GPIO pin Output Level */
    47. HAL_GPIO_WritePin(SDI_OUT_PORT, SDI_OUT_PIN, GPIO_PIN_SET);
    48. GPIO_InitStruct.Pin = SDI_OUT_PIN;
    49. GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
    50. GPIO_InitStruct.Pull = GPIO_NOPULL;
    51. GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
    52. GPIO_InitStruct.Alternate = GPIO_AF7_USART3;
    53. HAL_GPIO_Init(SDI_OUT_PORT, &GPIO_InitStruct);
    54. return;
    55. }

    示波器测试得到传感器的应答信号如下:第一个是唤醒信号,拉高电平13毫秒,之后保持20毫秒低电平,第二个数据帧是激活信号,即ascii码:  "0!",第三个是传感器的应答信号:"0\r\n"

  • 相关阅读:
    Electron 18-19 值得关注的变化
    海外版外卖系统,目前国外都有哪些呢?
    面向对象java
    《web课程设计》 基于HTML+CSS+JavaScript实现中国水墨风的小学学校网站模板(6个网页)
    新零售SaaS架构:客户管理系统架构设计(万字图文总结)
    Apifox : 不仅是Api调试工具,更是开发团队的协作神器
    工作流引擎:Workflow Engine 7.0 Crack
    云原生之深入解析如何合并多个kubeconfig文件
    Go学习笔记
    Vuex中多个参数显示undefined的解决方案
  • 原文地址:https://blog.csdn.net/weixin_42186805/article/details/133378703