MS-DTU/Anjiehui7_TTS_ST_V2.4_LOCAL/User/adc_sample.c

1214 lines
40 KiB
C
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 "includes.h"
// 采集次数
#define SAMPLE_COUNT (20)
// 通过界面请求采集的标志
volatile uint8_t Config_Sample_Request = 0;
volatile uint8_t Config_Vacuum_Request = 0;
// 得到采集数据的通知
volatile uint8_t GPRS_semSampled = 0;
// 通知采集的信号量
SemaphoreHandle_t Sample_Semaphore = NULL; // 二值信号量句柄
// 通知充装匹配的信号量
SemaphoreHandle_t Match_Semaphore = NULL; // 二值信号量句柄
// 当前采集阶段
volatile uint8_t Sample_phase = 0;
// 采集是否忙
uint32_t Sample_Busy()
{
return (Sample_phase != 0);
}
// 通知采集
void Sample_Notify()
{
if(!Sample_Busy())
{
// 发送消息给任务
xSemaphoreGive(Sample_Semaphore);
}
}
// 通知采集
void Sample_NotifyFromISR()
{
BaseType_t xHigherPriorityTaskWoken;
if(!Sample_Busy())
{
// 发送消息给任务
xSemaphoreGiveFromISR(Sample_Semaphore, &xHigherPriorityTaskWoken);
}
}
// 处理泄露报警唤醒
void Leak_Handler(void)
{
if(Wakeup_Sleeping)
{
SysTick->CTRL |= (SysTick_CTRL_ENABLE_Msk | SysTick_CTRL_TICKINT_Msk);
delay_ms(10);
Vcc_Enable();
delay_ms(40);
Wakeup_Sleeping = 0;
printf("\n\nWake up by LEAK.\n\n");
}
// 采集数据
Sample_NotifyFromISR();
}
// 采集一个通道总共采集20次取中间10次的平均值
uint32_t Sample_ChannelOne(uint32_t channel)
{
uint32_t i;
uint32_t adc[SAMPLE_COUNT];
LL_ADC_REG_SetSequencerRanks(ADC1, LL_ADC_REG_RANK_1, channel);
for(i = 0; i < SAMPLE_COUNT; i++)
{
LL_ADC_REG_StartConversion(ADC1);
while(LL_ADC_REG_IsConversionOngoing(ADC1));
adc[i] = LL_ADC_REG_ReadConversionData12(ADC1);
}
sort(adc, SAMPLE_COUNT);
adc[0] = 0;
for(i = 0; i < (SAMPLE_COUNT / 2); i++)
adc[0] += adc[SAMPLE_COUNT / 4 + i];
i = adc[0] / (SAMPLE_COUNT / 2);
printf("\nchannel %d adc: %d, volt: %dmV\n", channel, i, i * 3000 / 4095);
return i;
}
void Sample_Init()
{
LL_GPIO_InitTypeDef GPIO_InitStruct = {0};
LL_EXTI_InitTypeDef EXTI_InitStruct = {0};
LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_GPIOA);
/**ADC1 GPIO Configuration
PA0 ------> ADC1_IN5AD5
PA1 ------> ADC1_IN6 (AD6)
PA5 ------> ADC1_IN10 (AD10)
PA6 ------> ADC1_IN11 (AD11)
PA7 ------> ADC1_IN12 (AD12)
*/
GPIO_InitStruct.Pin = LL_GPIO_PIN_0|LL_GPIO_PIN_1
|LL_GPIO_PIN_5|LL_GPIO_PIN_6|LL_GPIO_PIN_7;
GPIO_InitStruct.Mode = LL_GPIO_MODE_ANALOG;
GPIO_InitStruct.Pull = LL_GPIO_PULL_NO;
LL_GPIO_Init(GPIOA, &GPIO_InitStruct);
LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_GPIOB);
/**ADC1 GPIO Configuration
PB0 ------> ADC1_IN15AD_BAT)
*/
GPIO_InitStruct.Pin = LL_GPIO_PIN_0;
GPIO_InitStruct.Mode = LL_GPIO_MODE_ANALOG;
GPIO_InitStruct.Pull = LL_GPIO_PULL_NO;
LL_GPIO_Init(GPIOB, &GPIO_InitStruct);
LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_GPIOC);
/**ADC1 GPIO Configuration
PC0 ------> ADC1_IN1AD1)
PC1 ------> ADC1_IN2AD2)
PC2 ------> ADC1_IN3AD3)
PC3 ------> ADC1_IN4AD4)
*/
GPIO_InitStruct.Pin = LL_GPIO_PIN_0|LL_GPIO_PIN_1|LL_GPIO_PIN_2|LL_GPIO_PIN_3;
GPIO_InitStruct.Mode = LL_GPIO_MODE_ANALOG;
GPIO_InitStruct.Pull = LL_GPIO_PULL_NO;
LL_GPIO_Init(GPIOC, &GPIO_InitStruct);
// 泄露报警引脚
LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_GPIOE);
/**/
LL_SYSCFG_SetEXTISource(LL_SYSCFG_EXTI_PORTE, LL_SYSCFG_EXTI_LINE8);
// 创建信号量
if(Sample_Semaphore == NULL)
Sample_Semaphore = xSemaphoreCreateBinary();
if(Match_Semaphore == NULL)
Match_Semaphore = xSemaphoreCreateBinary();
/**/
EXTI_InitStruct.Line_0_31 = LL_EXTI_LINE_8;
EXTI_InitStruct.Line_32_63 = LL_EXTI_LINE_NONE;
EXTI_InitStruct.LineCommand = ENABLE;
EXTI_InitStruct.Mode = LL_EXTI_MODE_IT;
EXTI_InitStruct.Trigger = LL_EXTI_TRIGGER_RISING_FALLING;
LL_EXTI_Init(&EXTI_InitStruct);
/**/
LL_GPIO_SetPinPull(GPIOE, LL_GPIO_PIN_8, LL_GPIO_PULL_DOWN);
/**/
LL_GPIO_SetPinMode(GPIOE, LL_GPIO_PIN_8, LL_GPIO_MODE_INPUT);
}
void Sample_Open()
{
uint32_t vrefint_cal = *((volatile uint16_t *)(0x1fff75aa));
LL_ADC_InitTypeDef ADC_InitStruct = {0};
LL_ADC_REG_InitTypeDef ADC_REG_InitStruct = {0};
LL_ADC_CommonInitTypeDef ADC_CommonInitStruct = {0};
// 设置传感器状态
dcBuff.sampleData.vacuum[0].staVacuum = VACUUM_STATUS_COMM_FAULT;
dcBuff.sampleData.leak.staLeak = LEAK_STATUS_COMM_FAULT;
NVIC_SetPriority(EXTI9_5_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(),5, 0));
NVIC_EnableIRQ(EXTI9_5_IRQn);
/* Peripheral clock enable */
LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_ADC);
/** Common config
*/
ADC_InitStruct.Resolution = LL_ADC_RESOLUTION_12B;
ADC_InitStruct.DataAlignment = LL_ADC_DATA_ALIGN_RIGHT;
ADC_InitStruct.LowPowerMode = LL_ADC_LP_AUTOWAIT;
LL_ADC_Init(ADC1, &ADC_InitStruct);
ADC_REG_InitStruct.TriggerSource = LL_ADC_REG_TRIG_SOFTWARE;
ADC_REG_InitStruct.SequencerLength = LL_ADC_REG_SEQ_SCAN_DISABLE;
ADC_REG_InitStruct.SequencerDiscont = LL_ADC_REG_SEQ_DISCONT_DISABLE;
ADC_REG_InitStruct.ContinuousMode = LL_ADC_REG_CONV_SINGLE;
ADC_REG_InitStruct.DMATransfer = LL_ADC_REG_DMA_TRANSFER_NONE;
ADC_REG_InitStruct.Overrun = LL_ADC_REG_OVR_DATA_PRESERVED;
LL_ADC_REG_Init(ADC1, &ADC_REG_InitStruct);
LL_ADC_ConfigOverSamplingRatioShift(ADC1, LL_ADC_OVS_RATIO_16, LL_ADC_OVS_SHIFT_RIGHT_4);
LL_ADC_SetOverSamplingDiscont(ADC1, LL_ADC_OVS_REG_CONT);
LL_ADC_DisableIT_EOC(ADC1);
LL_ADC_DisableIT_EOS(ADC1);
LL_ADC_DisableDeepPowerDown(ADC1);
LL_ADC_EnableInternalRegulator(ADC1);
ADC_CommonInitStruct.CommonClock = LL_ADC_CLOCK_SYNC_PCLK_DIV4;
LL_ADC_CommonInit(__LL_ADC_COMMON_INSTANCE(ADC1), &ADC_CommonInitStruct);
/** Configure Regular Channel
*/
LL_ADC_SetChannelSamplingTime(ADC1, LL_ADC_CHANNEL_1, LL_ADC_SAMPLINGTIME_24CYCLES_5);
LL_ADC_SetChannelSingleDiff(ADC1, LL_ADC_CHANNEL_1, LL_ADC_SINGLE_ENDED);
LL_ADC_SetChannelSamplingTime(ADC1, LL_ADC_CHANNEL_2, LL_ADC_SAMPLINGTIME_24CYCLES_5);
LL_ADC_SetChannelSingleDiff(ADC1, LL_ADC_CHANNEL_2, LL_ADC_SINGLE_ENDED);
LL_ADC_SetChannelSamplingTime(ADC1, LL_ADC_CHANNEL_3, LL_ADC_SAMPLINGTIME_24CYCLES_5);
LL_ADC_SetChannelSingleDiff(ADC1, LL_ADC_CHANNEL_3, LL_ADC_SINGLE_ENDED);
LL_ADC_SetChannelSamplingTime(ADC1, LL_ADC_CHANNEL_4, LL_ADC_SAMPLINGTIME_24CYCLES_5);
LL_ADC_SetChannelSingleDiff(ADC1, LL_ADC_CHANNEL_4, LL_ADC_SINGLE_ENDED);
LL_ADC_SetChannelSamplingTime(ADC1, LL_ADC_CHANNEL_5, LL_ADC_SAMPLINGTIME_24CYCLES_5);
LL_ADC_SetChannelSingleDiff(ADC1, LL_ADC_CHANNEL_5, LL_ADC_SINGLE_ENDED);
LL_ADC_SetChannelSamplingTime(ADC1, LL_ADC_CHANNEL_6, LL_ADC_SAMPLINGTIME_24CYCLES_5);
LL_ADC_SetChannelSingleDiff(ADC1, LL_ADC_CHANNEL_6, LL_ADC_SINGLE_ENDED);
LL_ADC_SetChannelSamplingTime(ADC1, LL_ADC_CHANNEL_10, LL_ADC_SAMPLINGTIME_24CYCLES_5);
LL_ADC_SetChannelSingleDiff(ADC1, LL_ADC_CHANNEL_10, LL_ADC_SINGLE_ENDED);
LL_ADC_SetChannelSamplingTime(ADC1, LL_ADC_CHANNEL_11, LL_ADC_SAMPLINGTIME_24CYCLES_5);
LL_ADC_SetChannelSingleDiff(ADC1, LL_ADC_CHANNEL_11, LL_ADC_SINGLE_ENDED);
LL_ADC_SetChannelSamplingTime(ADC1, LL_ADC_CHANNEL_12, LL_ADC_SAMPLINGTIME_24CYCLES_5);
LL_ADC_SetChannelSingleDiff(ADC1, LL_ADC_CHANNEL_12, LL_ADC_SINGLE_ENDED);
LL_ADC_SetChannelSamplingTime(ADC1, LL_ADC_CHANNEL_15, LL_ADC_SAMPLINGTIME_24CYCLES_5);
LL_ADC_SetChannelSingleDiff(ADC1, LL_ADC_CHANNEL_15, LL_ADC_SINGLE_ENDED);
Sample_ReOpen();
}
// 休眠唤醒以后需重新执行该函数
void Sample_ReOpen()
{
// ADC硬件校验
VCC_SENSOR_5V_ON();
delay_ms(50);
LL_ADC_StartCalibration(ADC1, LL_ADC_SINGLE_ENDED);
while(LL_ADC_IsCalibrationOnGoing(ADC1));
VCC_SENSOR_5V_OFF();
}
void Sample_Task(void *p_arg)
{
uint16_t adc1, adc2;
data_dtu_t dtuSample;
data_sample_t sample;
uint32_t sample_time;
// 每隔8小时测一次真空上电第一次不测
uint32_t vacuum_seconds = 30, vaccuumTick = 0;
uint8_t lastLeakWarning = 0;
int16_t i;
uint32_t u32Sample;
static uint8_t charging = 0; // 记录充装状态
static uint32_t lowest_Sample = 0xFFFFFFFFul; // 记录液位最低点:初值为最大(用于判断充装开始)
static uint32_t highest_Sample = 0; // 记录液位最高点:初值为最小(用于判断充装结束)
static uint8_t stopGrowCount = 0; // 记录液位停止增长的次数
static uint32_t last_SampleTime = 0; // 记录充装判别的时间(间隔时间不能过短)
uint32_t totalSeconds;
static uint32_t last_volumePct = 0; // 记录上次的液位
static uint16_t last_Press = 0;
static int16_t last_Tempr = -300;
static uint16_t last_Vacuum = 0;
S_RTC_TIME_DATA_T sRTC;
// TTS协议
static uint32_t last_spanPct[20] = {0}; // 记录上次变化量的百分比基数
static uint32_t last_spanTime[20] = {0}; // 记录上次变化量的时间基数
static uint8_t last_spanCount = 0; // 记录条数
uint32_t span;
static uint32_t Match_Time = 0;
static uint8_t first = 1;
uint16_t adDPress_inhibition; // 4~20mA输入差压采集抑制量
static uint16_t last_adDPress = 0; // 记录上一个差压采集值
// 和远气体:紧急切断阀门的输出: 电磁阀默认打开
if(dcBuff.powerInfo.hardVer.major == 231)
KZ_VALUE_ENABLE();
while(1)
{
// 等待采集信号
xSemaphoreTake(Sample_Semaphore, portMAX_DELAY);
// 4~20mA输入差压采集抑制量当前采集值和上一个采集值相差满量程的±6‰范围内用上一个采集值代替当前值
adDPress_inhibition = (dcBuff.configSensor.sensorDPress.fullValue - dcBuff.configSensor.sensorDPress.zeroValue) / 166;
// 下一阶段:采集传感器数据
Sample_phase = 1;
// 获取当前时间
RTC_GetDateAndTime(&sRTC);
// 计算自上次gps定位以来的时间
sample_time = Calc_SecondsFromYear(INITIAL_YEAR, sRTC.u32Year, sRTC.u32Month, sRTC.u32Day,
sRTC.u32Hour, sRTC.u32Minute, sRTC.u32Second);
// 初始化缓冲区
memset(&sample, 0, sizeof(sample));
memset(&dtuSample, 0, sizeof(dtuSample));
// 设置传感器状态
sample.staExtPress[0].status = SENSOR_STATUS_NOCONNECT;
sample.staExtPress[1].status = SENSOR_STATUS_NOCONNECT;
sample.staExtPress[2].status = SENSOR_STATUS_NOCONNECT;
sample.staExtTempr[0].status = SENSOR_STATUS_NOCONNECT;
sample.staExtTempr[1].status = SENSOR_STATUS_NOCONNECT;
sample.staExtTempr[2].status = SENSOR_STATUS_NOCONNECT;
// Modbus传感器默认为沿用原来的数据
sample.vacuum[0] = dcBuff.sampleData.vacuum[0];
sample.leak = dcBuff.sampleData.leak;
sample.flow = dcBuff.sampleData.flow;
// 计算理论值
Calculate_Theoretical_Params();
if(!IS_VCC_SENSOR_5V_ON())
{
// 用于采集真空计的延时
vaccuumTick = GetDelayTick(15000);
VCC_SENSOR_5V_ON();
// 延时1s以后进入采集阶段
osDelay(1000);
if(dcBuff.configDisplay.op_USE_R0SEMOUNT) // 罗斯蒙特传感器,额外延时
osDelay(5000);
}
// 允许ADC
LL_ADC_Enable(ADC1);
while(!LL_ADC_IsActiveFlag_ADRDY(ADC1));
osDelay(10);
// 采集差压通道
if(!dcBuff.configDisplay.op_DIFF_420MA)
sample.adDPress = Sample_ChannelOne(LL_ADC_CHANNEL_5);
else
{
sample.adDPress = Sample_ChannelOne(LL_ADC_CHANNEL_10);
// 非标定采集,抑制跳动
if(!Config_Sample_Request)
{
if(last_adDPress > 0 &&
(sample.adDPress + adDPress_inhibition >= last_adDPress && sample.adDPress <= last_adDPress + adDPress_inhibition))
{
// 用上一个值代替当前值
sample.adDPress = last_adDPress;
}
else
{
// 以当前值作为比较基准
last_adDPress = sample.adDPress;
}
}
}
if(!dcBuff.configDisplay.op_USE_CAPACITY_SENSOR)
{
// 差压值
sample.staDPress.status = ADC_Validate(sample.adDPress,
dcBuff.configSensor.sensorDPress.zeroValue, dcBuff.configSensor.sensorDPress.fullValue);
if(sample.staDPress.status == SENSOR_STATUS_NORMAL)
{
sample.diff = ADC_Calculate(sample.adDPress,
dcBuff.configSensor.sensorDPress.zeroValue, dcBuff.configSensor.sensorDPress.fullValue,
dcBuff.configSensor.sensorDPress.lowRange, dcBuff.configSensor.sensorDPress.highRangeX10)
* (dcBuff.configSensor.sensorDPress.ishighRangeX10 ? 0.1 : 1);
}
}
// 采集压力通道
if(!dcBuff.configDisplay.op_PRESS_420MA)
sample.adPress = Sample_ChannelOne(LL_ADC_CHANNEL_6);
else
sample.adPress = Sample_ChannelOne(LL_ADC_CHANNEL_11);
sample.staPress.status = ADC_Validate(sample.adPress,
dcBuff.configSensor.sensorPress.zeroValue, dcBuff.configSensor.sensorPress.fullValue);
if(sample.staPress.status == SENSOR_STATUS_NORMAL)
{
sample.pressure = ADC_Calculate(sample.adPress,
dcBuff.configSensor.sensorPress.zeroValue, dcBuff.configSensor.sensorPress.fullValue,
dcBuff.configSensor.sensorPress.lowRange, dcBuff.configSensor.sensorPress.highRange);
}
// 扩展压力通道
if(!dcBuff.configDisplay.op_PRESS_420MA)
sample.adExtPress[0] = Sample_ChannelOne(LL_ADC_CHANNEL_11);
else
sample.adExtPress[0] = Sample_ChannelOne(LL_ADC_CHANNEL_6);
sample.staExtPress[0].status = ADC_Validate(sample.adExtPress[0],
dcBuff.configSensor.sensorEPress[0].zeroValue, dcBuff.configSensor.sensorEPress[0].fullValue);
if(sample.staExtPress[0].status == SENSOR_STATUS_NORMAL)
{
sample.extPressure[0] = ADC_Calculate(sample.adExtPress[0],
dcBuff.configSensor.sensorEPress[0].zeroValue, dcBuff.configSensor.sensorEPress[0].fullValue,
dcBuff.configSensor.sensorEPress[0].lowRange, dcBuff.configSensor.sensorEPress[0].highRange);
}
if(dcBuff.configDisplay.op_USE_PT100_SENSOR)
{
// 采集温度1
adc1 = Sample_ChannelOne(LL_ADC_CHANNEL_1);
adc2 = Sample_ChannelOne(LL_ADC_CHANNEL_2);
sample.adExtTempr[0] = PT100_CalResit(adc1, adc2);
if(dcBuff.configDisplay.op_LEVEL_SENSOR_ONLY)
sample.staExtTempr[0].status = SENSOR_STATUS_NOCONNECT;
else
sample.staExtTempr[0].status = ADC_Validate(sample.adExtTempr[0],
PT100_Resis[0] * dcBuff.configDisplay.op_PT100_MULTI, PT100_Resis[sizeof(PT100_Resis) / sizeof(float) - 1] * dcBuff.configDisplay.op_PT100_MULTI);
if(sample.staExtTempr[0].status == SENSOR_STATUS_NORMAL)
{
sample.extTempr[0] = PT100_CalTempr(adc1, adc2,
dcBuff.configSensor.sensorPTempr[0].calibrateT, dcBuff.configSensor.sensorPTempr[0].calibrateR);
}
}
else
{
// 采集温度1
sample.adExtTempr[0] = Sample_ChannelOne(LL_ADC_CHANNEL_12);
sample.staExtTempr[0].status = ADC_Validate(sample.adExtTempr[0],
dcBuff.configSensor.sensorMTempr[0].zeroValue, dcBuff.configSensor.sensorMTempr[0].fullValue);
if(sample.staExtTempr[0].status == SENSOR_STATUS_NORMAL)
{
sample.extTempr[0] = ADC_Calculate(sample.adExtTempr[0],
dcBuff.configSensor.sensorMTempr[0].zeroValue, dcBuff.configSensor.sensorMTempr[0].fullValue,
dcBuff.configSensor.sensorMTempr[0].lowRange, dcBuff.configSensor.sensorMTempr[0].highRange);
}
}
// 采集温度2
adc1 = Sample_ChannelOne(LL_ADC_CHANNEL_3);
adc2 = Sample_ChannelOne(LL_ADC_CHANNEL_4);
sample.adExtTempr[1] = PT100_CalResit(adc1, adc2);
if(dcBuff.configDisplay.op_LEVEL_SENSOR_ONLY)
sample.staExtTempr[1].status = SENSOR_STATUS_NOCONNECT;
else
sample.staExtTempr[1].status = ADC_Validate(sample.adExtTempr[1],
PT100_Resis[0] * dcBuff.configDisplay.op_PT100_MULTI, PT100_Resis[sizeof(PT100_Resis) / sizeof(float) - 1] * dcBuff.configDisplay.op_PT100_MULTI);
if(sample.staExtTempr[1].status == SENSOR_STATUS_NORMAL)
{
sample.extTempr[1] = PT100_CalTempr(adc1, adc2,
dcBuff.configSensor.sensorPTempr[1].calibrateT, dcBuff.configSensor.sensorPTempr[1].calibrateR);
}
// 采集电池电压通道
// 为了避免ADC模块的使用冲突测量电压和传感器采样在一起执行
// 因称重传感器未用故将电池电压的adc值存放在称重传感器的位置
sample.adWeight = Sample_ChannelOne(LL_ADC_CHANNEL_15);
if(dcBuff.configDisplay.op_USE_O2_LEAK)
{
if(VCC_POWER_STATUS())
{
// 读取O2浓度传感器
Sensor_ReadLeakO2(&sample);
while(!IsTickOut(modbus_outTick))
osDelay(1);
}
}
else
{
// 读取泄露报警
sample.leak.typeLeak = LEAK_TYPE_SWITCH;
if(VCC_LEAK_STATUS())
{
sample.leak.staLeak = LEAK_STATUS_A2_ALARM;
sample.leak.concentrations = 1;
}
else
{
sample.leak.staLeak = LEAK_STATUS_OK;
sample.leak.concentrations = 0;
// 重启泄露报警
Leak_Alarm_Enabled = 1;
}
}
if(VCC_POWER_STATUS())
{
// Modbus采集流量计
Sensor_ReadFlow(&sample);
while(!IsTickOut(modbus_outTick))
osDelay(1);
}
// 是否到采集时间3秒误差
if(Config_Vacuum_Request || sample_time + 3 >= vacuum_seconds)
{
if(Config_Vacuum_Request)
{
// 强制采集真空计
Config_Vacuum_Request = 0;
}
else
{
// 下次上传时再采
vacuum_seconds = sample_time + dcBuff.configData.intervalTrans;
}
// 真空计需要额外延时
while(vaccuumTick > 0 && !IsTickOut(vaccuumTick))
osDelay(1);
// 如果不断电,下次采集真空计不用延时
vaccuumTick = 0;
// 读取真空数据
Sensor_ReadVacuum(0, &sample);
while(!IsTickOut(modbus_outTick))
osDelay(1);
if(sample.vacuum[0].staVacuum == VACUUM_STATUS_COMM_FAULT)
{
Sensor_ReadVacuum(0, &sample);
while(!IsTickOut(modbus_outTick))
osDelay(1);
}
if(sample.vacuum[0].staVacuum == VACUUM_STATUS_COMM_FAULT)
{
Sensor_ReadVacuum(0, &sample);
while(!IsTickOut(modbus_outTick))
osDelay(1);
}
}
// 无外部供电或者太阳能电池电压低于4.5v
if((!dcBuff.configDisplay.op_LOCAL_DISP_1S && !dcBuff.configDisplay.op_USE_R0SEMOUNT) || !VCC_POWER_STATUS() || (dcBuff.configDisplay.op_USE_SOLAR && dcBuff.dtuData.batVoltage <= 4500))
VCC_SENSOR_5V_OFF();
// 电容传感器
if(dcBuff.configDisplay.op_USE_CAPACITY_SENSOR && sample.staDPress.status != SENSOR_STATUS_NOCONNECT)
{
if(sample.adDPress == 0xFFFF) // 短路
sample.staDPress.status = SENSOR_STATUS_OVERFLOW;
else
{
// 根据底电容、增长电容判断状态
sample.staDPress.status = ADC_Validate(sample.diff * 10,
dcBuff.configSensor.sensorCap.baseC, dcBuff.configSensor.sensorCap.baseC + dcBuff.configSensor.sensorCap.refC);
}
}
// 总容积
sample.volumeTotal = Theoretical_Param.v;
if(dcBuff.configBottle.measureType == MEASURE_DPRESS && sample.staDPress.status == SENSOR_STATUS_NORMAL)
{
if(!dcBuff.configDisplay.op_USE_CAPACITY_SENSOR)
{
// 液位
if(!dcBuff.configDisplay.op_USE_HEIGHT_LEVEL && !dcBuff.configDisplay.op_USE_PCT_LEVEL)
sample.height = Diff2Level(sample.diff); // 单位mm
else if(!dcBuff.configDisplay.op_USE_PCT_LEVEL)
sample.height = sample.diff; // 直接测量液位高度单位mm
else
sample.height = sample.diff * 100; // 直接测量液位百分比单位0.01%
}
else
{
// 根据底电容、增长电容计算液位高度
sample.height = Cap_Calculate(sample.diff * 10,
dcBuff.configSensor.sensorCap.baseC, dcBuff.configSensor.sensorCap.refC);
}
if(!dcBuff.configDisplay.op_USE_PCT_LEVEL && dcBuff.configSensor.levelOutMMWC == 0)
{
// 体积
sample.volume = Level2Vol(sample.height);
// 质量
sample.weight = Vol2Quantity(sample.volume);
// 充装比
if(sample.volume >= Theoretical_Param.ve)
sample.volumePct = dcBuff.configBottle.chargePct * 100;
else
sample.volumePct = (float) sample.volume / sample.volumeTotal * 10000;
}
else
{
if(dcBuff.configSensor.levelOutMMWC > 0)
{
// 充装比
if(KPa2mmH2O(sample.diff) >= dcBuff.configSensor.levelOutMMWC)
sample.volumePct = dcBuff.configBottle.chargePct * 100;
else
sample.volumePct = KPa2mmH2O(sample.diff) / dcBuff.configSensor.levelOutMMWC * 10000;
}
else
{
// 充装比
if(sample.diff >= dcBuff.configBottle.chargePct)
sample.volumePct = dcBuff.configBottle.chargePct * 100;
else
sample.volumePct = sample.diff * 100;
}
// 体积
sample.volume = Theoretical_Param.ve * (sample.volumePct / 10000.0);
// 质量
sample.weight = Vol2Quantity(sample.volume);
}
}
// 防过充输出
if(dcBuff.configDisplay.op_ANTI_OVERFILL)
{
if((dcBuff.configBottle.measureType == MEASURE_WEIGHT && sample.staWeight.status == SENSOR_STATUS_NORMAL) ||
(dcBuff.configBottle.measureType == MEASURE_DPRESS && sample.staDPress.status == SENSOR_STATUS_NORMAL))
{
if(dcBuff.configBottle.fullPct > 0 && sample.volumePct >= dcBuff.configBottle.fullPct)
Charge_Enabled = 0;
// 任何情况下,防过充始终有效
if(Charge_Enabled != last_Charge_Enabled)
{
Charge_Pulse_Time = GetDelayTick(1000);
if(Charge_Enabled)
KZ_CHARGE_ENABLE_HIGH();
else
{
if(dcBuff.configDisplay.op_ANTI_SINGLE_CTRL)
KZ_CHARGE_ENABLE_LOW();
else
KZ_CHARGE_DISABLE_HIGH();
}
}
// 保存当前充装允许状态
last_Charge_Enabled = Charge_Enabled;
}
}
// 常开电磁阀防过充输出(气动关闭)
if(dcBuff.configDisplay.op_ANTI_NORM_OPEN)
{
if((dcBuff.configBottle.measureType == MEASURE_WEIGHT && sample.staWeight.status == SENSOR_STATUS_NORMAL) ||
(dcBuff.configBottle.measureType == MEASURE_DPRESS && sample.staDPress.status == SENSOR_STATUS_NORMAL))
{
// 当液位降到满液位之下10%,重启防过充检测
if(dcBuff.configBottle.fullPct > 0 && sample.volumePct < dcBuff.configBottle.fullPct - 10 * 100)
Anti_Enabled = 1;
if(dcBuff.configBottle.fullPct > 0 && sample.volumePct >= dcBuff.configBottle.fullPct)
{
if(Anti_Enabled)
{
// 气动泵关闭300秒
KZ_NORM_OPEN_DISABLE();
Anti_Pulse_Time = GetDelayTick(300000ul);
// 不再重复检测
Anti_Enabled = 0;
}
}
}
}
// 声光报警输出
if(dcBuff.configDisplay.op_ALARM_OUTPUT)
{
if((dcBuff.configBottle.measureType == MEASURE_WEIGHT && sample.staWeight.status == SENSOR_STATUS_NORMAL) ||
(dcBuff.configBottle.measureType == MEASURE_DPRESS && sample.staDPress.status == SENSOR_STATUS_NORMAL))
{
// 当液位降到满液位之下10%,重启声光报警检测
// 当液位高于满液位之下10%,声光报警状态不变(一直报警状态 或 手动关闭状态)
if(dcBuff.configBottle.fullPct > 0 && sample.volumePct < dcBuff.configBottle.fullPct - 10 * 100)
Alarm_Enabled = 1;
// 当液位高于满液位,且未手动关闭,则打开报警
if(dcBuff.configBottle.fullPct > 0 && sample.volumePct >= dcBuff.configBottle.fullPct)
{
if(Alarm_Enabled && VCC_POWER_STATUS() && (!dcBuff.configDisplay.op_USE_SOLAR || dcBuff.dtuData.batVoltage > 4500))
{
KZ_ALARM_ON();
Alarm_Output = 1;
}
}
}
}
// 泄露报警的输出
if(dcBuff.configDisplay.op_LEAK_ALARM_OUTPUT)
{
if(VCC_POWER_STATUS() && (!dcBuff.configDisplay.op_USE_SOLAR || dcBuff.dtuData.batVoltage > 4500)
&& sample.leak.staLeak == LEAK_STATUS_A2_ALARM)
{
if(Leak_Alarm_Enabled && VCC_POWER_STATUS() && (!dcBuff.configDisplay.op_USE_SOLAR || dcBuff.dtuData.batVoltage > 4500))
{
KZ_ALARM_ON();
Leak_Alarm_Output = 1;
}
}
}
// 强制低液位报警输出
if(dcBuff.configDisplay.op_LOW_ALARM_OUTPUT)
{
if((dcBuff.configBottle.measureType == MEASURE_WEIGHT && sample.staWeight.status == SENSOR_STATUS_NORMAL) ||
(dcBuff.configBottle.measureType == MEASURE_DPRESS && sample.staDPress.status == SENSOR_STATUS_NORMAL))
{
// 当液位升到空液位之上10%,重启低液位输出指示
// 当液位低于空液位之上10%,低液位指示状态不变(一直报警状态 或 手动关闭状态)
if(dcBuff.configBottle.emptyPct > 0 && sample.volumePct >= dcBuff.configBottle.emptyPct + 10 * 100)
Low_Alarm_Enabled = 1;
// 当液位低于空液位,且未手动关闭,则打开报警
if(dcBuff.configBottle.emptyPct > 0 && sample.volumePct <= dcBuff.configBottle.emptyPct)
{
if(Low_Alarm_Enabled && VCC_POWER_STATUS() && (!dcBuff.configDisplay.op_USE_SOLAR || dcBuff.dtuData.batVoltage > 4500))
{
KZ_ALARM_ON();
Low_Alarm_Output = 1;
}
}
}
}
// 默认低液位报警输出
if(!dcBuff.configDisplay.op_ALARM_OUTPUT && !dcBuff.configDisplay.op_LEAK_ALARM_OUTPUT && !dcBuff.configDisplay.op_LOW_ALARM_OUTPUT)
{
// 检查是否满足输出条件: 有外供电且测量值正常
if((dcBuff.configBottle.measureType == MEASURE_WEIGHT && sample.staWeight.status == SENSOR_STATUS_NORMAL) ||
(dcBuff.configBottle.measureType == MEASURE_DPRESS && sample.staDPress.status == SENSOR_STATUS_NORMAL))
{
// 当液位升到空液位之上10%,重启低液位输出指示
// 当液位低于空液位之上10%,低液位指示状态不变
if(dcBuff.configBottle.emptyPct > 0 && sample.volumePct >= dcBuff.configBottle.emptyPct + 10 * 100)
KZ_LOW_ALARM_OFF();
if(dcBuff.configBottle.emptyPct > 0 && sample.volumePct <= dcBuff.configBottle.emptyPct)
{
if(VCC_POWER_STATUS() && (!dcBuff.configDisplay.op_USE_SOLAR || dcBuff.dtuData.batVoltage > 4500))
KZ_LOW_ALARM_ON();
}
}
}
// 高压力报警
if(dcBuff.configDisplay.op_PRESS_ALARM_OUTPUT)
{
if(sample.staPress.status == SENSOR_STATUS_NORMAL)
{
// 当压力降到报警值之下0.05Mpa,重启高压力输出指示
// 当压力高于报警值之下0.05Mpa,高压力指示状态不变(一直报警状态 或 手动关闭状态)
if(dcBuff.configBottle.warnPressH > 0 && sample.pressure + 50 <= dcBuff.configBottle.warnPressH)
Press_Alarm_Enabled = 1;
// 当压力高于报警值,且未手动关闭,则打开报警
if(dcBuff.configBottle.warnPressH > 0 && sample.pressure >= dcBuff.configBottle.warnPressH)
{
if(Press_Alarm_Enabled && VCC_POWER_STATUS() && (!dcBuff.configDisplay.op_USE_SOLAR || dcBuff.dtuData.batVoltage > 4500))
{
KZ_ALARM_ON();
Press_Alarm_Output = 1;
}
}
}
}
// 低压力报警
if(dcBuff.configDisplay.op_LOW_PRESS_ALARM_OUTPUT)
{
if(sample.staPress.status == SENSOR_STATUS_NORMAL)
{
// 当压力升到报警值之上0.05Mpa,重启低压力输出指示
// 当压力低于报警值之上0.05Mpa,低压力指示状态不变(一直报警状态 或 手动关闭状态)
if(dcBuff.configBottle.warnPress > 0 && sample.pressure >= dcBuff.configBottle.warnPress + 50)
Low_Press_Alarm_Enabled = 1;
// 当压力低于报警值,且未手动关闭,则打开报警
if(dcBuff.configBottle.warnPress > 0 && sample.pressure <= dcBuff.configBottle.warnPress)
{
if(Low_Press_Alarm_Enabled && VCC_POWER_STATUS() && (!dcBuff.configDisplay.op_USE_SOLAR || dcBuff.dtuData.batVoltage > 4500))
{
KZ_ALARM_ON();
Low_Press_Alarm_Output = 1;
}
}
}
}
// 双压力报警版本
if(dcBuff.powerInfo.hardVer.major == 232)
{
if(sample.staExtPress[0].status == SENSOR_STATUS_NORMAL)
{
// 当压力降到报警值之下0.05Mpa,重启高压力输出指示
// 当压力高于报警值之下0.05Mpa,高压力指示状态不变(一直报警状态 或 手动关闭状态)
if(sample.extPressure[0] + 50 <= 2500)
ExtPress_Alarm_Enabled = 1;
// 当压力高于报警值,且未手动关闭,则打开报警
if(sample.extPressure[0] >= 2500)
{
if(ExtPress_Alarm_Enabled && VCC_POWER_STATUS() && (!dcBuff.configDisplay.op_USE_SOLAR || dcBuff.dtuData.batVoltage > 4500))
{
KZ_ALARM_ON();
ExtPress_Alarm_Output = 1;
}
}
// 当压力升到报警值之上0.05Mpa,重启低压力输出指示
// 当压力低于报警值之上0.05Mpa,低压力指示状态不变(一直报警状态 或 手动关闭状态)
if(sample.extPressure[0] >= 100 + 50)
Low_ExtPress_Alarm_Enabled = 1;
// 当压力低于报警值,且未手动关闭,则打开报警
if(sample.extPressure[0] <= 100)
{
if(Low_ExtPress_Alarm_Enabled && VCC_POWER_STATUS() && (!dcBuff.configDisplay.op_USE_SOLAR || dcBuff.dtuData.batVoltage > 4500))
{
KZ_ALARM_ON();
Low_ExtPress_Alarm_Output = 1;
}
}
}
}
// 无外供电,不输出声光报警,恢复到初始状态
if(!VCC_POWER_STATUS() || (dcBuff.configDisplay.op_USE_SOLAR && dcBuff.dtuData.batVoltage <= 4500))
{
KZ_ALARM_OFF();
KZ_LOW_ALARM_OFF();
Alarm_Output = 0;
Low_Alarm_Output = 0;
Leak_Alarm_Output = 0;
Press_Alarm_Output = 0;
Low_Press_Alarm_Output = 0;
ExtPress_Alarm_Output = 0;
Low_ExtPress_Alarm_Output = 0;
Alarm_Enabled = 1;
Low_Alarm_Enabled = 1;
Leak_Alarm_Enabled = 1;
Press_Alarm_Enabled = 1;
Low_Press_Alarm_Enabled = 1;
ExtPress_Alarm_Enabled = 1;
Low_ExtPress_Alarm_Enabled = 1;
}
// 低液位指示输出
// 检查是否满足输出条件: 有外供电且测量值正常
if(VCC_POWER_STATUS() && (!dcBuff.configDisplay.op_USE_SOLAR || dcBuff.dtuData.batVoltage > 4500)
&& dcBuff.configBottle.emptyPct > 0
&& ((dcBuff.configBottle.measureType == MEASURE_WEIGHT && sample.staWeight.status == SENSOR_STATUS_NORMAL) ||
(dcBuff.configBottle.measureType == MEASURE_DPRESS && sample.staDPress.status == SENSOR_STATUS_NORMAL)))
{
// 当液位升到空液位之上10%,重启低液位输出指示
// 当液位低于空液位之上10%,低液位指示状态不变
if(sample.volumePct >= dcBuff.configBottle.emptyPct + 10 * 100)
KZ_LOW_LEVEL_OFF();
if(sample.volumePct <= dcBuff.configBottle.emptyPct)
KZ_LOW_LEVEL_ON();
}
else // 不能输出指示,恢复到初始状态
KZ_LOW_LEVEL_OFF();
// 高液位指示输出
// 检查是否满足输出条件: 有外供电且测量值正常
if(VCC_POWER_STATUS() && (!dcBuff.configDisplay.op_USE_SOLAR || dcBuff.dtuData.batVoltage > 4500)
&& dcBuff.configBottle.fullPct > 0
&& ((dcBuff.configBottle.measureType == MEASURE_WEIGHT && sample.staWeight.status == SENSOR_STATUS_NORMAL) ||
(dcBuff.configBottle.measureType == MEASURE_DPRESS && sample.staDPress.status == SENSOR_STATUS_NORMAL)))
{
// 当液位降到满液位之下10%,重启高液位输出指示
// 当液位高于满液位之下10%,高液位指示状态不变
if(sample.volumePct <= dcBuff.configBottle.fullPct - 10 * 100)
KZ_LEVEL_OFF();
if(sample.volumePct >= dcBuff.configBottle.fullPct)
KZ_LEVEL_ON();
}
else // 不能输出指示,恢复到初始状态
KZ_LEVEL_OFF();
// 和远气体:紧急切断阀门的输出
if(dcBuff.powerInfo.hardVer.major == 231)
{
if(VCC_POWER_STATUS() && (!dcBuff.configDisplay.op_USE_SOLAR || dcBuff.dtuData.batVoltage > 4500)
&& sample.leak.staLeak != LEAK_STATUS_COMM_FAULT && sample.leak.staLeak != LEAK_STATUS_FAULT
&& sample.staExtTempr[0].status == SENSOR_STATUS_NORMAL)
{
if(sample.leak.staLeak == LEAK_STATUS_A2_ALARM || sample.extTempr[0] <= -35)
KZ_VALUE_DISABLE();
else if(sample.leak.staLeak == LEAK_STATUS_OK && sample.extTempr[0] >= -30)
KZ_VALUE_ENABLE();
}
else if(!VCC_POWER_STATUS() || (dcBuff.configDisplay.op_USE_SOLAR && dcBuff.dtuData.batVoltage <= 4500))
KZ_VALUE_DISABLE();
}
if((dcBuff.configBottle.measureType == MEASURE_WEIGHT && sample.staWeight.status == SENSOR_STATUS_NORMAL)
|| (dcBuff.configBottle.measureType == MEASURE_DPRESS && sample.staDPress.status == SENSOR_STATUS_NORMAL))
{
// 不设置储罐参数以mmWC作为报警门限的单位
if(dcBuff.configDisplay.op_DISP_MMWC_ONLY && !dcBuff.configDisplay.op_USE_PCT_LEVEL)
{
if(!dcBuff.configDisplay.op_USE_CAPACITY_SENSOR && !dcBuff.configDisplay.op_USE_HEIGHT_LEVEL)
u32Sample = (uint32_t) KPa2mmH2O(sample.diff);
else
u32Sample = (uint32_t) sample.height;
}
else // 以液量百分比作为报警门限的单位
u32Sample = sample.volumePct;
// 判别液位报警点
if(dcBuff.configBottle.fullPct > 0 &&
last_volumePct < dcBuff.configBottle.fullPct && u32Sample >= dcBuff.configBottle.fullPct)
sample.warnning = 1;
if(dcBuff.configBottle.priPct > 0 &&
last_volumePct > dcBuff.configBottle.priPct && u32Sample <= dcBuff.configBottle.priPct)
sample.warnning = 1;
if(dcBuff.configBottle.orderPct > 0 &&
last_volumePct > dcBuff.configBottle.orderPct && u32Sample <= dcBuff.configBottle.orderPct)
sample.warnning = 1;
if(dcBuff.configBottle.emptyPct > 0 &&
last_volumePct > dcBuff.configBottle.emptyPct && u32Sample <= dcBuff.configBottle.emptyPct)
sample.warnning = 1;
// TTS, 判别液位低点
if(dcBuff.configBottle.serverVer == 3)
{
// 液位低点
if(dcBuff.configBottle.floorLevel > 0 &&
last_volumePct > dcBuff.configBottle.floorLevel && u32Sample <= dcBuff.configBottle.floorLevel)
sample.warnning = 1;
}
// 记录上次采集的值
last_volumePct = u32Sample;
// 判别充装状态
RTC_GetDateAndTime(&sRTC);
totalSeconds = Calc_SecondsFromYear(INITIAL_YEAR, sRTC.u32Year, sRTC.u32Month, sRTC.u32Day,
sRTC.u32Hour, sRTC.u32Minute, sRTC.u32Second);
if(last_SampleTime == 0 || totalSeconds + 3 >= last_SampleTime + 300)
{
if(dcBuff.configBottle.measureType == MEASURE_WEIGHT)
u32Sample = sample.weight;
else if(!dcBuff.configDisplay.op_USE_CAPACITY_SENSOR && !dcBuff.configDisplay.op_USE_HEIGHT_LEVEL && !dcBuff.configDisplay.op_USE_PCT_LEVEL)
u32Sample = (uint32_t) KPa2mmH2O(sample.diff);
else
u32Sample = (uint32_t) sample.height;
if(!dcBuff.configDisplay.op_BOX_VER)
{
// 如果液位高于历史最低点+60mmWC/kg开始充装并计时
if(!charging)
{
// 记录液位最低点
if(u32Sample < lowest_Sample)
lowest_Sample = u32Sample;
if(u32Sample >= lowest_Sample + 120)
{
charging = 1;
Wakeup_SetAlarm(1);
sample.warnning = 1;
stopGrowCount = 0;
highest_Sample = u32Sample; // 重置液位最高点初值
printf("\n*** Charging warnning ***\n");
}
}
else
{
// 记录液位最高点
if(u32Sample > highest_Sample)
{
stopGrowCount = 0;
highest_Sample = u32Sample;
}
// 如果液位不高于最高液位
if(u32Sample <= highest_Sample)
{
stopGrowCount++;
if(stopGrowCount >= 3)
{
charging = 0;
sample.warnning = 1;
lowest_Sample = u32Sample; // 重置液位最低点初值
printf("\n*** Stop charging warnning ***\n");
}
}
}
}
// TTS, 判别变化量报警
if(dcBuff.configBottle.serverVer == 3)
{
// 一段时间内的变化量
if(dcBuff.configBottle.span > 0) // 变化量参数有效
{
for(i = 0; i < last_spanCount; i++)
{
if(totalSeconds <= last_spanTime[i] + dcBuff.configBottle.spanPeriod)
{
if(sample.volumePct >= last_spanPct[i])
span = sample.volumePct - last_spanPct[i];
else
span = last_spanPct[i] - sample.volumePct;
if(span >= dcBuff.configBottle.span * 100)
{
sample.warnning = 1;
break;
}
}
}
}
if(last_spanCount >= 20)
{
for(i = 0; i < last_spanCount - 1; i++)
{
last_spanPct[i] = last_spanPct[i + 1];
last_spanTime[i] = last_spanTime[i + 1];
}
last_spanCount--;
}
last_spanPct[last_spanCount] = sample.volumePct;
last_spanTime[last_spanCount] = totalSeconds;
last_spanCount++;
}
// 记录判断时间
last_SampleTime = totalSeconds;
}
if(sample.warnning)
printf("\n*** Level warnning ***\n");
// 设置充装标志
sample.charging = charging;
}
// 判断是否压力报警
if(!dcBuff.configDisplay.op_LEVEL_SENSOR_ONLY)
{
if(sample.staPress.status == SENSOR_STATUS_NORMAL)
{
if(dcBuff.configBottle.warnPress > 0 && last_Press > dcBuff.configBottle.warnPress && sample.pressure <= dcBuff.configBottle.warnPress)
sample.warnning = 1;
if(dcBuff.configBottle.warnPressH > 0 && last_Press < dcBuff.configBottle.warnPressH && sample.pressure >= dcBuff.configBottle.warnPressH)
sample.warnning = 1;
// 记录采集值
last_Press = sample.pressure;
}
}
// 判断是否温度报警
if(dcBuff.configBottle.serverVer != 3 && !dcBuff.configDisplay.op_LEVEL_SENSOR_ONLY)
{
if(sample.staExtTempr[0].status == SENSOR_STATUS_NORMAL)
{
if(dcBuff.configBottle.warnTempr > -300 && last_Tempr > dcBuff.configBottle.warnTempr && sample.extTempr[0] <= dcBuff.configBottle.warnTempr)
sample.warnning = 1;
if(dcBuff.configBottle.warnTemprH > -300 && last_Tempr < dcBuff.configBottle.warnTemprH && sample.extTempr[0] >= dcBuff.configBottle.warnTemprH)
sample.warnning = 1;
// 记录采集值
last_Tempr = sample.extTempr[0];
}
}
// 判断是否真空度报警
if(dcBuff.configBottle.serverVer != 3 && sample.vacuum[0].staVacuum == VACUUM_STATUS_OK)
{
if(dcBuff.configBottle.warnVacuumH > 0 && last_Vacuum < dcBuff.configBottle.warnVacuumH * 0.01 && sample.vacuum[0].vacuum >= dcBuff.configBottle.warnVacuumH * 0.01)
sample.warnning = 1;
// 记录采集值
last_Vacuum = sample.vacuum[0].vacuum;
}
// 槽车防过充匹配
if(!dcBuff.configDisplay.op_SEND_GPS_DATA && !dcBuff.configDisplay.op_BOX_VER && RF_initStatus && (charging || Manual_Charing))
{
if((dcBuff.configBottle.measureType == MEASURE_WEIGHT && sample.staWeight.status == SENSOR_STATUS_NORMAL) ||
(dcBuff.configBottle.measureType == MEASURE_DPRESS && sample.staDPress.status == SENSOR_STATUS_NORMAL))
{
if(dcBuff.configBottle.fullPct > 0 && sample.volumePct >= dcBuff.configBottle.fullPct)
Match_Charging = 0;
if(dcBuff.configBottle.fullPct > 0 && sample.volumePct < dcBuff.configBottle.fullPct - 10 * 100)
Match_Charging = 1;
if((Match_Charging == 0 && (!Truck_Matched || Truck_Charging)) // 充满,立即发送,然后不再发送
|| (Match_Charging == 1 && totalSeconds + 3 >= Match_Time + 60)) // 充装中或1分钟发送一次
{
Match_Time = totalSeconds;
// 发送消息到任务,进行充装匹配
xSemaphoreGive(Match_Semaphore);
}
}
}
// 如果非充装状态,匹配复位
if(!dcBuff.configDisplay.op_SEND_GPS_DATA && !dcBuff.configDisplay.op_BOX_VER && RF_initStatus && (!charging && !Manual_Charing))
{
Match_Charging = 1; // 回持区间,未充满
Match_Time = 0;
Truck_Matched = 0;
Truck_Charging = 0;
}
// 写入全局缓冲(保持报警标志,直到发送任务处理)
if(dcBuff.sampleData.warnning)
sample.warnning = 1;
dcBuff.sampleData = sample;
if((dcBuff.sampleData.leak.staLeak == LEAK_STATUS_A2_ALARM) != lastLeakWarning)
{
printf("\n*** Leak warnning: %d ***\n", (dcBuff.sampleData.leak.staLeak == LEAK_STATUS_A2_ALARM));
dcBuff.sampleData.warnning = 1;
// 首次检测到泄露或停止泄露,立即发送数据
DTU_semGPRS = 1;
}
lastLeakWarning = (dcBuff.sampleData.leak.staLeak == LEAK_STATUS_A2_ALARM);
// 如果没有扩展温度,且有真空计温度,用真空计温度代替扩展温度(显示和上传)
if(dcBuff.sampleData.staExtTempr[0].status == SENSOR_STATUS_NOCONNECT)
{
if(dcBuff.sampleData.vacuum[0].staVacuum != VACUUM_STATUS_COMM_FAULT && dcBuff.sampleData.vacuum[0].staVacuum != VACUUM_STATUS_FAULT)
{
dcBuff.sampleData.extTempr[0] = dcBuff.sampleData.vacuum[0].tempr;
dcBuff.sampleData.staExtTempr[0].status = SENSOR_STATUS_NORMAL;
}
}
// 读取电池电压
if(DS2788_ReadBattery(&dtuSample))
{
dcBuff.dtuData.batLow = dtuSample.batLow;
dcBuff.dtuData.batCurrent = dtuSample.batCurrent;
dcBuff.dtuData.batPct = dtuSample.batPct;
dcBuff.dtuData.batCapa = dtuSample.batCapa;
dcBuff.dtuData.batMaxCapa = dtuSample.batMaxCapa;
dcBuff.dtuData.batTempr = dtuSample.batTempr;
dcBuff.dtuData.batVoltage = dtuSample.batVoltage;
}
// 禁止ADC
LL_ADC_Disable(ADC1);
// 通知发送任务采集完成
GPRS_semSampled = 1;
// 通知显示板采集完成
Config_Sample_Request = 0;
// 通知显示屏: 刷新
xSemaphoreGive(Key_Semaphore); //Form_Refresh(); //这个函数未做互斥,有可能冲突
// 刷新电流输出
DAC7311_Refresh();
/* Get the conversion result */
if(!dcBuff.configDisplay.op_USE_CAPACITY_SENSOR)
printf("\nConversion result of diff: \t\t%02X, %.1f kPa", sample.staDPress.status, sample.diff);
else
printf("\nConversion result of capa: \t\t%02X, %.1f pF", sample.staDPress.status, sample.diff);
// printf("\nConversion result of press: \t\t%02X, %.2f MPa", sample.staPress.status, (float) sample.pressure / 1000);
// for(i = 0; i < 0; i++)
// printf("\nConversion result of extPress[%d]: \t%02X, %.2f MPa", i, sample.staExtPress[i].status, (float) sample.extPressure[i] / 1000);
// for(i = 0; i < 2; i++)
// printf("\nConversion result of extTempr[%d]: \t%02X, %d ℃", i, sample.staExtTempr[i].status, sample.extTempr[i]);
printf("\nConversion result of height: \t\t%.1f mm", sample.height);
// printf("\nConversion result of volTol: \t\t%u L", sample.volumeTotal);
// printf("\nConversion result of volume: \t\t%u L", sample.volume);
printf("\nConversion result of volPct: \t\t%.2f %%", (float) sample.volumePct / 100);
printf("\nConversion result of charging: \t\t%d", sample.charging);
// printf("\nConversion result of staVacuum: \t%u", sample.vacuum[0].staVacuum);
// printf("\nConversion result of lifeVacuum: \t%u Months", sample.vacuum[0].lifeVacuum);
printf("\nConversion result of vacuum: \t\t%.2f Pa", sample.vacuum[0].vacuum);
// printf("\nConversion result of rateVacuum: \t%.2f Pa.M3/s", sample.vacuum[0].rateVacuum);
// printf("\nConversion result of typeLeak: \t\t%u", sample.leak.typeLeak);
// printf("\nConversion result of staLeak: \t\t%u", sample.leak.staLeak);
printf("\nConversion result of concentrations: \t%u %%", sample.leak.concentrations);
printf("\n");
if(first)
{
first = 0;
// 马上采集真空数据
Config_Vacuum_Request = 1;
// 发送消息给任务
xSemaphoreGive(Sample_Semaphore);
}
// 采集结束
Sample_phase = 0;
}
}
void Match_Task(void *p_arg)
{
uint8_t fail_count = 0;
while(1)
{
// 等待匹配信号
xSemaphoreTake(Match_Semaphore, portMAX_DELAY);
RF_PowerOn();
Truck_Matched = rf_charge_match(Match_Charging);
if(Truck_Matched)
{
fail_count = 0;
Truck_Charging = Match_Charging;
if(!Truck_Charging)
Manual_Charing = 0;
}
else
{
if(++fail_count >= 3)
{
fail_count = 0;
Manual_Charing = 0;
}
}
RF_PowerOff();
if(!Manual_Charing)
{
printf("********* Manual_Charing = 0 ****\r\n");
// 恢复初始状态
Truck_Matched = 0;
Truck_Charging = 0;
}
}
}