这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » 综合技术 » 基础知识 » 【STM32H755】健康监护仪

共1条 1/1 1 跳转至

【STM32H755】健康监护仪

工程师
2025-10-03 21:15:37     打赏

【前言】

现在对健康的监护人们越来越需要高,国庆假期鼓捣一个健康监护仪,目前可以实现测心率、血氧、血压健康监护仪,现在分享如下:

【硬件】

1、NUCLEO-H755开发板。

2、ST7789LCD屏

3、健康监测模块 心率血氧检测模块反射式检测传感器

【程序框图】

image.png

CM4开启usart2,开启中断接收,当从CM7内核接收到OpenAMP的信号后,解析命,通过向传感器发送开始监测/停止监测的命。当开始监测后,传感器会周期的将数据回传给CM4。CM4接收到数据后,通过OpenAMP发送给CM7内核。

CM7开启了TouchGFX用户交互界面,当GUI点击开启转换后,通过OpenAMP向CM4内核发送开始/停止信号;同时如果OpenAMP接收到数据后,置位接收标志,在touchGFX的handleTickEvent周期函数,判断是否有数据更新,如何有更新,就将数据列新到的用户界面。

【GUI界面设计】

打开touchGFX Designer,制作界面如下:

image.png

界面中bntRun,添加一个虚拟函数,当按下后,判断其标签来实现按键按下事件,来通知CM4是否开启或者停止采集。

void screenView::funRun()
{
    // 获取bntRun的标签文本
    touchgfx::TypedText btnRunText = bntRun.getLabelText();
    
    // 判断按钮文本是否为"START"
    if (touchgfx::Unicode::strncmp(btnRunText.getText(), TypedText(T_START).getText(), 5) == 0)
    {
        // 改变按钮文本为"STOP"
			  MKS_RUN(0x8a);
        bntRun.setLabelText(touchgfx::TypedText(T_STOP));
        bntRun.invalidate();
    }
		else if (touchgfx::Unicode::strncmp(btnRunText.getText(), TypedText(T_STOP).getText(), 4) == 0)
		{
			// 改变按钮文本为"START"
				MKS_RUN(0x88);
        bntRun.setLabelText(touchgfx::TypedText(T_START));
        bntRun.invalidate();
		}
    // Override and implement this function in screen
}

在handleTickEvent事件中周期判断是否接到数据,如果有更新数据

void screenView::handleTickEvent()
{
    // 调用基类的处理函数
//    screenViewBase::handleTickEvent();
//    
    // 检查是否有新数据需要处理
    if (message_received == 1)
    {
        // 处理接收到的数据
        handleReceivedData();
        
        // 重置标志
        message_received = 0;
    }
}

void screenView::handleReceivedData()
{
	Unicode::snprintf(valHartBuffer,10,"%d",default_mks_params.heart);
	valHart.invalidate();
	Unicode::snprintf(valSpo2Buffer,10,"%d",default_mks_params.spo2);
	valSpo2.invalidate();
	Unicode::snprintf(valbpBuffer1, VALBPBUFFER1_SIZE, "%d", default_mks_params.diastolic_pressure);
	Unicode::snprintf(valbpBuffer2, VALBPBUFFER2_SIZE, "%d", default_mks_params.systolic_pressure);
	valbp.invalidate();
    
}

【CM7事件处理】

1、事件发送

void MKS_RUN(uint8_t state)
{
	if(state == 0x88)
	{
		default_mks_params.cmd = 0x88;
		OPENAMP_send(&rp_endpoint, &default_mks_params, sizeof(default_mks_params));
	}
	else if(state == 0x8A)
	{
		default_mks_params.cmd = 0x8A;
		OPENAMP_send(&rp_endpoint, &default_mks_params, sizeof(default_mks_params));
	}
}

当接收到touchGFX的命令,通OPENAMP_sen将事件发送给CM4。

2、事件接收

