一、硬件
JY901引脚 | STM32F103引脚 | 功能说明 |
---|---|---|
VCC | 3.3V | 电源供电 |
GND | GND | 地线 |
TX | PA10 (USART1_RX) | 接收数据 |
RX | PA9 (USART1_TX) | 发送数据 |
二、STM32串口配置代码(HAL库)
// usart.c
#include "stm32f1xx_hal.h"UART_HandleTypeDef huart1;void MX_USART1_UART_Init(void)
{huart1.Instance = USART1;huart1.Init.BaudRate = 115200; // 默认波特率huart1.Init.WordLength = UART_WORDLENGTH_8B;huart1.Init.StopBits = UART_STOPBITS_1;huart1.Init.Parity = UART_PARITY_NONE;huart1.Init.Mode = UART_MODE_TX_RX;huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;huart1.Init.OverSampling = UART_OVERSAMPLING_16;if (HAL_UART_Init(&huart1) != HAL_OK){Error_Handler();}
}// 重定向printf函数
int fputc(int ch, FILE *f)
{HAL_UART_Transmit(&huart1, (uint8_t*)&ch, 1, HAL_MAX_DELAY);return ch;
}
三、数据接收与解析
1. 数据结构定义
typedef struct {uint8_t header[2]; // 起始符 0x55 0xAAuint8_t addr; // 地址位uint8_t ctrl; // 控制码uint16_t length; // 数据长度uint8_t data[64]; // 数据域uint8_t checksum; // 校验和
} JY901_Frame;typedef struct {float accel[3]; // 加速度 (g)float gyro[3]; // 角速度 (°/s)float angle[3]; // 角度 (°)float mag[3]; // 磁场 (mG)float pressure; // 气压 (hPa)float altitude; // 高度 (m)
} JY901_Data;
2. DMA接收配置
#define RX_BUFFER_SIZE 256uint8_t rx_buffer[RX_BUFFER_SIZE];
JY901_Frame current_frame;void MX_DMA_Init(void)
{__HAL_RCC_DMA1_CLK_ENABLE();DMA_HandleTypeDef hdma_usart1_rx;hdma_usart1_rx.Instance = DMA1_Channel5;hdma_usart1_rx.Init.Direction = DMA_PERIPH_TO_MEMORY;hdma_usart1_rx.Init.PeriphInc = DMA_PINC_DISABLE;hdma_usart1_rx.Init.MemInc = DMA_MINC_ENABLE;hdma_usart1_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;hdma_usart1_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;hdma_usart1_rx.Init.Mode = DMA_CIRCULAR;hdma_usart1_rx.Init.Priority = DMA_PRIORITY_HIGH;if (HAL_DMA_Init(&hdma_usart1_rx) != HAL_OK){Error_Handler();}__HAL_LINKDMA(&huart1, hdmarx, hdma_usart1_rx);HAL_UART_Receive_DMA(&huart1, rx_buffer, RX_BUFFER_SIZE);
}
四、数据解析核心代码
void USART1_IRQHandler(void)
{HAL_UART_IRQHandler(&huart1);if (__HAL_UART_GET_FLAG(&huart1, UART_FLAG_IDLE)){__HAL_UART_CLEAR_IDLEFLAG(&huart1);// 计算接收数据长度uint16_t len = RX_BUFFER_SIZE - __HAL_DMA_GET_COUNTER(huart1.hdmarx);// 解析数据帧if(Parse_Frame(rx_buffer, len, ¤t_frame)){// 数据处理Process_JY901_Data(¤t_frame, &sensor_data);}}
}// 数据帧解析函数
bool Parse_Frame(uint8_t *buffer, uint16_t len, JY901_Frame *frame)
{if(len < 10) return false; // 最小帧长度// 检查起始符if(buffer[0] != 0x55 || buffer[1] != 0xAA) return false;frame->addr = buffer[2];frame->ctrl = buffer[3];frame->length = (buffer[4] << 8) | buffer[5];// 检查数据长度合法性if(frame->length > RX_BUFFER_SIZE - 8) return false;// 复制数据域memcpy(frame->data, buffer+6, frame->length);// 校验和验证uint8_t checksum = 0;for(int i=2; i<6+frame->length; i++) checksum += buffer[i];if(checksum != buffer[6+frame->length]) return false;return true;
}
五、数据处理与输出
void Process_JY901_Data(JY901_Frame *frame, JY901_Data *data)
{static float accel_scale = 16.0f/32768.0f; // ±2g量程static float gyro_scale = 2000.0f/32768.0f; // ±2000°/s量程// 解析加速度data->accel[0] = (frame->data[0] | (frame->data[1]<<8)) * accel_scale;data->accel[1] = (frame->data[2] | (frame->data[3]<<8)) * accel_scale;data->accel[2] = (frame->data[4] | (frame->data[5]<<8)) * accel_scale;// 解析角速度data->gyro[0] = (frame->data[6] | (frame->data[7]<<8)) * gyro_scale;data->gyro[1] = (frame->data[8] | (frame->data[9]<<8)) * gyro_scale;data->gyro[2] = (frame->data[10]| (frame->data[11]<<8)) * gyro_scale;// 解析角度(示例:Roll/Pitch/Yaw)data->angle[0] = (frame->data[12] | (frame->data[13]<<8)) / 100.0f; // Rolldata->angle[1] = (frame->data[14] | (frame->data[15]<<8)) / 100.0f; // Pitchdata->angle[2] = (frame->data[16] | (frame->data[17]<<8)) / 100.0f; // Yaw
}
六、主程序流程
int main(void)
{HAL_Init();SystemClock_Config();MX_USART1_UART_Init();MX_DMA_Init();printf("JY901 UART Test Start...\r\n");while(1){// 主循环处理其他任务HAL_Delay(10);}
}
参考代码 Jy901通过串口连接stm32f1x的源代码 www.youwenfan.com/contentcnj/71613.html
七、常见问题解决
- 数据乱码 检查波特率是否匹配(使用逻辑分析仪验证) 确认TX/RX引脚交叉连接
- 校验失败 验证数据帧长度字段是否正确 检查数据解析顺序是否与协议一致
- 动态漂移 实现温度补偿算法 定期执行零偏校准