www.pudn.com > M26(2M).rar > BloodGlucose.c, change:2016-01-05,size:22013b


/*************************************************************************************************** 
	* Copyright (c) 2015, BIOHERMOS 
	* All rights reserved. 
	* 文件名称: BloodGlucose.c 
	* 摘 要:    血糖主函数 
	* 当前版本: V1.0, 易建, 2015-10-09 
	* 更改记录: 无 
***************************************************************************************************/ 
#include "BloodGlucose.h" 
 
#define     SUCCESS                     0                       // 测试阶段成功 
#define     NORMAL                      1                       // 正常测试状态 
#define     ERROE                       2                       // 故障 
 
// ADC采样类型 
#define     POLE_TYPE_SAMPLE            0 
#define     HTC_BG_SAMPLE               1 
 
// 采样通道 
#define     TEMP_CHANNEL                0                       // 温度通道 
#define     BG_CHANNEL                  1                       // BG通道 
#define     HCT_CHANNEL                 2                       // HCT通道 
 
 
// HCT通道检测到血压滴入的采样阈值 
// 血液未滴入时采样值    
#define     THRESHOLE_HCT               0X1000                  // 血液滴入试纸HCT通道识别阈值 
 
// BG通道检测到血压滴入的采样阈值 
// 血液未滴入时采样值   370 
#define     THRESHOLE_BG                0X1000                  // 血液滴入试纸HCT通道识别阈值 
 
// 血液从HCT电极到BG电极时间阈值 
#define     THRESHOLE_BLOOD_FLOW_TINE   15                      // 15*100MS = 1.5S 
 
#define     TEST_PAPER_IN               0                       // 试纸已经插入 
#define     TEST_PAPER_OUT              1                       // 试纸未插入 
 
 
u8  g_u8TimerCnt;                                               // 计数器 
u8  g_u8EnTimer;                                                // 定时器使 
u8  g_u8EnSineWave;                                             // hct正弦波 
u8  g_u8EnAdcSample;                                            // 使能ADC中断连续采样 
 
u8  g_u8TestPaperStatus;                                        // 试纸插入状态 
 
u8  g_u8HCT_EnSample;                                           // 使能采样 
u8  g_u8HCT_SampTime;                                           // HCT采样时间 
u8  g_u8BG_EnSample;                                            // 使能采样 
u8  g_u8HCT_DetStatus;                                          // HCT开始检测 
u8  g_u8BG_DetStatus;                                           // BG开始检测 
 
u8  g_u8EnSampDataSend;                                         // 使能数据发生 
u16 g_u16CountdownTimer;                                        // 倒计时计数器 
 
u16 g_u16HCT_SampData[SAMP_DATA_BUFF_LEN]; 
u16 g_u16BG_SampData[SAMP_DATA_BUFF_LEN]; 
u16 g_u16SendData[10]; 
 
u8  g_u8SendDataW; 
u8  g_u8SendDataR; 
u8  g_u8HCT_SampDataW; 
u8  g_u8HCT_SampDataR; 
u8  g_u8BG_SampDataW; 
u8  g_u8BG_SampDataR; 
 
static u8  s_u8MainPhase = 0;                                   // 
static u8  s_u8SubPhase;                                        // 
 
void Delay(u32 clk); 
void ADC_Disable(void); 
void ADC_SampleConfig(u8 channel); 
void ADC_StartSample(void); 
void ADC_WaitSmpComplete(void); 
u16  ADC_GetSmpResult(u8 channel); 
 
u8 TestPaperStatusDet(void);                                    // 试纸插入状态识别 
u8 BloodInsertDetect(void);                                     // 血液滴入识别 
u8 HCT_Detect(void);                                            // HCT通道检测 
u8 BG_Detect(void);                                             // BG通道检测 
 
