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波特率。

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

bash 复制代码
#define SDI_BREAK_TIME 13
#define SDI_BREAK_QUIET_TIME 20

//@brief 发送确认激活命令  
//@param addr 传感器地址 ascii码 低7位有效
void sdi12SendAckActive(uint8_t addr)
{
	uint8_t cmd[]={'0'+addr,'!'};
	switchToIoConfig();
	HAL_GPIO_WritePin(SDI_DIR_GPIO_Port,SDI_DIR_Pin,GPIO_PIN_RESET);   //使能 SDI_OUT_PIN 输出
	sdi12SendBreak();
	switchToUartConfig();
	//HAL_UART_AbortReceive(&huart3);
	HAL_UART_Transmit(&huart3,cmd,2,0xFFFF);
	HAL_GPIO_WritePin(SDI_DIR_GPIO_Port,SDI_DIR_Pin,GPIO_PIN_SET);   //失能 SDI_OUT_PIN 输出

	g_SdiReceiveMessage.receiveFlag=0;
	g_SdiReceiveMessage.messageTop =0;
	HAL_UART_Receive_IT(&huart3, g_SdiReceiveMessage.message, 1);
	return;
}

//@brief 将tx引脚配置为输出模式,作输出唤醒信号使用
void switchToIoConfig()
{
	GPIO_InitTypeDef GPIO_InitStruct={0};
	/*Configure GPIO pin Output Level */
	HAL_GPIO_WritePin(SDI_OUT_PORT, SDI_OUT_PIN, GPIO_PIN_SET);

	/*Configure GPIO pin : SPI_DIR_Pin */
	GPIO_InitStruct.Pin = SDI_OUT_PIN;
	GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
	GPIO_InitStruct.Pull = GPIO_NOPULL;
	GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
	HAL_GPIO_Init(SDI_OUT_PORT, &GPIO_InitStruct);
	return;
}

//@brief 发送唤醒信号
void sdi12SendBreak()
{
	HAL_GPIO_WritePin(SDI_OUT_PORT,SDI_OUT_PIN,GPIO_PIN_RESET);
	HAL_Delay(SDI_BREAK_TIME);
	HAL_GPIO_WritePin(SDI_OUT_PORT,SDI_OUT_PIN,GPIO_PIN_SET);
	HAL_Delay(SDI_BREAK_QUIET_TIME);
}

//@brief 将tx引脚配置为复用模式,作串口输出使用
void switchToUartConfig()
{
	GPIO_InitTypeDef GPIO_InitStruct={0};
	/*Configure GPIO pin Output Level */
	HAL_GPIO_WritePin(SDI_OUT_PORT, SDI_OUT_PIN, GPIO_PIN_SET);

	GPIO_InitStruct.Pin = SDI_OUT_PIN;
	GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
	GPIO_InitStruct.Pull = GPIO_NOPULL;
	GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
	GPIO_InitStruct.Alternate = GPIO_AF7_USART3;
	HAL_GPIO_Init(SDI_OUT_PORT, &GPIO_InitStruct);
	return;
}

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

相关推荐
richxu2025100140 分钟前
嵌入式学习之路->stm32篇->(11)SPI通信(下)
stm32·嵌入式硬件·学习
电子科技圈1 小时前
从进迭时空K3看RISC-V CPU与Imagination GPU协同:如何构建高性能SoC能力
大数据·图像处理·人工智能·嵌入式硬件·边缘计算·智能硬件·risc-v
W.W.H.1 小时前
FreeRTOS移植(保姆级教程)
经验分享·单片机·操作系统·freertos·rtos
LCG元2 小时前
STM32实战:基于STM32F103的智能消防报警联动系统
stm32·单片机·嵌入式硬件
ivy159868377152 小时前
CH32V203G6U6 ‌沁恒32位 RISC-V 微控制器(MCU)‌
单片机·嵌入式硬件·risc-v
北山有鸟3 小时前
Linux第一宏:container_of
笔记·嵌入式硬件·学习
blevoice3 小时前
杰理蓝牙音箱开发板AC696N上演示降本设计:AC696N“省晶振”方案配置
单片机·嵌入式硬件·jl杰理蓝牙音频芯片·杰理ac696n开发板·ac6966b蓝牙音响芯片·蓝牙芯片ble透传·杰理蓝牙音箱方案开发
Ww.xh3 小时前
STM32+ESP8266智能农业系统开发指南
stm32·单片机·嵌入式硬件
charlie1145141913 小时前
嵌入式Linux驱动开发(3)——内核模块机制 - Linux 的插件系统
linux·运维·开发语言·驱动开发·嵌入式硬件·学习
yong99903 小时前
在 STC15W201S 上实现 MODBUS RTU 协议
stm32·单片机·嵌入式硬件