我在 STM32L4 上对接 SDI-12 传感器。MCU 为 3.3V 电平,SN74LVC1G240 缓冲器实现 UART 转 SDI-12 单总线;
MOSFET 将 MCU 3.3V 信号抬升至 SDI-12 标准 5V 电平;
已确认硬件接线、电压输出全部正常。
UART5 配置代码如下:
static void MX_UART5_Init(void)
{
/* USER CODE BEGIN UART5_Init 0 */
/* USER CODE END UART5_Init 0 */
/* USER CODE BEGIN UART5_Init 1 */
/* USER CODE END UART5_Init 1 */
huart5.Instance = UART5;
huart5.Init.BaudRate = 1200;
huart5.Init.WordLength = UART_WORDLENGTH_8B; // Including parity
huart5.Init.StopBits = UART_STOPBITS_1;
huart5.Init.Parity = UART_PARITY_EVEN;
huart5.Init.Mode = UART_MODE_TX_RX;
huart5.Init.HwFlowCtl = UART_HWCONTROL_NONE;
huart5.Init.OverSampling = UART_OVERSAMPLING_16;
huart5.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;
huart5.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
if (HAL_UART_Init(&huart5) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN UART5_Init 2 */
/* USER CODE END UART5_Init 2 */
}
参考官方电路方案:缓冲器 OE 拉低时输出 5V 总线,UART TX 电平同步映射到 SDI12 数据线。规范要求发送命令后最多 15ms 传感器回复,但当前完全收不到应答。传感器供电 12V 正常。
SDI-12 协议要求先发 12ms Break 低电平、再发 8.3ms Mark 高电平,我已在代码实现该时序;示波器观测 SDI-12 总线波形时序电平都符合标准,但传感器对任何指令均无回应。测试指令:0!-0 号传感器 ping、?!-查询在线传感器地址,均无返回。
发送指令函数核心逻辑:
static HAL_StatusTypeDef _SDI12_send_command(const char cmd[], const uint8_t cmd_len, char response_buffer[], uint8_t res_len)
{
HAL_StatusTypeDef res;
// Step 1: Configure GPIO for break
GPIO_InitTypeDef GPIO_InitStruct = {0};
GPIO_InitStruct.Pin = GPIO_PIN_12;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
// Step 2: Select SDI-12
HAL_GPIO_WritePin(SDI12_SELECT_GPIO_Port, SDI12_SELECT_Pin, GPIO_PIN_RESET);
//HAL_Delay(1);
// Step 3: Send break (low for at least 12 ms)
HAL_GPIO_WritePin(GPIOC, GPIO_PIN_12, GPIO_PIN_SET);
HAL_Delay(12);
// Step 4: Marking condition (high for at least 8.3 ms)
HAL_GPIO_WritePin(GPIOC, GPIO_PIN_12, GPIO_PIN_RESET);
HAL_Delay(12);
// Step 5: Reconfigure the GPIO pin for UART TX
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Alternate = GPIO_AF_UART;
HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
HAL_Delay(1); // Set it to normilize the osciloscope outpu.
// Step 6: Transmit the command
res = HAL_UART_Transmit(&huart5, (uint8_t*)&cmd, cmd_len, 1000);
if (res != HAL_OK) {
printf("Error in transmitting UART data\r\n");
return HAL_ERROR;
}
// Step 7: Deselect SDI-12
HAL_GPIO_WritePin(SDI12_SELECT_GPIO_Port, SDI12_SELECT_Pin, GPIO_PIN_SET);
// Step 8: Wait for the sensor's response
uint8_t count = 0;
res = _SDI12_ReceiveLine(response_buffer, res_len, &count); // Make sure this function is correctly implemented
printf("response_buffer[0]=%d\r\n", response_buffer[0]);
printf("response_buffer[1]=%d\r\n", response_buffer[1]);
printf("response_buffer[2]=%d\r\n", response_buffer[2]);
return res;
}
我试过多种修改:切换 7 位数据位、反转比特序、调整高低位优先,全部无效。
|
|