STM32F1系列单片机通过串口与JY901传感器通信
STM32F1系列单片机通过串口与JY901传感器通信,主要任务是正确解析其输出的数据帧。
硬件连接与JY901数据协议
确保JY901模块与STM32F1开发板接线正确是其正常通信的基础。JY901模块的串口通常是TTL电平。
| JY901模块 | STM32F1xx | 说明 |
|---|---|---|
| VCC | 3.3V 或 5V | 根据模块要求 |
| GND | GND | 共地 |
| TX | 任意USART的RX引脚 (如PA3/USART2_RX) | JY901发送,STM32接收 |
| RX | 任意USART的TX引脚 (如PA2/USART2_TX) | 如需向JY901发送配置指令才连接 |
JY901数据帧格式是关键,其主动输出模式下的数据帧格式如下:
| 字节偏移 | 内容 | 说明 |
|---|---|---|
| 0 | 0x55 |
帧头 |
| 1 | 0x5X |
数据类型标识,X代表不同传感器数据 |
| 2-9 | 数据内容 | 具体数据(小端模式存储) |
| 10 | 0x5X |
此字节有时在示例代码中未被明确提及,通常关注前11字节 |
常见的数据类型标识包括:0x50(时间)、0x51(加速度)、0x52(角速度)、0x53(角度)、0x54(磁场)等。
软件实现:STM32F1读取JY901数据
利用STM32标准外设库,通过串口读取并解析JY901数据的基本步骤和代码示例。
1. 串口初始化
首先需要初始化一个USART,以下以USART2为例。
#include "stm32f10x.h"
#include <stdio.h>
// 定义接收缓冲区及相关变量
#define RX_BUFFER_SIZE 256
uint8_t ucRxBuffer[RX_BUFFER_SIZE];
uint32_t uiRxCnt = 0;
// 定义用于存储解析后数据的结构体
// 注意:根据JY901协议,数据通常为小端模式
typedef struct {
short a[3];
short T;
} SAcc;
typedef struct {
short w[3];
short T;
} SGyro;
typedef struct {
short Angle[3];
short T;
} SAngle;
// ... 可根据需要定义其他数据结构,如磁场、角度等
SAcc stcAcc;
SGyro stcGyro;
SAngle stcAngle;
void USART2_Init(uint32_t baudrate) {
GPIO_InitTypeDef GPIO_InitStructure;
USART_InitTypeDef USART_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
// 使能时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);
// 配置USART2 Tx (PA.2) 为复用推挽输出
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_Init(GPIOA, &GPIO_InitStructure);
// 配置USART2 Rx (PA.3) 为浮空输入
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(GPIOA, &GPIO_InitStructure);
// USART 参数配置
USART_InitStructure.USART_BaudRate = baudrate; // 常用9600或115200
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
USART_InitStructure.USART_StopBits = USART_StopBits_1;
USART_InitStructure.USART_Parity = USART_Parity_No;
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
USART_Init(USART2, &USART_InitStructure);
// 使能USART2接收中断
USART_ITConfig(USART2, USART_IT_RXNE, ENABLE);
// 配置NVIC
NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
// 使能串口
USART_Cmd(USART2, ENABLE);
}
2. 串口中断服务函数与数据帧解析
在中断服务函数中接收数据,并调用数据处理函数。
// 在stm32f10x_it.c中
void USART2_IRQHandler(void) {
if(USART_GetITStatus(USART2, USART_IT_RXNE) != RESET) {
// 读取接收到的数据
uint8_t ucData = USART_ReceiveData(USART2);
// 调用数据处理函数
CopeSerial2Data(ucData);
// 可选:将接收到的字节原样发送回串口助手,用于调试
// USART_SendData(USART2, ucData);
}
}
数据处理函数 CopeSerial2Data 是核心,负责识别并解析完整的数据帧。
// 数据处理函数
void CopeSerial2Data(unsigned char ucData) {
// 静态变量,用于在函数调用间保持值
static unsigned char ucRxBuffer[11]; // 存放一帧数据
static unsigned char ucRxCnt = 0; // 接收计数
// 将数据存入缓冲区
ucRxBuffer[ucRxCnt++] = ucData;
// 检查帧头:第一个字节必须是0x55
if (ucRxBuffer[0] != 0x55) {
ucRxCnt = 0;
return;
}
// 检查是否接收够一帧数据(11字节)
if (ucRxCnt < 11) {
return; // 数据不够,继续等待
} else {
// 根据第二个字节(数据类型标识)进行数据解析
switch(ucRxBuffer[1]) {
case 0x51:
// 解析加速度数据,注意数据在小端模式下通过memcpy拷贝到结构体
memcpy(&stcAcc, &ucRxBuffer[2], 8);
// 数据转换示例(根据模块手册和量程)
// stcAcc.a[0] = (short)(ucRxBuffer[3]<<8 | ucRxBuffer[2]); // 也可用此方式合并字节
break;
case 0x52:
// 解析角速度数据
memcpy(&stcGyro, &ucRxBuffer[2], 8);
break;
case 0x53:
// 解析角度数据
memcpy(&stcAngle, &ucRxBuffer[2], 8);
break;
// 可根据需要添加其他数据类型 case 0x54: 等
default:
break;
}
// 处理完一帧,重置计数,准备接收下一帧
ucRxCnt = 0;
}
}
3. 主函数初始化与数据使用
在主函数中初始化串口,然后在循环中处理或发送解析后的数据。
#include "stm32f10x.h"
#include "usart2.h" // 假设串口初始化代码放在这个头文件
int main(void) {
char str[50]; // 用于格式化输出
// 系统时钟等初始化
SystemInit();
// 初始化串口2,波特率设置为9600或115200
USART2_Init(9600);
while(1) {
// 示例:通过其他串口(如USART1)发送角度数据到上位机
sprintf(str, "Angle: %.3f %.3f %.3f\r\n",
(float)stcAngle.Angle[0]/32768*180, // 转换为度,假设量程±180°
(float)stcAngle.Angle[1]/32768*180,
(float)stcAngle.Angle[2]/32768*180);
// 假设UART1_SendString函数已实现,用于向串口助手发送数据
UART1_SendString(str);
// 延时,控制数据发送频率
Delay_ms(500);
}
}
参考代码 Jy901通过串口连接stm32f1x的源代码 www.3dddown.com/cna/71613.html
关键点与调试
- 数据解析与转换:从缓冲区提取的原始数据是字节,需按小端模式(低位字节在前)组合成
short或int型,再根据模块资料给出的量程和分辨率转换为有物理意义的量。 - 校验和:上述示例代码为了简洁,省略了校验和验证。在实际应用中,为增强通信可靠性,建议根据JY901的通信协议加上校验和检查。
- 连接与配置:
- 确保JY901模块的VCC和GND连接正确稳定。
- 确认STM32的串口波特率与JY901模块的输出波特率一致(常见9600或115200)。
- JY901模块通常支持主动输出模式,可能需要通过上位机配置其串口输出参数和数据类型。
- 调试技巧:
- 可以先将JY901的TX引脚连接到USB-TTL,直接接电脑,用串口助手(如sscom)查看其原始数据输出,确认模块工作正常和数据格式。
- 在STM32代码中,可以先将接收到的每一个字节通过另一个串口原样发送给PC,模拟"串口透传",帮助判断STM32是否正常接收。

浙公网安备 33010602011771号