#include "../main/SystemInclude.h" #if(DP2201_M0CONTROL) __SAMPLE_STATUS_BIT_TypeDef sampleState; u16 offsetRType, offsetGCFX; //u16 processNextTime, processIndex; u16 voltageDetected[ANX], adcGain; void SystemPolling(void) //轮询 { // if(mcuModeSleeping) LowPowerModeProcess();//进入低功耗模式 if(mucSaveParams==PARAMS_READY) SaveSysParams();//参数准备就绪,保存参数到Flash if(HWState.SampledOver) FlowRateDealAndOuputSub(); //采样结束,计算流量 if(comState.state.ReceivedData) ReceivedDataProcessing(); //一帧数据接收完成 } /*========================================================================================== //外部传感器设备 ==========================================================================================*/ void TestTemperatureInit(void)//温度测试初始化 { WriteWordRegister(CONFIG, CONVERSION); WriteByteRegister(RREG, RESULT_0_25_BIT); HWState.EnableTempInit = 0; } u32 tempLongInt; void TestTemperature(void)//温度测试/测量,获取TPCB { if(!HWState.EnableTempTest) return; if(HWState.EnableTempInit) return; voltageDetected[TPCB] = ReadWordRegister(TA);//获取传感器原始值 WriteWordRegister(CONFIG, SHUT_DOWN);//温度传感器禁用 voltageDetected[TPCB] &= 0x1fff; tempLongInt = (u32)(voltageDetected[TPCB] & 0xFFF); if(voltageDetected[TPCB] >= 0x1000) tempLongInt = 0xFFF - tempLongInt; tempLongInt *= 6400; // 0.0625*1024*100 tempLongInt >>= 10; // /1024 PCBTemperature = (u16)tempLongInt; // Temperature*100 voltageDetected[TPCB] =PCBTemperature; __NOP(); } /*========================================================================================== //数据采样 ==========================================================================================*/ /*********************************************************************/ //采样数据处理阶段 /*********************************************************************/ uint32_t data_array[64]; uint32_t sum = 0; uint32_t average = 0; void FlowRateDealAndOuputSub(void) { HWState.SampledOver = 0;//采样结束标志重置 ComputeFlowRateIndexAndFlowRate();//计算内码 转换成流量 TestTemperature();//计算PCB温度 // for (int i = 0; i < 64; i++) { // data_array[i] = rand(); // } // u32 *p=data_array; // TEST_PIN_TOGGLE(); // for (int i = 0; i < 64; i++) { // sum += *p++; // } // average = sum >> 6; } /*sampleData.TCode[CTCode]//VDU sampleData.TCode[RTCode]//VRR sampleData.TCode[HTCode]//VRH sampleData.TCode[ATCode]//IRH*/ void ComputeFlowRateIndexAndFlowRate(void) { voltageDetected[NIDX ]= (u16)sampleData.TCode[CTCode]; //8303 VDU1 voltageDetected[VRHX ]= (u16)sampleData.TCode[RTCode]; //8304 VRR voltageDetected[IVHDX]= (u16)sampleData.TCode[HTCode]; //8305 VRH voltageDetected[RHVOL]= (u16)sampleData.TCode[ATCode]; //8306 IRH voltageDetected[VDUGX]= (u16)sampleData.TCode[BTCode]; //8307 VDU2 //voltageDetected[FRIDX]=voltageDetected[NIDX]- offsetGas; //判断气体类型 //1---根据VRH原始值判断 // if(voltageDetected[IVHDX]<56000) voltageDetected[FRIDX]=voltageDetected[NIDX ]- offsetAir; //Air // else voltageDetected[FRIDX]=voltageDetected[VRHX ]- offsetAir; //H2 if(offsetAir)voltageDetected[FRIDX]=voltageDetected[NIDX ]- offsetGas; //Air else voltageDetected[FRIDX]=voltageDetected[VRHX ]- offsetGas; //H2 currentFlowRate = GetFlowRate(voltageDetected[FRIDX],CURVE_1ST); // flowRateH // flowRateL voltageDetected[FR_H] = currentFlowRate >> 16; voltageDetected[FR_L] = currentFlowRate&0xFFFF; // voltageDetected[VDUGX]= AirflowSensor_Read(); // voltageDetected[TPCB]= (u16)(Get_AirflowSensor_SCCM()); } u16 WordSubFunction(u16 minuend, u16 subtractor) { u16 subResult; subResult = minuend - subtractor; if(minuend >= subtractor) { if(subResult < 32768) subResult += 32768; else subResult = 65535; } else { if(subResult < 32768) subResult = 0; else subResult -= 32768; } return subResult; } /********************************************************************/ //采样阶段 /********************************************************************/ __Process_TypeDef flowProcess; //采样中断 void SamplingTimer_IRQ_Callback(void) { FlowProcessManagement(); // LHL_GPIO_TogglePin(pGPIO1, GPIO_PIN_7); } void StartNormolFlowMeasurement(void)//开始常规流量测量 { HWState.SampledOver = 0;//采样结束标志重置 StartSamplingTimerInterval(32768); //启动比较定时器,开始从0递增计数 Timer_register_irq_callback(SamplingTimer,SamplingTimer_IRQ_Callback );//注册中断回调函数 flowProcess.Index = 0; flowProcess.NextTime = 0; FlowProcessManagement();//每个周期运行,开启采样过程 } void SetNextProcess(void)//设置采样定时器的下一个进程 { if(flowProcess.Index == 0){ StopSamplingTimerInterval();//关闭采集时钟 return; } u32 currentTAR = SamplingTimer->CNT;//定时器当前计数值 if(currentTAR > flowProcess.NextTime) flowProcess.NextTime = currentTAR + 5; ResetSamplingTimerInterval(flowProcess.NextTime); } /*-----------------------------------------------------------------------------------------------------*/ __Samp_Buf_TypeDef sampleData; static void ADC0_Conversion_Init(ADC_BaseConfig_TypeDef* adc_config) { ADC_REF_Init(REF_INTERNAL_2P5V,REF_INTERNAL_2P5V);/* 1. 初始化内部基准源 */ ADC_Init(ADC_0, adc_config->SPS, adc_config->Gain, adc_config->PChan, adc_config->NChan); /* 2. 初始化ADC0 */ } //ADC1采样初始化---------------------------------------------------------- static void ADC1_Conversion_Init(ADC_BaseConfig_TypeDef* adc_config) { ADC_REF_Init(REF_INTERNAL_2P5V,REF_INTERNAL_2P5V);/* 1. 初始化内部基准源 */ ADC_Init(ADC_1, adc_config->SPS, adc_config->Gain, adc_config->PChan, adc_config->NChan); /* 2. 初始化ADC1 */ } void SetSampleSiagnlForSingleADC(const ADC_BaseConfig_TypeDef* adc_cfg) { sampleData.adcBaseCfg.Gain = adc_cfg->Gain; sampleData.adcBaseCfg.PChan = adc_cfg->PChan; sampleData.adcBaseCfg.NChan = adc_cfg->NChan; sampleData.adcBaseCfg.SPS = adc_cfg->SPS; } //ADC同步采样初始化---------------------------------------------------------- static void ADC0_1_SyncConversion_Init(ADC_SyncConfig_TypeDef* adc_config) { // ADC_REF_Init(REF_INTERNAL_2P5V,REF_INTERNAL_2P5V);/* 1. 初始化内部基准源 */ REF_InitTypeDef REF_InitStructure; REF_InitStructure.VREF = REF_INTERNAL_2P5V; // 内部基准电压 REF_InitStructure.VDRIVE = REF_INTERNAL_2P5V; // VDrive输出电压 REF_InitStructure.VREF_Boost = DISABLE; LHL_REF_Init(&REF_InitStructure); // LHL_ADC_SetVREF(REF_INTERNAL_2P5V, ENABLE); // LHL_ADC_SetVDRIVE(REF_INTERNAL_2P5V, ENABLE); ADC_Init(ADC_0, adc_config->SPS, adc_config->Gain0, adc_config->PChan0, adc_config->NChan0); /* 2. 初始化ADC0 */ ADC_Init(ADC_1, adc_config->SPS, adc_config->Gain1, adc_config->PChan1, adc_config->NChan1); /* 3. 初始化ADC1 */ ADC_SyncCmd(ENABLE);/* 4. ADC同步使能 */ } void SetSampleSiagnlForSyncADC(const ADC_SyncConfig_TypeDef* adc_cfg) { sampleData.adcSyncCfg.Gain0 = adc_cfg->Gain0; sampleData.adcSyncCfg.PChan0 = adc_cfg->PChan0; sampleData.adcSyncCfg.NChan0 = adc_cfg->NChan0; sampleData.adcSyncCfg.Gain1 = adc_cfg->Gain1; sampleData.adcSyncCfg.PChan1 = adc_cfg->PChan1; sampleData.adcSyncCfg.NChan1 = adc_cfg->NChan1; sampleData.adcSyncCfg.SPS = adc_cfg->SPS; } /* ====================================================================================================== adc中断采样流程说明: 1.设置:SetSampleSiagnlForSingleADC SetSampleSiagnlForSyncADC 2.开始:StartADC0SampingData StartADC1SampingData StartADCSyncSampingData 3.读取:IRQ ReadSamplingData 4.计算:ComputeSampleData ======================================================================================================*/ //转换完成中断 void ConversionIRQ_Callback(void) { if(sampleData.SkipSampNum) {sampleData.SkipSampNum -- ; return; } ReadSamplingData(); //读取采样数据 } //开始转换控制--------------------------------------------------------------- void StartADC0SampingData(void) { sampleData.ADCBuffer[0]=0; sampleData.Counter=0; sampleData.SkipSampNum = 3 ; ADC0_Conversion_Init(&sampleData.adcBaseCfg); ADC_register_irq_callback(ADC_0,ConversionIRQ_Callback); StartADC(ADC_0); } void StartADC1SampingData(void) { sampleData.ADCBuffer[1]=0; sampleData.Counter=0; sampleData.SkipSampNum = 3 ; ADC1_Conversion_Init(&sampleData.adcBaseCfg); ADC_register_irq_callback(ADC_1,ConversionIRQ_Callback); StartADC(ADC_1); } void StartADCSyncSampingData(void) { sampleData.ADCBuffer[0]=0; sampleData.ADCBuffer[1]=0; sampleData.Counter=0; sampleData.SkipSampNum = 3 ; #if 1 ADC0_1_SyncConversion_Init(&sampleData.adcSyncCfg); ADC_register_irq_callback(ADC_0,ConversionIRQ_Callback); StartADC(ADC_0);//只需开启ADC_0 #else NVIC_DisableIRQ(ADC0_IRQn); StartConversionTimerInterval(1);//1ms 定时器中断读取adc转换数据 Timer_register_irq_callback(ConversionTimer,ConversionIRQ_Callback );//注册timer2中断回调函数 #endif } void ReadSamplingData(void)//ADC中断读取采样数据 BPS { sampleData.ADCBuffer[0] += ADC_ReadData(ADC_0); //多重采样累计 sampleData.ADCBuffer[1] += ADC_ReadData(ADC_1); //多重采样累计 sampleData.Counter++; // 采样次数自增 } void ComputeSampleData(void) //计算样本数据 { StopADC(ADC_0); StopADC(ADC_1); if(sampleData.Counter != 0)//采集数量求平均 { sampleData.ADCBuffer[0] /= (u32)sampleData.Counter; sampleData.ADCBuffer[1] /= (u32)sampleData.Counter; } } /* ====================================================================================================== adc dma采样流程说明: 1.设置: SetSampleSiagnlForSingleADC SetSampleSiagnlForSyncADC 2.开始: StartDMAForADC0SampingData StartDMAForADC1SampingData StartDMAForADCSyncSampingData 3.传输完成: IRQ 标志位 4.计算: DMA_ComputeSampleData_ADC0 DMA_ComputeSampleData_ADC1 ======================================================================================================*/ //传输完成中断标志位 void DMAForADC0_Callback() { sampleData.DMA_ADC_adcflag[0] = 1; } void DMAForADC1_Callback() { sampleData.DMA_ADC_adcflag[1] = 1; } //开始转换控制--------------------------------------------------------------- void StartDMAForADC0SampingData(void) { ADC0_Conversion_Init(&sampleData.adcBaseCfg); DMA_ADC_Init(ADC_0,sampleData.DMA_ADC_Buffer[0],sampleData.DMA_ADC_SampLen+sampleData.SkipSampNum); DMA_register_irq_callback(DMA_CHANNEL_ADC_0,NULL,DMAForADC0_Callback); DMA_StartADC(ADC_0); } void StartDMAForADC1SampingData(void) { ADC0_Conversion_Init(&sampleData.adcBaseCfg); DMA_ADC_Init(ADC_1, sampleData.DMA_ADC_Buffer[1],sampleData.DMA_ADC_SampLen+sampleData.SkipSampNum); DMA_register_irq_callback(DMA_CHANNEL_ADC_1,NULL,DMAForADC1_Callback); DMA_StartADC(ADC_1); } void StartDMAForADCSyncSampingData(void) { ADC0_1_SyncConversion_Init(&sampleData.adcSyncCfg); DMA_ADC_Init(ADC_0,sampleData.DMA_ADC_Buffer[0],sampleData.DMA_ADC_SampLen+sampleData.SkipSampNum); DMA_ADC_Init(ADC_1,sampleData.DMA_ADC_Buffer[1],sampleData.DMA_ADC_SampLen+sampleData.SkipSampNum); DMA_register_irq_callback(DMA_CHANNEL_ADC_0,NULL,DMAForADC0_Callback); DMA_register_irq_callback(DMA_CHANNEL_ADC_1,NULL,DMAForADC1_Callback); DMA_StartADC(ADC_0); DMA_StartADC(ADC_1); } u16 DMA_ComputeSampleData_ADC0(void) { u16 adcCode; u32 adcCount; u8 i ; for(i = sampleData.SkipSampNum ; i < sampleData.DMA_ADC_SampLen ;i++) { adcCode = ((((sampleData.DMA_ADC_Buffer[0][i] & 0xFFFFFF) | ((sampleData.DMA_ADC_Buffer[0][i] & 0x800000) ? 0xFF000000 : 0)) >> 8) + 32768) & 0xFFFF;//处理成16位数据 adcCount += adcCode ; } adcCode = adcCount>>sampleData.DMA_ADC_Exponent; return adcCode; } u16 DMA_ComputeSampleData_ADC1(void) { u16 adcCode; u32 adcCount; u8 i ; for(u8 i = sampleData.SkipSampNum ; i < sampleData.DMA_ADC_SampLen ;i++) { adcCode = ((((sampleData.DMA_ADC_Buffer[1][i] & 0xFFFFFF) | ((sampleData.DMA_ADC_Buffer[1][i] & 0x800000) ? 0xFF000000 : 0)) >> 8) + 32768) & 0xFFFF;//处理成16位数据 adcCount += adcCode ; } adcCode = adcCount>>sampleData.DMA_ADC_Exponent; return adcCode; } /*用户同步采样信号配置数组*/ typedef enum { Signal_VDU_VRR, Signal_VDU1_VRH, Signal_VDU2_VRH, Signal_VDU1_IRH, Signal_VDU2_IRH, //...... Signals_Count, }ADC_CFG_Index_TypeDef; static const ADC_SyncConfig_TypeDef signal_cfgs[Signals_Count] = { [Signal_VDU_VRR] = { GAIN64, ADC0_AIN0, ADC0_AIN1, GAIN1, ADC1_AIN3, ADC1_AIN4 ,SPS_977 }, [Signal_VDU1_VRH] = { GAIN64, ADC0_AIN0, ADC0_AIN1, GAIN1, ADC1_AIN2, ADC1_AVSS ,SPS_977 }, [Signal_VDU2_VRH] = { GAIN128, ADC0_AIN0, ADC0_AIN1, GAIN1, ADC1_AIN2, ADC1_AVSS ,SPS_977 }, [Signal_VDU1_IRH] = { GAIN64, ADC0_AIN0, ADC0_AIN1, GAIN8, ADC1_AIN5, ADC1_AIN4 ,SPS_977 }, [Signal_VDU2_IRH] = { GAIN128, ADC0_AIN0, ADC0_AIN1, GAIN8, ADC1_AIN5, ADC1_AIN4 ,SPS_977 }, //...... }; /*sampleData.TCode[CTCode]//VDU sampleData.TCode[RTCode]//VRR sampleData.TCode[HTCode]//VRH sampleData.TCode[ATCode]//IRH*/ #define CLIBMODE 1 void FlowProcessManagement(void)//采样过程管理状态机 { switch(flowProcess.Index) { case 0: //Part1采样 VDU预采样与VRR采样 { HWState.SampledOver = 0;//采样开始 SetSampleSiagnlForSyncADC(&signal_cfgs[Signal_VDU_VRR]); StartADCSyncSampingData();//开始采集 flowProcess.NextTime += 653; //40ms 计数值= 65535/4000*t(t=40) = 653 flowProcess.Index = 1; }break; case 1: //Part2 Part4分支 VRR 与预采样结果 { ComputeSampleData(); //计算样本数据 sampleData.TCode[RTCode] = sampleData.ADCBuffer[1];//VRR 放入缓存 #if CLIBMODE if(flowProcess.State == 0) //下一个去Part2 VDU_VRH { SetSampleSiagnlForSyncADC(&signal_cfgs[Signal_VDU1_VRH]);//使用VDU1进行采集 } else //下一个去Part4 VDU_IRH { SetSampleSiagnlForSyncADC(&signal_cfgs[Signal_VDU2_IRH]);//使用VDU2进行采集 } #else u16 currt_vdu = sampleData.ADCBuffer[0];//预采样结果 if(flowProcess.State == 0) //下一个去Part2 VDU_VRH { if(currt_vdu)SetSampleSiagnlForADC(&signal_cfgs[Signal_VDU1_VRH]);//根据采样结果设置 else SetSampleSiagnlForADC(&signal_cfgs[Signal_VDU2_VRH]); } else //下一个去Part4 VDU_IRH { if(currt_vdu)SetSampleSiagnlForADC(&signal_cfgs[Signal_VDU1_IRH]);//根据采样结果设置 else SetSampleSiagnlForADC(&signal_cfgs[Signal_VDU2_IRH]); } #endif StartADCSyncSampingData();//开始采集 flowProcess.NextTime += 1048;//64ms flowProcess.Index = 2; }break; case 2: //Part3 { ComputeSampleData(); //计算样本数据 //Part2 Part4分支 #if CLIBMODE if(flowProcess.State == 0)//Part2 { sampleData.TCode[CTCode] = sampleData.ADCBuffer[0];//VDU1 放入缓存 sampleData.TCode[HTCode] = sampleData.ADCBuffer[1];//VRH 放入缓存 } else //Part4 { sampleData.TCode[BTCode] = sampleData.ADCBuffer[0];//VDU2 放入缓存 sampleData.TCode[ATCode] = sampleData.ADCBuffer[1];//IRH 放入缓存 } #else sampleData.TCode[CTCode] = sampleData.ADCBuffer[0];//VDU 放入缓存 if(flowProcess.State == 0)sampleData.TCode[HTCode] = sampleData.ADCBuffer[1];//VRH 放入缓存 else sampleData.TCode[ATCode] = sampleData.ADCBuffer[1];//IRH 放入缓存 #endif HWState.SampledOver = 1; //采样结束 StopSamplingTimerInterval();//关闭采集时钟 进入Part3 if(flowProcess.State) flowProcess.State = 0 ;//切换Part2 Part4 else flowProcess.State = 1 ; flowProcess.Index = 0; }break; default : flowProcess.Index = 0; break; } SetNextProcess(); } void DMA_sampleMainProcess(void)//DMA采样过程管理状态机 { volatile u8 DMA_State_Index; switch(DMA_State_Index) { case 0 : //67.68ms sps=977 if(HWState.SampledOver) return; HWState.SampledOver = 0; //采样开始 sampleData.SkipSampNum = 0 ; sampleData.DMA_ADC_SampLen = 16 ; sampleData.DMA_ADC_Exponent= 4; SetSampleSiagnlForSyncADC(&signal_cfgs[Signal_VDU_VRR]);// 设置采样信号 StartDMAForADCSyncSampingData(); // 开始采样 DMA_State_Index++; //TEST_PIN_TOGGLE(); break; case 1 : if(!sampleData.DMA_ADC_adcflag[0]) return; if(!sampleData.DMA_ADC_adcflag[1]) return; sampleData.DMA_ADC_adcflag[0]= 0; sampleData.DMA_ADC_adcflag[1]= 0; //TEST_PIN_TOGGLE(); sampleData.TCode[CTCode] = DMA_ComputeSampleData_ADC0(); sampleData.TCode[RTCode] = DMA_ComputeSampleData_ADC1(); sampleData.SkipSampNum = 0 ; sampleData.DMA_ADC_SampLen = 32 ; sampleData.DMA_ADC_Exponent= 5; SetSampleSiagnlForSyncADC(&signal_cfgs[Signal_VDU2_VRH]);// 设置采样信号 StartDMAForADCSyncSampingData(); // 开始采样 DMA_State_Index++; break; case 2 : if(!sampleData.DMA_ADC_adcflag[0]) return; if(!sampleData.DMA_ADC_adcflag[1]) return; sampleData.DMA_ADC_adcflag[0]= 0; sampleData.DMA_ADC_adcflag[1]= 0; sampleData.TCode[BTCode] = DMA_ComputeSampleData_ADC0(); sampleData.TCode[HTCode] = DMA_ComputeSampleData_ADC1(); sampleData.SkipSampNum = 0 ; sampleData.DMA_ADC_SampLen = 32 ; sampleData.DMA_ADC_Exponent= 5; SetSampleSiagnlForSyncADC(&signal_cfgs[Signal_VDU2_IRH]);// 设置采样信号 StartDMAForADCSyncSampingData(); // 开始采样 DMA_State_Index++; break; case 3 : if(!sampleData.DMA_ADC_adcflag[0]) return; if(!sampleData.DMA_ADC_adcflag[1]) return; sampleData.DMA_ADC_adcflag[0]= 0; sampleData.DMA_ADC_adcflag[1]= 0; sampleData.TCode[ATCode] = DMA_ComputeSampleData_ADC1(); HWState.SampledOver = 1; //采样结束 DMA_State_Index = 0 ; break; default : DMA_State_Index = 0 ; } } /*================================================================================*/ #endif