static int rpmsg_recv_callback(struct rpmsg_endpoint *ept, void *data,
                size_t len, uint32_t src, void *priv)
{
  default_mks_params = *((mks_control_params_t *) data);
  message_received=1;
  return 0;
}

当有从CM4的事件接收时,在此回函数,解析数据,并置位message_receivied置,touchGFX事件会即接收并完成数据的更新。

【CM4事件处理】

1、OpenAmp接收事件:

static int rpmsg_recv_callback(struct rpmsg_endpoint *ept, void *data,
               size_t len, uint32_t src, void *priv)
{
  default_mks_params = *((mks_control_params_t *) data);
	uint8_t txData;
	if(default_mks_params.cmd == 0x8A)
	{
		txData = 0x8A;
		HAL_UART_Transmit(&huart2,&txData,1,0xffff);
	}
	else if(default_mks_params.cmd == 0x88)
	{
		txData = 0x88;
		HAL_UART_Transmit(&huart2,&txData,1,0xffff);
	}
  return 0;
}

当有从CM7事件接收到时,向usart2即传感器转输命令,开始或停止数据采集。

2、中断回调

RT_PACK *rt_pack = (RT_PACK *)usart2_rx_buffer;  // ӳ�仺�������ṹ��
void HAL_UART_ErrorCallback(UART_HandleTypeDef *huart)
{
	if(huart->Instance == USART2)
	{
		UART_Start_Receive_IT(&huart2, usart2_buf, 1);
	}
}
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
    if(huart->Instance == USART2)
    {

        if(usart2_buf[0] == PACKET_HEADER)
        {

            usart2_rx_in_progress = 1;
            usart2_rx_count = 0;      
            usart2_rx_complete = 0;    
						usart2_rx_buffer[usart2_rx_count++] = usart2_buf[0];
        }

        else if(usart2_rx_in_progress)
        {

            if(usart2_rx_count < RECEIVE_LENGTH)
            {
                usart2_rx_buffer[usart2_rx_count++] = usart2_buf[0];
                
                if(usart2_rx_count >= RECEIVE_LENGTH)
                {
                    usart2_rx_complete = 1;   
                    usart2_rx_in_progress = 0; 
                }
            }
        }
        
    }
		UART_Start_Receive_IT(&huart2, usart2_buf, 1);
}


void process_rt_packet(void)
{
    if (usart2_rx_complete)  
    {
        if (rt_pack->head == 0xFF)
        {
            int8_t* ecg_wave = rt_pack->acdata;

            uint32_t heart_rate = rt_pack->heartrate;    
            uint32_t spo2_val = rt_pack->spo2;          
            uint8_t micro_circ = rt_pack->bk;          

            uint8_t fatigue_index = rt_pack->rsv[0];   
            uint32_t systolic_pressure = rt_pack->rsv[3]; 
            uint32_t diastolic_pressure = rt_pack->rsv[4]; 

            uint8_t sdann_val = rt_pack->sdann;        
            uint8_t rmssd_val = rt_pack->rmssd;       
            uint8_t* rr_interval = rt_pack->rra;       
            send_hart(heart_rate, spo2_val, systolic_pressure, diastolic_pressure);

        }
        usart2_rx_complete = 0;
    }
}

在这里按照程序框图,当判断接收到完整的一个数据包时,通过send_hart函数将参数传输出OpenAmp发送函数:

void send_hart(uint32_t heart,uint32_t spo2,uint8_t systolic_pressure,uint8_t diastolic_pressure)
{
  default_mks_params.heart = heart;
  default_mks_params.spo2 = spo2;
  default_mks_params.systolic_pressure = systolic_pressure;
  default_mks_params.diastolic_pressure = diastolic_pressure;
  OPENAMP_send(&rp_endpoint, &default_mks_params, sizeof(default_mks_params));
}

【实现效果】

470742ecf09879442f20c1abc8052c8d.jpg





关键词: STM32H755     监护仪    

共1条 1/1 1 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]