/*************************************************************************************************** 
 * 函 数 名: BloodGlucose 
 * 功能描述: 血糖测试功能总结构 
 * 函数说明: 无 
 * 输  入: 无 
 * 返  回: 无 
***************************************************************************************************/ 
#define TEST_VAR_INIT           0               // 测试参数初始化 
#define PAPER_INSERT_DET        1               // 试纸插入状态识别 
#define BLOOD_INSET_DET         2               // 血液滴入识别 
#define HCT_DETECT              3               // HCT采样 
#define BG_DETECT               4               // BG采样 
#define PAPER_PULLOUT_DET       5               // 试纸拔出识别 
 
 
void BloodGlucose(void) 
{ 
    u8 ret; 
    switch (s_u8MainPhase) 
    { 
        // 测试参数初始化 
        case TEST_VAR_INIT: 
        { 
            g_u8EnAdcSample = FALSE; 
            s_u8SubPhase = 0; 
            s_u8MainPhase = PAPER_INSERT_DET; 
            break; 
        } 
        // 检测试纸插入 
        case PAPER_INSERT_DET: 
        { 
            /*ret = TestPaperStatusDet(); 
            if (ret == TEST_PAPER_IN) */ 
            { 
                KeyPressed = 0; 
                s_u8SubPhase = 0; 
                s_u8MainPhase = BLOOD_INSET_DET; 
            } 
            break; 
        } 
        // 血液滴入识别 
        case BLOOD_INSET_DET: 
        {/* 
            ret = BloodInsertDetect(); 
            if (ret == SUCCESS)*/ 
            if (KeyPressed) 
            { 
                KeyPressed = 0; 
                s_u8SubPhase = 0; 
                s_u8MainPhase = HCT_DETECT; 
            } 
            break; 
        }  
        // HCT测试 
        case HCT_DETECT: 
        { 
            ret = HCT_Detect(); 
            if (ret == SUCCESS) 
            { 
                s_u8SubPhase = 0; 
                s_u8MainPhase = BG_DETECT; 
            } 
            break; 
        } 
        // BG测试 
        case BG_DETECT: 
        { 
            ret = BG_Detect(); 
            if (ret == SUCCESS) 
            { 
                s_u8SubPhase = 0; 
                s_u8MainPhase = PAPER_PULLOUT_DET; 
            } 
            break; 
        } 
        // 试纸拔出识别 
        case PAPER_PULLOUT_DET: 
        {/* 
            ret = TestPaperStatusDet(); 
            if (ret == TEST_PAPER_OUT)*/ 
            { 
                s_u8SubPhase = 0; 
                s_u8MainPhase = TEST_VAR_INIT; 
            } 
            break; 
        } 
    } 
} 
 
/*************************************************************************************************** 
 * 函 数 名: TestPaperInsertDet 
 * 功能描述: 试纸插入识别 
 * 函数说明: 通过IO口状态判断试纸是否已经插入 
 * 输  入: 无 
 * 返  回: 插入状态 
***************************************************************************************************/ 
#define PAPER_DET_INIT              0               // 试纸插入识别初始化 
#define PAPER_DET                   1               // 试纸插入识别过程 
 
