Files
CHJ/user/Core/DP2201V01.c
2026-03-20 21:16:58 +08:00

597 lines
18 KiB
C
Executable File
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#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*tt=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