基于STM32的血氧儀
一、簡(jiǎn)介
設(shè)計(jì)一款基于STM32的血氧儀,用于測(cè)量人體血氧飽和度和心率,并將測(cè)量結(jié)果顯示在LCD屏幕上。
本產(chǎn)品由STM32F103C8T6單片機(jī)最小系統(tǒng)+MAX30102傳感器+LCD顯示模塊+蜂鳴器模塊組成。
1.選擇合適的傳感器模塊,如MAX30102,用于采集紅光和紅外線信號(hào),并通過(guò)單片機(jī)IIC總線讀取。
2.使用STM32微控制器作為主控芯片,配置相應(yīng)的時(shí)鐘源和分頻系數(shù),開(kāi)啟需要使用的外設(shè)時(shí)鐘,包括GPIO口、ADC、LCD等。
3.根據(jù)傳感器模塊和LCD屏幕的接口要求,進(jìn)行相應(yīng)的GPIO口配置和LCD初始化操作。
二、功能需求
采集功能:能夠采集被測(cè)者的血氧飽和度和脈率信息,并進(jìn)行數(shù)字化處理。
顯示功能:通過(guò)LED數(shù)碼管、LCD顯示屏等方式直觀地呈現(xiàn)被測(cè)者的血氧飽和度和脈率信息。
報(bào)警功能:當(dāng)被測(cè)者的血氧飽和度低于設(shè)定閾值時(shí),能夠及時(shí)發(fā)出聲音或光閃提示,提醒用戶。
數(shù)據(jù)存儲(chǔ)功能:能夠?qū)⒉杉降难躏柡投群兔}率數(shù)據(jù)保存在內(nèi)部存儲(chǔ)器中,并具有查詢和導(dǎo)出功能。
操作簡(jiǎn)單:血氧儀的操作應(yīng)簡(jiǎn)單易懂,可以通過(guò)觸摸方式實(shí)現(xiàn)。
尺寸輕巧:血氧儀應(yīng)小巧便攜,方便隨身攜帶,適用于家庭、醫(yī)院、體育運(yùn)動(dòng)等場(chǎng)合。
高精度穩(wěn)定性:對(duì)于血氧飽和度和脈率的精度和穩(wěn)定性要求較高,需確保數(shù)據(jù)準(zhǔn)確可靠。
高安全性:血氧儀應(yīng)具有較高的安全性,避免對(duì)人體產(chǎn)生不良影響。
三、硬件設(shè)計(jì)
3.1電路分析
傳感器:血氧儀需要使用光學(xué)傳感器進(jìn)行血氧飽和度和脈率的采集。傳感器可以采用LED光源和光敏傳感器進(jìn)行測(cè)量,對(duì)傳感器的靈敏度、響應(yīng)速度等指標(biāo)進(jìn)行測(cè)試和優(yōu)化。
信號(hào)放大與濾波:為提高信號(hào)的穩(wěn)定性和精度,需要進(jìn)行信號(hào)放大和濾波處理??梢圆捎?a target="_blank">運(yùn)算放大器和低通濾波器進(jìn)行信號(hào)處理,調(diào)整增益和截止頻率以達(dá)到最佳效果。
顯示屏:血氧儀需要配備顯示屏進(jìn)行數(shù)據(jù)顯示。選擇LCD顯示屏作為顯示模塊。
控制器:血氧儀需要配備控制器進(jìn)行系統(tǒng)控制和數(shù)據(jù)處理。選擇STM32F103C8T6作為嵌入式微處理器。
3.2 MAX30102傳感器原理
兩個(gè)發(fā)光二極管,一個(gè)光檢測(cè)器,攜帶氧氣的紅血球能吸收較多紅外光(850-1000nm),未攜帶氧氣的紅血球則是吸收較多的紅外光(600-750nm),利用不同紅血球之吸收光譜的原理,來(lái)分析血氧飽和度。
四、軟件設(shè)計(jì)
4.1軟件設(shè)計(jì)框圖
4.2 MAX30102驅(qū)動(dòng)編寫(xiě)
4.2.1時(shí)鐘配置
設(shè)置系統(tǒng)時(shí)鐘源和分頻系數(shù),使得STM32能夠正常工作。
__HAL_RCC_GPIOB_CLK_ENABLE();
4.2.2外設(shè)初始化
開(kāi)啟需要使用的外設(shè)時(shí)鐘,并進(jìn)行相應(yīng)的GPIO口、LCD等外設(shè)初始化。
//使用模擬SPI ?GPIO_InitTypeDef GPIO_InitStruct = {0}; ? ?GPIO_InitStruct.Pin = GPIO_PIN_13|GPIO_PIN_15; ?GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; ?GPIO_InitStruct.Pull = GPIO_NOPULL; ?GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; ?HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
LCD屏初始化
void max30100_init(void) { ?max30100_Bus_Write(0x06, 0x0b); ?//mode configuration : temp_en[3] ? ? ?MODE[2:0]=010 HR only enabled ? ?011 SP02 enabled ?max30100_Bus_Write(0x01, 0xF0); //open all of interrupt ?max30100_Bus_Write(INTERRUPT_REG, 0x00); //all interrupt clear ?max30100_Bus_Write(0x09, 0x33); //r_pa=3,ir_pa=3 ? max30100_Bus_Write(0x02, 0x00); //set FIFO write Pointer reg = 0x00 for clear it ?max30100_Bus_Write(0x03, 0x00); ?//set Over Flow Counter ?reg = 0x00 for clear it ?max30100_Bus_Write(0x04, 0x0F); ?//set FIFO Read Pointer ?reg = 0x0f for ? ? ? ? ? ? ? ? ? ? ? ?//waitting ?write pointer eq read pointer ? to ? interrupts ?INTERRUPT_REG_A_FULL }
MAX30100驅(qū)動(dòng)程序
單片機(jī)通過(guò)I2C總線與傳感器模塊通信,獲取血氧、心率等數(shù)據(jù)。
//血液檢測(cè)信息更新 void blood_data_update(void) { ?uint16_t temp_num=0; ?uint16_t fifo_word_buff[1][2]; ? ?temp_num = max30100_Bus_Read(INTERRUPT_REG); ? ?//標(biāo)志位被使能時(shí) 讀取FIFO ?if (INTERRUPT_REG_A_FULL&temp_num) ?{ ? ?HAL_GPIO_WritePin(GPIOC,GPIO_PIN_13,1); ? ?//讀取FIFO ? ?max30100_FIFO_Read(0x05,fifo_word_buff,1); //read the hr and spo2 data form fifo in reg=0x05 ? ? ? ?//將數(shù)據(jù)寫(xiě)入fft輸入并清除輸出 ? ?for(int i = 0;i < 1;i++) ? ?{ ? ? ?if(g_fft_index < FFT_N) ? ? ?{ ? ? ? ?s1[g_fft_index].real = fifo_word_buff[i][0]; ? ? ? ?s1[g_fft_index].imag= 0; ? ? ? ?s2[g_fft_index].real = fifo_word_buff[i][1]; ? ? ? ?s2[g_fft_index].imag= 0; ? ? ? ?g_fft_index++; ? ? ?} ? ?} ? ?//信息更新標(biāo)志位 ? ?g_blooddata.update++; ?} ?else ?{ ? ?HAL_GPIO_WritePin(GPIOC,GPIO_PIN_13,0); ?} }
硬件初始化模塊:包括時(shí)鐘配置、外設(shè)初始化等。
數(shù)據(jù)處理模塊:對(duì)采集到的數(shù)據(jù)進(jìn)行處理,計(jì)算出血氧值和心率等指標(biāo),并將其顯示在LCD等界面上。
通信模塊:可以通過(guò)UART方式與其他設(shè)備進(jìn)行通信,將數(shù)據(jù)上傳至PC端進(jìn)行分析。
4.2.3計(jì)算血氧值和心率值
根據(jù)采集到的SPO2數(shù)據(jù)和心率數(shù)據(jù),進(jìn)行相應(yīng)的計(jì)算,得出血氧值和心率值。
4.2.3.1 雙波長(zhǎng)光吸收比值計(jì)算
雙波長(zhǎng)光吸收比值計(jì)算是血氧值計(jì)算算法的第一步,它通過(guò)傳感器模塊采集的紅光和紅外線信號(hào),計(jì)算出其在不同波長(zhǎng)下的吸收比值。一般需要進(jìn)行以下幾個(gè)步驟:
1.獲取紅光和紅外線信號(hào):
temp_num = max30100_Bus_Read(INTERRUPT_REG);
2.血氧飽和度計(jì)算:根據(jù)雙波長(zhǎng)光吸收比值和相關(guān)系數(shù),計(jì)算出血氧飽和度。
? ?//解平方 ? ?for(int i = 0;i < FFT_N;i++) ? ?{ ? ? ?s1[i].real=sqrtf(s1[i].real*s1[i].real+s1[i].imag*s1[i].imag); ? ? ?s2[i].real=sqrtf(s2[i].real*s2[i].real+s2[i].imag*s2[i].imag); ? ?}
3.計(jì)算紅光和紅外線信號(hào)比值:將紅光和紅外線信號(hào)分別除以一個(gè)參考值(如環(huán)境光強(qiáng)度),得到其相對(duì)強(qiáng)度,再將兩者相除,得到紅光/紅外線信號(hào)比值。
? ? ? ? ?//心率計(jì)算 ? ? ?uint16_t Heart_Rate = 60 * SAMPLES_PER_SECOND * ? ? ? ? ? ? ? ? ? ? ? ? ? ?s2_max_index / FFT_N; ? ? ? ? ? ?g_blooddata.heart = Heart_Rate - 10; ? ? ? ? ? ?//血氧含量計(jì)算 ? ? ?float sp02_num = (s2[s1_max_index].real * s1[0].real) ? ? ? ? ? ? ? ? ? ? ?/(s1[s1_max_index].real * s2[0].real); ? ? ? ? ? ?sp02_num = (1 - sp02_num) * SAMPLES_PER_SECOND + CORRECTED_VALUE; ? ? ? ? ? ?g_blooddata.SpO2 = sp02_num;
4.對(duì)比值進(jìn)行濾波
對(duì)紅光/紅外線信號(hào)比值進(jìn)行直流濾波處理,降低采集噪聲和干擾。
? ?//前8次求平均值 ?for(int i = 0;i < 8;i++) ?{ ? ?hbag ?+= s1[g_fft_index - 8 + i].real; ? ?hboag += s2[g_fft_index - 8 + i].real; ?} ? ? ?//直流濾波 ?hbag_d = dc_filter(hbag,&hbdc) / 8; ?hboag_d = dc_filter(hboag,&hbodc) / 8; ? ?//高度數(shù)據(jù) ?float hbhight ?= 0; ?float hbohight = 0; ? ?//比例與偏置 ?hbhight ?= (-hbag_d / 40.0) + 5; ?hbohight ?= (-hboag_d / 40.0) + 5; ? ?//高度數(shù)據(jù)幅度限制 ?hbhight = (hbhight > 27) ? 27 : hbhight; ?hbhight = (hbhight < 0) ? ?0 : hbhight; ? ?hbohight = (hbohight > 27) ? 27 : hbohight; ?hbohight = (hbohight < 0) ? ?0 : hbohight; ? ?//將數(shù)據(jù)發(fā)布到全局 ?g_BloodWave.Hp = hbhight; ?g_BloodWave.HpO2 = hbohight;
4.2.4顯示數(shù)據(jù)
將計(jì)算得到的血氧值和心率值,顯示在LCD等界面上
//測(cè)試顯示血液信息 void tft_test_display(void) { ?uint8_t str[50]; ?if (g_blooddata.display == 1) ?{ ? ?g_blooddata.display = 0; ? ? ? ?//顯示血氧信息 ? ?sprintf((char *)str,"heart = %3d",g_blooddata.heart); ? ?Gui_DrawFont_GBK16(8,8,0x00FF,BLACK,str); ? ? ? ?//顯示心率信息 ? ?sprintf((char *)str,"SpO2 = %3.1f",g_blooddata.SpO2); ? ?Gui_DrawFont_GBK16(8,26,0x00FF,BLACK,str); ? ? ? ?//顯示狀態(tài)信息 ? ?if(g_blooddata.state) ? ?{ ? ? ?sprintf((char *)str,"ERROR ? ? "); ? ? ?Gui_DrawFont_GBK16(8,44,0xF000,BLACK,str); ? ?} ? ?else ? ?{ ? ? ?sprintf((char *)str,"NORMAL ? ?"); ? ? ?Gui_DrawFont_GBK16(8,44,0x07E0,BLACK,str); ? ?} ?} }
五、實(shí)物演示
?
編輯:黃飛
評(píng)論