u8 TestPaperStatusDet(void) 
{ 
    static u8 a_u8InsertCnt = 0; 
    static u8 a_u8InsertBuff = 0; 
    u8 ret = 3; 
     
    switch (s_u8SubPhase) 
    { 
        // 准备检测试纸插入状态 
        case PAPER_DET_INIT: 
        { 
            AN_POWER_ON; 
            WAKEUP_POLE_LOW_OFF; 
            SCAN_POLE1_HIGH_OFF; 
            Delay(100); 
            SCAN_POLE1_LOW_ON; 
            WAKEUP_POLE_HIGH_ON; 
            a_u8InsertCnt = 0; 
            s_u8SubPhase = PAPER_DET; 
            break; 
        } 
        // 插入状态识别 
        case PAPER_DET: 
        { 
            if (WAKEUP_PIN_STATUSE == 0) 
            { 
                if (a_u8InsertBuff) 
                { 
                    a_u8InsertCnt = 0; 
                    a_u8InsertBuff = 0; 
                } 
                else 
                { 
                    a_u8InsertCnt++; 
                    if (a_u8InsertCnt > 10) 
                    { 
                        s_u8SubPhase = 0; 
                        ret = TEST_PAPER_IN;                    // 有试纸插入 
                    } 
                } 
            } 
            else 
            { 
                if (a_u8InsertBuff) 
                { 
                    a_u8InsertCnt = 0; 
                    a_u8InsertBuff = 0; 
                } 
                else 
                { 
                    a_u8InsertCnt++; 
                    if (a_u8InsertCnt > 10) 
                    { 
                        s_u8SubPhase = 0; 
                        ret = TEST_PAPER_OUT;                   // 无试纸插入 
                    } 
                } 
            } 
            break; 
        } 
        default: 
        { 
            a_u8InsertCnt = 0; 
            s_u8SubPhase = 0; 
            break; 
        } 
    } 
    return ret; 
} 
 
/*************************************************************************************************** 
 * 函 数 名: BloodInsertDetect 
 * 功能描述: 试纸中血液滴入识别 
 * 函数说明: 判断血液滴入速度是否正常 
 * 输  入: 无 
 * 返  回: 处理状态 
***************************************************************************************************/ 
#define HCT_BLOOD_DET_INIT          0               // HCT通道血液滴入识别初始化 
#define HCT_BLOOD_DET               1               // HCT通道血液滴入识别 
#define BG_BLOOD_DET_INIT           2               // BG通道血液滴入识别初始化 
#define BG_BLOOD_DET                3               // BG通道血液滴入识别 
u8 BloodInsertDetect(void) 
{ 
    u8 ret = NORMAL; 
    u16 SampleResult; 
    static u8 SampIndex = 0; 
    static u32 SampSum = 0; 
    switch (s_u8SubPhase) 
    { 
        // HCT通道血液滴入识别初始化 
        case HCT_BLOOD_DET_INIT: 
        { 
            SW_CHANNEL_HCT_ON; 
            SW_CHANNEL_BG_OFF; 
            SW_ISD_K_OFF; 
            SW_ISD_A_OFF; 
            SW_TEST_BG_OFF; 
            SW_TEST_HCT_OFF; 
             
            SampIndex = 0; 
            SampSum = 0; 
            g_u8EnSineWave = TURE;                              // 开始施加交流电 
            ADC_SampleConfig(HTC_BG_SAMPLE);                    // ADC配置为检测模式 
            s_u8SubPhase = HCT_BLOOD_DET; 
            break; 
        } 
        // HCT通道血液滴入识别 
        case HCT_BLOOD_DET: 
        { 
            ADC_StartSample();                                  // 开始采样 
            ADC_WaitSmpComplete(); 
            SampleResult = ADC_GetSmpResult(HCT_CHANNEL);       // 获取采样值 
            SampSum += SampleResult; 
            SampIndex++; 
            if (SampIndex >= 4) 
            { 
                SampIndex = 0; 
                SampSum = SampSum / 4; 
                if (SampSum > 1200) 
                { 
                    g_u8EnTimer = TURE;                             // 使能计时器 
                    s_u8SubPhase = BG_BLOOD_DET_INIT; 
                } 
                SampSum = 0; 
            } 
            break; 
        } 
        // BG通道血液滴入识别初始化 
        case BG_BLOOD_DET_INIT: 
        {    
            /* 
            g_u8EnSineWave = FALSE;                              // 移除交流电 
            SW_CHANNEL_HCT_OFF; 
            SW_CHANNEL_BG_ON; 
            SW_ISD_K_OFF; 
            SW_ISD_A_OFF; 
            SW_TEST_BG_OFF; 
            SW_TEST_HCT_OFF; 
            */ 
            s_u8SubPhase = BG_BLOOD_DET; 
            break; 
        } 
        // BG通道血液滴入识别 
        case BG_BLOOD_DET: 
        {/* 
            ADC_StartSample();                                  // 开始采样 
            ADC_WaitSmpComplete(); 
            SampleResult = ADC_GetSmpResult(BG_CHANNEL);        // 获取采样值 
            SampSum += SampleResult; 
            SampIndex++; 
            if (SampIndex >= 4) 
            { 
                SampIndex = 0; 
                SampSum = SampSum / 4; 
                if (SampSum > 530) 
                { 
                    g_u8EnTimer = FALSE; 
                    if (g_u8TimerCnt < THRESHOLE_BLOOD_FLOW_TINE) 
                    { 
                        s_u8SubPhase = HCT_BLOOD_DET_INIT; 
                        ret = SUCCESS; 
                    } 
                    else 
                    { 
                        s_u8SubPhase = HCT_BLOOD_DET_INIT; 
                        ret = ERROE; 
                    } 
                } 
                SampSum = 0; 
            }*/ 
            ret = SUCCESS; 
            break; 
        } 
        default: 
        { 
            s_u8SubPhase = HCT_BLOOD_DET_INIT; 
            break; 
        } 
    } 
    return ret; 
} 
 
