一、簡(jiǎn)介
續(xù)上部分,我們已經(jīng)介紹了硬件設(shè)計(jì)和軟件框圖,接下來(lái)進(jìn)行軟件的編寫和實(shí)物演示
二、軟件設(shè)計(jì)
2.1軟件設(shè)計(jì)框圖
2.2 MAX30102驅(qū)動(dòng)編寫
2.2.1時(shí)鐘配置
設(shè)置系統(tǒng)時(shí)鐘源和分頻系數(shù),使得STM32能夠正常工作。
__HAL_RCC_GPIOB_CLK_ENABLE();
2.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ù)寫入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);
}
}
1.硬件初始化模塊:包括時(shí)鐘配置、外設(shè)初始化等。
2.數(shù)據(jù)處理模塊:對(duì)采集到的數(shù)據(jù)進(jìn)行處理,計(jì)算出血氧值和心率等指標(biāo),并將其顯示在LCD等界面上。
3.通信模塊:可以通過(guò)UART方式與其他設(shè)備進(jìn)行通信,將數(shù)據(jù)上傳至PC端進(jìn)行分析。
2.2.3計(jì)算血氧值和心率值
根據(jù)采集到的SPO2數(shù)據(jù)和心率數(shù)據(jù),進(jìn)行相應(yīng)的計(jì)算,得出血氧值和心率值。
2.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;
2.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í)物演示
-
單片機(jī)
+關(guān)注
關(guān)注
6037文章
44558瀏覽量
635212 -
STM32
+關(guān)注
關(guān)注
2270文章
10900瀏覽量
355980 -
軟件設(shè)計(jì)
+關(guān)注
關(guān)注
3文章
58瀏覽量
17771 -
血氧儀
+關(guān)注
關(guān)注
2文章
131瀏覽量
24798 -
GPIO
+關(guān)注
關(guān)注
16文章
1204瀏覽量
52090
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論