【前言】
最近拿到MAX32630FTHR开发板,结合一个国产的血氧传感器,读取他的血氧、心率。现分享如下。
【硬件】
1、MAX32630FTHR开发板
2、MKS血氧传感器
【开发环境】
MDK 5.41
【硬件连接】
MKS血氧传感器为串口接,因此项目使用到了开发板的两个串口,串口1做为Debug可,是通过DAPLINK外接出来的,串口2与MKS传器进行连接。
【串口初始化与读取】
debug传感,在官方的示例的SDK已经初始化了,主要描述串口2的初始化。
1、定义串口TX(P3_1)、RX(P3_0)结构体:
const gpio_cfg_t data_uart_rx = { PORT_3, PIN_0, GPIO_FUNC_GPIO, GPIO_PAD_INPUT }; const gpio_cfg_t data_uart_tx = { PORT_3, PIN_1, GPIO_FUNC_GPIO, GPIO_PAD_INPUT };
2、对串口进行配置:
GPIO_Config(&data_uart_tx); GPIO_Config(&data_uart_rx);
3、定义串口的结构体并进行配置:
const uart_cfg_t data_uart_cfg = { .parity = UART_PARITY_DISABLE, .size = UART_DATA_SIZE_8_BITS, .extra_stop = 0, .cts = 0, .rts = 0, .baud = 38400, }; const sys_cfg_uart_t data_sys_cfg = { .clk_scale = CLKMAN_SCALE_AUTO,//CLKMAN_SCALE_DIV_4, .io_cfg = IOMAN_UART(DATA_UART, IOMAN_MAP_A, IOMAN_MAP_UNUSED, IOMAN_MAP_UNUSED, 1, 1, 1) }; if ((err = UART_Init(MXC_UART_GET_UART(2), &data_uart_cfg, &data_sys_cfg)) != E_NO_ERROR) { MXC_ASSERT_FAIL(); return err; }
4、串口2接收代码:
while(MXC_UART2->rx_fifo_ctrl & MXC_F_UART_RX_FIFO_CTRL_FIFO_ENTRY) { data[state++] = MXC_UART2_FIFO->rx; }
这个接收就是读取UART2的rxfio_ctrl的接收buff是否为空,如果不为空读取MXC_UART2_FIFO->rx,直到读取不为空为止。
【MKS传感器操作】
1、根据MKS的用户手册,他的串口波特率为38400,因此初始化串口为38440。
2、开始转换的命令为0x8A,串口发送0x8A即可开始传换。
3、停止转换的命令为0x88,串口发送0x88即可停止传换。
4、数据解析
这个传感每1.28秒转换一次数据,发送来的88个字节其意义如下:
因此我编写简单的解析函数如下:
void task_mks(void *pvParameters) { // setupMksSensor(); stopMksMeasurement(); vTaskDelay(500); startMksMeasurement(); LOG("startmks\r\n"); int num= 0; uint8_t data[128] = {0}; int len=1; int state; state = 0; uint8_t mks_heart_rate; while(1) { while(MXC_UART2->rx_fifo_ctrl & MXC_F_UART_RX_FIFO_CTRL_FIFO_ENTRY) { data[state++] = MXC_UART2_FIFO->rx; } if(state>=88 && (data[0] == MKS_PACKET_HEADER)) { // 心率 (规格书第66字节 -> 缓冲区下标 65) [source: 27] mks_heart_rate = data[MKS_HR_INDEX]; // 血氧 (规格书第67字节 -> 缓冲区下标 66) [source: 27] mks_spo2 = data[MKS_SPO2_INDEX]; // --- 解析完成 --- mks_new_data_flag = true; // 设置新数据标志,通知 UI 更新 // 可选:打印解析的数据用于调试 printf("MKS Parsed: HR=%d, SpO2=%d\n", mks_heart_rate, mks_spo2); // 每次调用只处理一个完整的数据包,避免长时间阻塞主循环 state = 0; } vTaskDelay(5); } }
【效果展示】
可以看到检测到的数据还是比较稳定的。