/*************************************************************************************************** 
 * 函 数 名: HCT_Detect 
 * 功能描述: HCT测试 
 * 函数说明: 无 
 * 输  入: 无 
 * 返  回: 处理状态 
***************************************************************************************************/ 
#define HCT_DET_INIT            0                               // HCT通道检测初始化 
#define HCT_DET                 2                               // HCT测试 
u8 HCT_Detect(void) 
{ 
    static u32 SampSum = 0; 
    static u8 count = 0; 
    static u8 Rade = 0; 
    float delt; 
    u8 ret = NORMAL; 
    switch (s_u8SubPhase) 
    { 
        // 初始化 
        case HCT_DET_INIT: 
        { 
 
            g_u8EnSineWave = TURE;                              // 开始施加交流电 
            Delay(2000); 
            SW_CHANNEL_HCT_ON; 
            SW_CHANNEL_BG_OFF; 
            SW_ISD_K_ON; 
            SW_ISD_A_ON; 
            SW_TEST_BG_OFF; 
            SW_TEST_HCT_OFF; 
             
            Delay(2000); 
            g_u8HCT_SampDataR = 0; 
            g_u8HCT_SampDataW = 0; 
             
            //g_u8HCT_DetStatus = START_DEC; 
             
            g_u8HCT_EnSample = TURE;                            // 开始HCT采样 
            g_u8BG_EnSample = FALSE;                            // 停止BG采样 
            g_u8EnAdcSample = TURE; 
             
            ADC_SampleConfig(HTC_BG_SAMPLE);                    // ADC配置为检测模式 
             
            g_u16CountdownTimer = 30;//g_u8HCT_SampTime;             // 持续xx s; 
             
            s_u8SubPhase = 1; 
             
            SampSum = 0; 
            count = 0; 
            Rade = 0; 
            g_u8EnSampDataSend = 0; 
             
            break; 
        } 
        case 1: 
        {/* 
            if (Rade != g_u8HCT_SampDataW) 
            { 
                SampSum += g_u16HCT_SampData[Rade]; 
                count++; 
                if (count >= 4) 
                { 
                    count = 0; 
                    SampSum = SampSum / 4; 
                    if (SampSum >= 2000)*/ 
                    { 
                        s_u8SubPhase = HCT_DET; 
                        g_u8EnSampDataSend = 1; 
                        g_u8HCT_DetStatus = START_DEC; 
                        g_u8HCT_SampDataR = 0; 
                        g_u8HCT_SampDataW = 0; 
                        g_u16CountdownTimer = 50;//g_u8HCT_SampTime;             // 持续xx s; 
                        break; 
                    }/* 
                    SampSum = 0; 
                } 
                Rade++; 
                if (Rade >= SAMP_DATA_BUFF_LEN-1) 
                { 
                    Rade = 0; 
                } 
            } 
            break;*/ 
        } 
        // HCT测试 
        case HCT_DET: 
        { 
             
            if (g_u16CountdownTimer == 0) 
            { 
                g_u8HCT_EnSample = FALSE; 
                g_u8EnAdcSample = FALSE; 
                g_u8EnSineWave = FALSE;                         // 停止施加交流电 
                s_u8SubPhase = HCT_DET_INIT; 
                g_u8HCT_DetStatus = STOP_DEC; 
                SW_CHANNEL_HCT_OFF; 
                ret = SUCCESS; 
            } 
            break; 
        } 
        default: 
        { 
            s_u8SubPhase = HCT_DET_INIT; 
            break; 
        } 
    } 
    return ret; 
} 
 
/*************************************************************************************************** 
 * 函 数 名: BG_Detect 
 * 功能描述: BG测试 
 * 函数说明: 无 
 * 输  入: 无 
 * 返  回: 处理状态 
***************************************************************************************************/ 
#define BG_DET_INIT            0                                // BG通道检测初始化 
#define BG_DET                 1                                // BG测试 
u8 BG_Detect(void) 
{ 
    u8 ret = NORMAL; 
    switch (s_u8SubPhase) 
    { 
        case BG_DET_INIT: 
        { 
            ADC_SampleConfig(HTC_BG_SAMPLE);                    // ADC配置为检测模式 
 
            g_u8BG_SampDataR = 0; 
            g_u8BG_SampDataW = 0; 
            g_u16CountdownTimer = 20;                           // 持续8s; 
            g_u8BG_DetStatus = START_DEC; 
            s_u8SubPhase = BG_DET; 
             
            SINE_WAVE_OFF; 
            SW_CHANNEL_HCT_OFF; 
            SW_CHANNEL_BG_ON; 
            SW_ISD_K_ON; 
            SW_ISD_A_ON; 
            SW_TEST_BG_OFF; 
            SW_TEST_HCT_OFF; 
             
            g_u8HCT_EnSample = FALSE;                           // 结束HCT采样 
            g_u8BG_EnSample = TURE; 
            g_u8EnAdcSample = TURE; 
     
            break; 
        } 
        case BG_DET: 
        { 
            if (g_u16CountdownTimer == 0) 
            { 
                g_u8BG_EnSample = FALSE; 
                g_u8EnAdcSample = FALSE; 
                s_u8SubPhase = BG_DET_INIT; 
                g_u8BG_DetStatus = STOP_DEC; 
                SW_CHANNEL_BG_OFF; 
                ret = SUCCESS; 
            } 
            break; 
        } 
        default: 
        { 
            s_u8SubPhase = BG_DET_INIT; 
            break; 
        } 
    } 
    return ret; 
} 
 
 
 
/*************************************************************************************************** 
 * 函 数 名: ADC_Init 
 * 功能描述: ADC初始化 
 * 函数说明: 使用外部参考电源 
 * 输  入: 无 
 * 返  回: 无 
***************************************************************************************************/ 
void ADC_Disable(void) 
{ 
    ADC12CTL0 &= ~ENC;  
} 
 
/*************************************************************************************************** 
 * 函 数 名: ADC_SampleConfig 
 * 功能描述: ADC采样配置 
 * 函数说明: 无 
 * 输  入: 无 
 * 返  回: 无 
***************************************************************************************************/ 
void ADC_SampleConfig(u8 channel) 
{ 
    ADC12CTL0 &= ~ENC;  
    switch (channel) 
    { 
        case POLE_TYPE_SAMPLE: 
        { 
            ADC12CTL0 = ADC12ON + MSC + SHT0_2;             // ADC12 on, extend sampling time 
                                                            // to avoid overflow of results 
            ADC12CTL1  = CSTARTADD_1 + SHP + CONSEQ_1;      // Use sampling timer, repeated seq 
            ADC12MCTL0 = INCH_1 + SREF_7;                   // ref+=AVcc, channel = A1 
            ADC12MCTL1 = INCH_2 + SREF_7;                   // ref+=AVcc, channel = A2 
            ADC12MCTL2 = INCH_3 + SREF_7 + EOS;             // ref+=AVcc, channel = A3 
            break; 
        } 
        case HTC_BG_SAMPLE: 
        { 
            ADC12CTL0 = ADC12ON + MSC + SHT0_2;             // ADC12 on, extend sampling time 
                                                            // to avoid overflow of results 
            ADC12CTL1  = CSTARTADD_1 + SHP + CONSEQ_1;      // Use sampling timer, repeated seq 
            ADC12MCTL0 = INCH_0 + SREF_2;                   // ref+=AVcc, channel = A0 
            ADC12MCTL1 = INCH_5 + SREF_2;                   // ref+=AVcc, channel = A5 
            ADC12MCTL2 = INCH_6 + SREF_2 + EOS;             // ref+=AVcc, channel = A6 
            break; 
        } 
    } 
    ADC12CTL0 |= ENC; 
} 
 
/*************************************************************************************************** 
 * 函 数 名: ADC_StartSample 
 * 功能描述: ADC开始采样 
 * 函数说明: 无 
 * 输  入: 无 
 * 返  回: 无 
***************************************************************************************************/ 
void ADC_StartSample(void) 
{ 
    ADC12CTL0 |= ADC12SC; 
} 
 
/*************************************************************************************************** 
 * 函 数 名: ADC_WaitSmpComplete 
 * 功能描述: ADC采样完成 
 * 函数说明: 无 
 * 输  入: 无 
 * 返  回: 无 
***************************************************************************************************/ 
void ADC_WaitSmpComplete(void) 
{ 
    while (ADC12CTL1 & ADC12BUSY); 
} 
 
/*************************************************************************************************** 
 * 函 数 名: ADC_GetSmpResult 
 * 功能描述: 获取ADC采样结果 
 * 函数说明: 无 
 * 输  入: 无 
 * 返  回: 无 
***************************************************************************************************/ 
u16 ADC_GetSmpResult(u8 channel) 
{ 
    u16 ret; 
    switch (channel) 
    { 
        case TEMP_CHANNEL: 
        { 
            ret = ADC12MEM0; 
            break; 
        } 
        case BG_CHANNEL: 
        { 
            ret = ADC12MEM1; 
            break; 
        } 
        case HCT_CHANNEL: 
        { 
            ret = ADC12MEM2; 
            break; 
        } 
        default: 
        { 
            ret = 0; 
            break; 
        } 
    } 
    return ret; 
} 
 
/*************************************************************************************************** 
 * 函 数 名: HCT_SaveSampData 
 * 功能描述: 保存HCT采样数据 
 * 函数说明: 无 
 * 输  入: 无 
 * 返  回: 无 
***************************************************************************************************/ 
void HCT_SaveSampData(void) 
{ 
    g_u16HCT_SampData[g_u8HCT_SampDataW] = ADC_GetSmpResult(BG_CHANNEL); 
    g_u8HCT_SampDataW++; 
    if (g_u8HCT_SampDataW >= SAMP_DATA_BUFF_LEN) 
        g_u8HCT_SampDataW = 0; 
} 
 
/*************************************************************************************************** 
 * 函 数 名: BG_SaveSampData 
 * 功能描述: 保存BG采样数据 
 * 函数说明: 无 
 * 输  入: 无 
 * 返  回: 无 
***************************************************************************************************/ 
void BG_SaveSampData(void) 
{ 
    g_u16BG_SampData[g_u8BG_SampDataW]  = ADC_GetSmpResult(BG_CHANNEL); 
    g_u8BG_SampDataW++; 
    if (g_u8BG_SampDataW >= SAMP_DATA_BUFF_LEN-1) 
        g_u8BG_SampDataW = 0; 
}