1151 lines
31 KiB
C
1151 lines
31 KiB
C
/*
|
||
*********************************************************************************************************
|
||
* IAR Development Kits
|
||
* on the
|
||
*
|
||
* M451
|
||
*
|
||
* Filename : spi_adc.c
|
||
* Version : V1.00
|
||
* Programmer(s) : Qian Xianghong
|
||
*********************************************************************************************************
|
||
*/
|
||
|
||
#include "includes.h"
|
||
|
||
// 是否SMARC的流量计
|
||
//#define _SMARC_FLOWMETER_
|
||
|
||
//#define RS485_EN() LL_GPIO_SetOutputPin(GPIOB, LL_GPIO_PIN_2);
|
||
//#define RS485_DIS() LL_GPIO_ResetOutputPin(GPIOB, LL_GPIO_PIN_2);
|
||
|
||
// 是否热式流量计
|
||
//#define _THERMAL_FLOWMETER_
|
||
|
||
// 是否希尔思S401流量计
|
||
//#define _S401_FLOWMETER_
|
||
|
||
// 默认为斯达易思流量计
|
||
|
||
// 读取超时计数
|
||
volatile uint32_t modbus_outTick = 0;
|
||
|
||
const uint8_t VACUUM_ID[] = {1, 2}; // 真空计通信地址
|
||
#define VACUUM_CMD 4 // 真空计读取命令
|
||
#define VACUUM_ADDR 608 // 真空计起始寄存器地址
|
||
#define VACUUM_LEN 8 // 真空计读取寄存器个数
|
||
|
||
const uint8_t LEAK_ID = 3; // 泄露报警控制器通信地址
|
||
#define LEAK_CMD 3 // 泄露报警控制器读取命令
|
||
#define LEAK_ADDR 0x08 // 泄露报警控制器起始寄存器地址
|
||
#define LEAK_LEN 8 // 泄露报警控制器读取寄存器个数
|
||
|
||
#if defined(_SMARC_FLOWMETER_)
|
||
const uint8_t FLOW_ID = 1; // SMARC流量计通信地址
|
||
#define FLOW_CMD 3 // 流量计读取命令
|
||
#define FLOW_ADDR 4068 // 流量计起始寄存器地址
|
||
#define FLOW_LEN 12 // 流量计读取寄存器个数
|
||
#elif defined(_THERMAL_FLOWMETER_)
|
||
const uint8_t FLOW_ID = 4; // 热式流量计通信地址
|
||
#define FLOW_CMD 3 // 流量计读取命令
|
||
#define FLOW_ADDR 7 // 流量计起始寄存器地址
|
||
#define FLOW_LEN 6 // 流量计读取寄存器个数
|
||
#elif defined(_S401_FLOWMETER_)
|
||
const uint8_t FLOW_ID = 4; // S401流量计通信地址
|
||
#define FLOW_CMD 3 // 流量计读取命令
|
||
#define FLOW_ADDR 6 // 流量计起始寄存器地址
|
||
#define FLOW_LEN 4 // 流量计读取寄存器个数
|
||
#else
|
||
const uint8_t FLOW_ID = 4; // 斯达易思流量计通信地址
|
||
#define FLOW_CMD 3 // 流量计读取命令
|
||
#define FLOW_ADDR 0 // 流量计起始寄存器地址
|
||
#define FLOW_LEN 15 // 流量计读取寄存器个数
|
||
#endif
|
||
|
||
const uint8_t LEAK_O2_ID = 1; // O2浓度传感器通信地址
|
||
#define LEAK_O2_SOF 0xFF // O2浓度传感器起始符
|
||
#define LEAK_O2_CMD 0x86 // O2浓度传感器读取命令
|
||
|
||
#pragma pack(push, 1)
|
||
typedef struct
|
||
{
|
||
uint8_t id;
|
||
uint8_t cmd;
|
||
uint16_t addr;
|
||
uint16_t len;
|
||
uint16_t crc;
|
||
} modbus_send_t;
|
||
|
||
typedef struct
|
||
{
|
||
struct
|
||
{
|
||
uint8_t id;
|
||
uint8_t cmd;
|
||
uint8_t len;
|
||
} header;
|
||
union{
|
||
// 真空计数据
|
||
struct
|
||
{
|
||
uint16_t staVacuum; // 状态
|
||
uint16_t lifeVacuum; // 使用年限
|
||
uint32_t vacuum; // 真空度,float型,先用整形交换字节序
|
||
uint32_t rateVacuum; // 漏放气速率,float型,先用整形交换字节序
|
||
uint32_t tempr; // 温度,float型,先用整形交换字节序
|
||
} vacuum;
|
||
|
||
// 泄漏报警器数据
|
||
struct
|
||
{
|
||
unsigned unit : 4; // 气体单位
|
||
unsigned ratio : 4; // 数值单位
|
||
uint8_t type; // 气体类型
|
||
uint16_t A1; // A1报警值
|
||
uint16_t A2;
|
||
uint16_t A3;
|
||
uint16_t A4;
|
||
uint16_t range; // 量程
|
||
uint16_t concentrations; // 浓度
|
||
uint8_t staLeak; // 传感器状态
|
||
unsigned : 8;
|
||
} leak;
|
||
|
||
// 流量计数据
|
||
struct
|
||
{
|
||
uint32_t nM3_int; // 标况累积总量整数部分
|
||
uint16_t nM3_frac; // 标况累积总量小数部分(放大10000倍)
|
||
uint32_t M3_int; // 工况累积总量整数部分
|
||
uint16_t M3_frac; // 工况累积总量小数部分(放大10000倍)
|
||
uint32_t nM3_h; // 标况流量(nM3/h,放大100倍)
|
||
uint32_t M3_h; // 工况流量(M3/h,放大100倍)
|
||
int16_t tempr; // 温度(℃,放大10倍,第一位正负位(即数值大于0x7FFF为负))
|
||
uint32_t pressure; // 压力(绝压)(KPa, 放大10倍)
|
||
uint16_t err1; // 异常标志位1
|
||
//温度错误标志位: 0x0003
|
||
//压力错误标志位: 0x0030
|
||
//电池电量低标志位: 0x0300
|
||
//工况流量超最大工况流量: 0x3000
|
||
//无异常:0x0000
|
||
uint16_t err2; // 异常标志位2
|
||
//存储器异常标志位: 0x0003
|
||
//无异常:0x0000
|
||
} flow;
|
||
|
||
// SMARC流量计数据
|
||
struct
|
||
{
|
||
uint32_t nM3_h; // 标况流量: float, 方便颠倒顺序,用uint32_t型接收
|
||
uint32_t M3_h; // 工况流量: float, 方便颠倒顺序,用uint32_t型接收
|
||
uint32_t tempr; // 温度: float, 方便颠倒顺序,用uint32_t型接收
|
||
uint32_t pressure; // 压力: float, 方便颠倒顺序,用uint32_t型接收
|
||
uint16_t warnFlag; // 报警标志
|
||
uint8_t nM3_BCD[6]; // 标况体积
|
||
} flow_SMARC;
|
||
|
||
// 热式流量计数据
|
||
struct
|
||
{
|
||
uint32_t nM3_h; // 标况流量: float, 方便颠倒顺序,用uint32_t型接收
|
||
uint32_t nM3x100; // 累计流量100以上,uint32_t
|
||
uint32_t nM3r100; // 累计流量100以下,float, 方便颠倒顺序,用uint32_t型接收
|
||
} flow_Thermal;
|
||
|
||
// S401流量计数据
|
||
struct
|
||
{
|
||
uint32_t nM3_h; // 流量: 分辨率0.1, uint32_t
|
||
uint32_t nM3; // 累积量,分辨率1,uint32_t
|
||
} flow_S401;
|
||
};
|
||
uint16_t crc; // 占位置
|
||
} modbus_recv_t;
|
||
|
||
typedef union
|
||
{
|
||
modbus_send_t send;
|
||
modbus_recv_t recv;
|
||
uint8_t buff[sizeof(modbus_recv_t)];
|
||
} modbus_comm_t;
|
||
|
||
// O2浓度传感器读取命令
|
||
typedef struct
|
||
{
|
||
uint8_t addr;
|
||
uint8_t cmd;
|
||
uint8_t reserved[5];
|
||
} leak_o2_send_t;
|
||
|
||
// O2浓度传感器返回结果
|
||
typedef struct
|
||
{
|
||
uint8_t cmd;
|
||
uint16_t concentrations; // 浓度
|
||
uint8_t reserved[4];
|
||
} leak_o2_recv_t;
|
||
|
||
// O2浓度传感器通信帧
|
||
typedef union
|
||
{
|
||
struct
|
||
{
|
||
uint8_t sof;
|
||
union
|
||
{
|
||
leak_o2_send_t send;
|
||
leak_o2_recv_t recv;
|
||
};
|
||
uint8_t cs;
|
||
};
|
||
uint8_t buff[9];
|
||
} leak_o2_comm_t;
|
||
|
||
// DYQ-7通信协议的泄露报警器、电容采集头、压力采集头等
|
||
#define RS_MIN_FRAME_LEN (15)
|
||
#define RS_MAX_FRAME_LEN (39)
|
||
#define RS_MIN_DATA_LEN (0)
|
||
#define RS_MAX_DATA_LEN (RS_MAX_FRAME_LEN - RS_MIN_FRAME_LEN)
|
||
|
||
#define RS_FRAME_SOF (0x1B) // 标识一个帧的开始
|
||
|
||
#define RS_DIR_M2S (0) // Master->Slave
|
||
#define RS_DIR_S2M (1) // Slave->Master
|
||
|
||
#define RS_PROTOCOL_VER_1 (1)
|
||
|
||
// 请求命令
|
||
#define RS_CMD_READ_DATA (5) // 读采集数据
|
||
// 处理结果
|
||
#define RS_RESULT_SUCC (0) // 处理成功
|
||
#define RS_RESULT_FAIL (-1) // 处理失败
|
||
|
||
// 通信协议版本
|
||
const uint8_t RS_PROTOCOL_VER = RS_PROTOCOL_VER_1;
|
||
|
||
// 485泄露报警器请求数据
|
||
typedef struct // size = RS_MAX_FRAME_LEN
|
||
{
|
||
uint8_t sof; // RS_FRMAE_SOF
|
||
uint8_t len; // bytes from sof to crc(RS_MIN_FRAME_LEN~RS_MAX_FRAME_LEN)
|
||
uint8_t destAddr;
|
||
uint8_t srcAddr;
|
||
uint8_t srcPSN[6];
|
||
uint8_t dir;
|
||
uint8_t protocol_ver; // RS_PROTOCOL
|
||
uint8_t cmd;
|
||
uint8_t data[RS_MAX_DATA_LEN];
|
||
uint16_t crc; // 占位置,实际crc可能更靠前
|
||
} rs_frame_t;
|
||
|
||
// 485泄露报警器应答数据
|
||
typedef struct // size = 20
|
||
{
|
||
uint16_t adc; // 采集ADC值
|
||
float measureValue; // 采集值
|
||
uint8_t measureState; // 测量值状态
|
||
uint16_t levelHeight; // 液位高度
|
||
uint16_t volume; // 剩余液量
|
||
uint16_t volumeMax; // 有效容积
|
||
uint16_t quality; // 剩余重量
|
||
uint8_t warnState; // 报警状态
|
||
uint16_t envAdc; // 环境温度ADC
|
||
int16_t envTempr; // 环境温度
|
||
} rs_data_t;
|
||
|
||
#pragma pack(pop)
|
||
|
||
rs_frame_t RS_TranFrame;
|
||
|
||
modbus_comm_t modbus;
|
||
uint8_t modbus_idx = 0;
|
||
uint8_t vaccum_idx = 0;
|
||
data_sample_t *modbus_sample;
|
||
|
||
leak_o2_comm_t leakO2;
|
||
|
||
// 将十进制转换成BCD
|
||
void dec2bcd(uint32_t dec, uint8_t *bcd, uint8_t len)
|
||
{
|
||
char fmt[10], str[20];
|
||
uint8_t i;
|
||
|
||
// 生成格式串(如:%010u)
|
||
sprintf(fmt, "%%0%du", len * 2);
|
||
// 将dec值转换成前面补0的字符串(如:000000123456)
|
||
sprintf(str, fmt, dec);
|
||
// 转换
|
||
for(i = 0; i < strlen(str); i += 2)
|
||
{
|
||
bcd[i / 2] = ((str[i] - '0') << 4) | (str[i + 1] - '0');
|
||
}
|
||
}
|
||
|
||
// 计算O2浓度传感器校验和
|
||
uint8_t leak_o2_calcuCS(uint8_t *data, uint16_t len)
|
||
{
|
||
uint8_t cs = 0;
|
||
|
||
while(len--)
|
||
cs += *data++;
|
||
|
||
return (~cs) + 1;
|
||
}
|
||
|
||
// 初始化O2浓度通信帧
|
||
void leak_o2_init_frame(leak_o2_comm_t *frame)
|
||
{
|
||
memset(frame, 0, sizeof(leak_o2_comm_t));
|
||
frame->sof = LEAK_O2_SOF;
|
||
}
|
||
|
||
// 本函数由规管设计者(Zhang Jm)提供,用于对读出的真空值进行修正
|
||
// 本函数只适用于规管量程为-2(0.01Pa)的情况
|
||
/**
|
||
* @brief Function of Fuzzy Processing.
|
||
* @param value: vacuun value.
|
||
* @retval None.
|
||
*/
|
||
float Mode1_Fuzzy_Process(float value)
|
||
{
|
||
static const float beta1 = -0.2539755;
|
||
static const float beta2 = 13.15659;
|
||
|
||
static const float theta = 0.011666666;
|
||
static const float eta = 0.9999999;
|
||
static const float kappa = 0.006666666;
|
||
float temp1, temp2, result, lower_t = 0.0101;
|
||
|
||
if((value < 0.09f) && (value > 0.04f))
|
||
{
|
||
temp1 = -beta1 * value;
|
||
temp2 = beta2 * pow(value, 2.0);
|
||
return(1 - exp(temp1 - temp2));
|
||
}
|
||
else if((value <= 0.04f) && (value > 0.005f))
|
||
{/*y = theta*x^eta/(kappa^eta+x^eta)*/
|
||
temp1 = pow(value, eta);
|
||
temp2 = pow(kappa, eta) + temp1;
|
||
result = theta * temp1 / temp2;
|
||
if(result < lower_t)
|
||
return(lower_t);
|
||
else
|
||
return(result);
|
||
}
|
||
else
|
||
return(value);
|
||
}
|
||
|
||
void Modbus_Read(USART_Handle *huart)
|
||
{
|
||
uint8_t i;
|
||
uint32_t reversed;
|
||
int32_t i_reversed;
|
||
float f;
|
||
uint8_t c = (uint8_t) huart->Instance->RDR;
|
||
|
||
/* Receive data */
|
||
if(modbus_idx < sizeof(modbus_recv_t))
|
||
{
|
||
modbus.buff[modbus_idx++] = c;
|
||
|
||
if(modbus.recv.header.id == LEAK_ID && modbus.recv.header.cmd == LEAK_CMD
|
||
&& modbus.recv.header.len == sizeof(modbus.recv.leak)
|
||
&& modbus_idx == sizeof(modbus.recv.header) + sizeof(modbus.recv.leak) + sizeof(modbus.recv.crc)
|
||
&& MODBUS_RTU_CRC16(modbus.buff, modbus_idx) == 0)
|
||
{
|
||
/* Print the received data */
|
||
// printf("Received data:\n");
|
||
// for(i = 0; i < modbus_idx; i++)
|
||
// {
|
||
// printf("%02X ", modbus.buff[i]);
|
||
// }
|
||
// printf("\n");
|
||
|
||
// 探测器状态
|
||
modbus_sample->leak.staLeak = modbus.recv.leak.staLeak;
|
||
// 浓度
|
||
modbus_sample->leak.concentrations = ntohs(modbus.recv.leak.concentrations);
|
||
if(modbus.recv.leak.ratio == 1)
|
||
modbus_sample->leak.concentrations /= 10;
|
||
else if(modbus.recv.leak.ratio == 2)
|
||
modbus_sample->leak.concentrations /= 100;
|
||
else if(modbus.recv.leak.ratio == 3)
|
||
modbus_sample->leak.concentrations /= 1000;
|
||
|
||
// 退出超时等待
|
||
modbus_outTick = GetDelayTick(0);
|
||
}
|
||
else if(modbus.recv.header.id == VACUUM_ID[vaccum_idx] && modbus.recv.header.cmd == VACUUM_CMD
|
||
&& modbus.recv.header.len == sizeof(modbus.recv.vacuum)
|
||
&& modbus_idx == sizeof(modbus.recv.header) + sizeof(modbus.recv.vacuum) + sizeof(modbus.recv.crc)
|
||
&& MODBUS_RTU_CRC16(modbus.buff, modbus_idx) == 0)
|
||
{
|
||
/* Print the received data */
|
||
printf("Received data:\n");
|
||
for(i = 0; i < modbus_idx; i++)
|
||
{
|
||
printf("%02X ", modbus.buff[i]);
|
||
}
|
||
printf("\n");
|
||
|
||
// 传感器状态
|
||
modbus_sample->vacuum[vaccum_idx].staVacuum = ntohs(modbus.recv.vacuum.staVacuum);
|
||
// 使用年限
|
||
modbus_sample->vacuum[vaccum_idx].lifeVacuum = ntohs(modbus.recv.vacuum.lifeVacuum);
|
||
// 真空度
|
||
reversed = ntohl(modbus.recv.vacuum.vacuum);
|
||
memmove(&modbus_sample->vacuum[vaccum_idx].vacuum, &reversed, sizeof(modbus_sample->vacuum[vaccum_idx].vacuum));
|
||
// 调用真空值修正函数(2021.10.28)
|
||
modbus_sample->vacuum[vaccum_idx].vacuum = Mode1_Fuzzy_Process(modbus_sample->vacuum[vaccum_idx].vacuum);
|
||
// 漏放气速率
|
||
reversed = ntohl(modbus.recv.vacuum.rateVacuum);
|
||
memmove(&modbus_sample->vacuum[vaccum_idx].rateVacuum, &reversed, sizeof(modbus_sample->vacuum[vaccum_idx].rateVacuum));
|
||
// 温度
|
||
reversed = ntohl(modbus.recv.vacuum.tempr);
|
||
memmove(&modbus_sample->vacuum[vaccum_idx].tempr, &reversed, sizeof(modbus_sample->vacuum[vaccum_idx].tempr));
|
||
|
||
// 退出超时等待
|
||
modbus_outTick = GetDelayTick(0);
|
||
}
|
||
#if defined(_SMARC_FLOWMETER_)
|
||
else if(modbus.recv.header.id == FLOW_ID && modbus.recv.header.cmd == FLOW_CMD
|
||
&& modbus.recv.header.len == sizeof(modbus.recv.flow_SMARC)
|
||
&& modbus_idx == sizeof(modbus.recv.header) + sizeof(modbus.recv.flow_SMARC) + sizeof(modbus.recv.crc)
|
||
&& MODBUS_RTU_CRC16(modbus.buff, modbus_idx) == 0)
|
||
{
|
||
// /* Print the received data */
|
||
// printf("Received data:\n");
|
||
// for(i = 0; i < modbus_idx; i++)
|
||
// {
|
||
// printf("%02X ", modbus.buff[i]);
|
||
// }
|
||
// printf("\n");
|
||
|
||
// 标况体积总量
|
||
// 整数部分
|
||
reversed = 0;
|
||
for(i = 0; i < 9; i++)
|
||
{
|
||
reversed *= 10;
|
||
if(i % 2 == 0)
|
||
reversed += (modbus.recv.flow_SMARC.nM3_BCD[i / 2] >> 4);
|
||
else
|
||
reversed += (modbus.recv.flow_SMARC.nM3_BCD[i / 2] & 0x0F);
|
||
}
|
||
dec2bcd(reversed, modbus_sample->flow.nM3, 5);
|
||
// 小数部分
|
||
reversed = 0;
|
||
for(i = 9; i < 11; i++)
|
||
{
|
||
reversed *= 10;
|
||
if(i % 2 == 0)
|
||
reversed += (modbus.recv.flow_SMARC.nM3_BCD[i / 2] >> 4);
|
||
else
|
||
reversed += (modbus.recv.flow_SMARC.nM3_BCD[i / 2] & 0x0F);
|
||
}
|
||
dec2bcd(reversed, modbus_sample->flow.nM3 + 5, 1);
|
||
// 标况流量
|
||
reversed = ntohl(modbus.recv.flow_SMARC.nM3_h);
|
||
memmove(&f, &reversed, 4);
|
||
reversed = f * 100;
|
||
dec2bcd(reversed, modbus_sample->flow.nM3_h, 4);
|
||
// 工况流量
|
||
reversed = ntohl(modbus.recv.flow_SMARC.M3_h);
|
||
memmove(&f, &reversed, 4);
|
||
reversed = f * 100;
|
||
dec2bcd(reversed, modbus_sample->flow.M3_h, 4);
|
||
// 温度
|
||
reversed = ntohl(modbus.recv.flow_SMARC.tempr);
|
||
memmove(&f, &reversed, 4);
|
||
i_reversed = f * 100;
|
||
if(i_reversed >= 0)
|
||
dec2bcd(i_reversed, modbus_sample->flow.tempr, 4);
|
||
else
|
||
{
|
||
dec2bcd(-i_reversed, modbus_sample->flow.tempr, 4);
|
||
modbus_sample->flow.tempr[0] = 0x80;
|
||
}
|
||
// 压力
|
||
reversed = ntohl(modbus.recv.flow_SMARC.pressure);
|
||
memmove(&f, &reversed, 4);
|
||
reversed = f * 100;
|
||
dec2bcd(reversed, modbus_sample->flow.pressure, 4);
|
||
|
||
/* Print the converted bcd data */
|
||
printf("Flowmeter BCD data:\n");
|
||
for(i = 0; i < sizeof(modbus_sample->flow); i++)
|
||
{
|
||
printf("%02X ", *(((uint8_t *) &modbus_sample->flow) + i));
|
||
}
|
||
printf("\n");
|
||
|
||
// 退出超时等待
|
||
modbus_outTick = GetDelayTick(0);
|
||
}
|
||
#elif defined(_THERMAL_FLOWMETER_)
|
||
else if(modbus.recv.header.id == FLOW_ID && modbus.recv.header.cmd == FLOW_CMD
|
||
&& modbus.recv.header.len == sizeof(modbus.recv.flow_Thermal)
|
||
&& modbus_idx == sizeof(modbus.recv.header) + sizeof(modbus.recv.flow_Thermal) + sizeof(modbus.recv.crc)
|
||
&& MODBUS_RTU_CRC16(modbus.buff, modbus_idx) == 0)
|
||
{
|
||
// /* Print the received data */
|
||
// printf("Received data:\n");
|
||
// for(i = 0; i < modbus_idx; i++)
|
||
// {
|
||
// printf("%02X ", modbus.buff[i]);
|
||
// }
|
||
// printf("\n");
|
||
|
||
// 标况流量
|
||
reversed = ntohl(modbus.recv.flow_Thermal.nM3_h);
|
||
memmove(&f, &reversed, 4);
|
||
reversed = f * 100;
|
||
dec2bcd(reversed, modbus_sample->flow.nM3_h, 4);
|
||
// 工况流量(协议无,填标况流量)
|
||
dec2bcd(reversed, modbus_sample->flow.M3_h, 4);
|
||
// 温度(协议无,填0)
|
||
dec2bcd(0, modbus_sample->flow.tempr, 4);
|
||
// 压力(协议无,填0)
|
||
dec2bcd(0, modbus_sample->flow.pressure, 4);
|
||
|
||
// 标况体积总量
|
||
// 100以上部分
|
||
reversed = ntohl(modbus.recv.flow_Thermal.nM3x100);
|
||
dec2bcd(reversed, modbus_sample->flow.nM3, 4);
|
||
// 100以下部分
|
||
reversed = ntohl(modbus.recv.flow_Thermal.nM3r100);
|
||
memmove(&f, &reversed, 4);
|
||
reversed = f * 100;
|
||
dec2bcd(reversed, modbus_sample->flow.nM3 + 4, 2);
|
||
|
||
/* Print the converted bcd data */
|
||
printf("Flowmeter BCD data:\n");
|
||
for(i = 0; i < sizeof(modbus_sample->flow); i++)
|
||
{
|
||
printf("%02X ", *(((uint8_t *) &modbus_sample->flow) + i));
|
||
}
|
||
printf("\n");
|
||
|
||
// 退出超时等待
|
||
modbus_outTick = GetDelayTick(0);
|
||
}
|
||
#elif defined(_S401_FLOWMETER_)
|
||
else if(modbus.recv.header.id == FLOW_ID && modbus.recv.header.cmd == FLOW_CMD
|
||
&& modbus.recv.header.len == sizeof(modbus.recv.flow_S401)
|
||
&& modbus_idx == sizeof(modbus.recv.header) + sizeof(modbus.recv.flow_S401) + sizeof(modbus.recv.crc)
|
||
&& MODBUS_RTU_CRC16(modbus.buff, modbus_idx) == 0)
|
||
{
|
||
// /* Print the received data */
|
||
// printf("Received data:\n");
|
||
// for(i = 0; i < modbus_idx; i++)
|
||
// {
|
||
// printf("%02X ", modbus.buff[i]);
|
||
// }
|
||
// printf("\n");
|
||
|
||
// 流量
|
||
reversed = ntohl(modbus.recv.flow_S401.nM3_h) * 10; // x10->x100
|
||
dec2bcd(reversed, modbus_sample->flow.nM3_h, 4);
|
||
// 工况流量(协议无,填标况流量)
|
||
dec2bcd(reversed, modbus_sample->flow.M3_h, 4);
|
||
// 温度(协议无,填0)
|
||
dec2bcd(0, modbus_sample->flow.tempr, 4);
|
||
// 压力(协议无,填0)
|
||
dec2bcd(0, modbus_sample->flow.pressure, 4);
|
||
|
||
// 累积量
|
||
reversed = ntohl(modbus.recv.flow_S401.nM3) * 100; // x1->x100
|
||
dec2bcd(reversed, modbus_sample->flow.nM3, 6);
|
||
|
||
/* Print the converted bcd data */
|
||
printf("Flowmeter BCD data:\n");
|
||
for(i = 0; i < sizeof(modbus_sample->flow); i++)
|
||
{
|
||
printf("%02X ", *(((uint8_t *) &modbus_sample->flow) + i));
|
||
}
|
||
printf("\n");
|
||
|
||
// 退出超时等待
|
||
modbus_outTick = GetDelayTick(0);
|
||
}
|
||
#else
|
||
else if(modbus.recv.header.id == FLOW_ID && modbus.recv.header.cmd == FLOW_CMD
|
||
&& modbus.recv.header.len == sizeof(modbus.recv.flow)
|
||
&& modbus_idx == sizeof(modbus.recv.header) + sizeof(modbus.recv.flow) + sizeof(modbus.recv.crc)
|
||
&& MODBUS_RTU_CRC16(modbus.buff, modbus_idx) == 0)
|
||
{
|
||
// /* Print the received data */
|
||
// printf("Received data:\n");
|
||
// for(i = 0; i < modbus_idx; i++)
|
||
// {
|
||
// printf("%02X ", modbus.buff[i]);
|
||
// }
|
||
// printf("\n");
|
||
|
||
// 标况体积总量(BCD码,放大100倍)
|
||
if((htons(modbus.recv.flow.err2) & 0x000F) == 0x0003) // 是否存储器错误?
|
||
dec2bcd(0, modbus_sample->flow.nM3, 6);
|
||
else
|
||
{
|
||
reversed = ntohl(modbus.recv.flow.nM3_int); // 整数部分
|
||
dec2bcd(reversed, modbus_sample->flow.nM3, 5);
|
||
reversed = ntohs(modbus.recv.flow.nM3_frac); // 小数部分
|
||
reversed /= 100; // 放大10000倍->放大100倍
|
||
dec2bcd(reversed, modbus_sample->flow.nM3 + 5, 1);
|
||
}
|
||
// 标况流量(BCD码,放大100倍)
|
||
reversed = ntohl(modbus.recv.flow.nM3_h);
|
||
dec2bcd(reversed, modbus_sample->flow.nM3_h, 4);
|
||
// 工况流量(BCD码,放大100倍)
|
||
reversed = ntohl(modbus.recv.flow.M3_h);
|
||
dec2bcd(reversed, modbus_sample->flow.M3_h, 4);
|
||
// 温度(BCD码,放大100倍,第一字节为符号: 80H 为负,00H 为正)
|
||
if((htons(modbus.recv.flow.err1) & 0x000F) == 0x0003) // 是否温度传感器错误?
|
||
i_reversed = 0;
|
||
else
|
||
{
|
||
i_reversed = ntohs(modbus.recv.flow.tempr);
|
||
i_reversed *= 10; // 放大10倍->放大100倍
|
||
}
|
||
if(i_reversed >= 0)
|
||
dec2bcd(i_reversed, modbus_sample->flow.tempr, 4);
|
||
else
|
||
{
|
||
dec2bcd(-i_reversed, modbus_sample->flow.tempr, 4);
|
||
modbus_sample->flow.tempr[0] = 0x80;
|
||
}
|
||
// 压力(BCD码,放大100倍)
|
||
if((htons(modbus.recv.flow.err1) & 0x00F0) == 0x0030) // 是否压力传感器错误?
|
||
reversed = 0;
|
||
else
|
||
{
|
||
reversed = ntohl(modbus.recv.flow.pressure);
|
||
reversed *= 10; // 放大10倍->放大100倍
|
||
}
|
||
dec2bcd(reversed, modbus_sample->flow.pressure, 4);
|
||
|
||
/* Print the converted bcd data */
|
||
printf("Flowmeter BCD data:\n");
|
||
for(i = 0; i < sizeof(modbus_sample->flow); i++)
|
||
{
|
||
printf("%02X ", *(((uint8_t *) &modbus_sample->flow) + i));
|
||
}
|
||
printf("\n");
|
||
|
||
// 退出超时等待
|
||
modbus_outTick = GetDelayTick(0);
|
||
}
|
||
#endif
|
||
}
|
||
}
|
||
|
||
void LeakO2_Read(USART_Handle *huart)
|
||
{
|
||
uint8_t i;
|
||
uint8_t c = (uint8_t) huart->Instance->RDR;
|
||
uint16_t concentrations = 0;
|
||
|
||
/* Receive data */
|
||
if(modbus_idx < sizeof(leak_o2_comm_t))
|
||
{
|
||
leakO2.buff[modbus_idx++] = c;
|
||
|
||
if(modbus_idx == sizeof(leak_o2_comm_t)
|
||
&& leakO2.sof == LEAK_O2_SOF && leakO2.recv.cmd == LEAK_O2_CMD
|
||
&& leak_o2_calcuCS(leakO2.buff + 1, sizeof(leak_o2_comm_t) - 2) == leakO2.cs)
|
||
{
|
||
/* Print the received data */
|
||
printf("Received data:\n");
|
||
for(i = 0; i < modbus_idx; i++)
|
||
{
|
||
printf("%02X ", leakO2.buff[i]);
|
||
}
|
||
printf("\n");
|
||
|
||
#if 1
|
||
// 浓度: 分辨率0.1%
|
||
concentrations = ntohs(leakO2.recv.concentrations);
|
||
#else
|
||
// 测试报警输出
|
||
concentrations = 240;
|
||
#endif
|
||
// 浓度降到21.5%,重启泄露报警
|
||
if(concentrations <= 215)
|
||
Leak_Alarm_Enabled = 1;
|
||
// 报警阀值:浓度达到23%
|
||
if(concentrations >= 230)
|
||
{
|
||
modbus_sample->leak.staLeak = LEAK_STATUS_A2_ALARM;
|
||
modbus_sample->leak.concentrations = 1;
|
||
}
|
||
else
|
||
{
|
||
modbus_sample->leak.staLeak = LEAK_STATUS_OK;
|
||
modbus_sample->leak.concentrations = 0;
|
||
}
|
||
// 退出超时等待
|
||
modbus_outTick = GetDelayTick(0);
|
||
}
|
||
}
|
||
}
|
||
|
||
// 物理层校验
|
||
uint8_t rs_phy_valid(rs_frame_t *frame)
|
||
{
|
||
if(frame->protocol_ver != RS_PROTOCOL_VER || frame->dir != RS_DIR_S2M)
|
||
{
|
||
// 物理层校验失败
|
||
return 0;
|
||
}
|
||
return 1;
|
||
}
|
||
|
||
// mac层校验
|
||
uint8_t rs_mac_valid(rs_frame_t *frame, uint8_t dir)
|
||
{
|
||
if(frame->destAddr != dcBuff.configBottle.addr)
|
||
{
|
||
// mac层校验失败
|
||
return 0;
|
||
}
|
||
return 1;
|
||
}
|
||
|
||
// 初始化帧
|
||
void rs_initial_frame(rs_frame_t *frame)
|
||
{
|
||
memset((uint8_t *) frame, 0, sizeof(rs_frame_t));
|
||
frame->len = RS_MIN_FRAME_LEN;
|
||
}
|
||
|
||
// 追加负载数据
|
||
uint8_t rs_append_data(rs_frame_t *frame, uint8_t *data, uint8_t len)
|
||
{
|
||
if(frame->len < RS_MIN_FRAME_LEN || frame->len + len > RS_MAX_FRAME_LEN)
|
||
return 0;
|
||
|
||
if(len > 0)
|
||
memmove(frame->data + (frame->len - RS_MIN_FRAME_LEN), data, len);
|
||
frame->len += len;
|
||
return 1;
|
||
}
|
||
|
||
// 重新寻找SOF
|
||
void RS_SearchSOF(uint8_t *buf, uint16_t fromPos, uint8_t *len)
|
||
{
|
||
uint8_t i;
|
||
|
||
for(i = fromPos; i < *len && buf[i] != RS_FRAME_SOF; i++)
|
||
{
|
||
}
|
||
|
||
*len -= i;
|
||
memmove(buf, buf + i, *len);
|
||
}
|
||
|
||
// 模块任务主体:处理射频接收数据
|
||
void RS_ParseFrame(USART_Handle *huart)
|
||
{
|
||
uint8_t *RS_ModuleData = (uint8_t *) &RS_TranFrame;
|
||
uint16_t i;
|
||
uint8_t frameOk, frameErr;
|
||
uint8_t c = (uint8_t) huart->Instance->RDR;
|
||
|
||
uint32_t mask;
|
||
rs_data_t *rsData = (rs_data_t *) (RS_TranFrame.data + sizeof(mask));
|
||
|
||
if(modbus_idx == 0 && c != RS_FRAME_SOF)
|
||
return;
|
||
|
||
RS_ModuleData[modbus_idx++] = c;
|
||
|
||
do
|
||
{
|
||
frameErr = (modbus_idx >= 2 &&
|
||
(RS_ModuleData[1] < RS_MIN_FRAME_LEN || RS_ModuleData[1] > RS_MAX_FRAME_LEN));
|
||
if(frameErr)
|
||
{
|
||
// 从1开始寻找SOF
|
||
RS_SearchSOF(RS_ModuleData, 1, &modbus_idx);
|
||
}
|
||
|
||
frameOk = (modbus_idx >= 2 && RS_ModuleData[1] >= RS_MIN_FRAME_LEN && RS_ModuleData[1] <= RS_MAX_FRAME_LEN
|
||
&& modbus_idx >= RS_ModuleData[1]);
|
||
if(frameOk)
|
||
{
|
||
if(MODBUS_RTU_CRC16(RS_ModuleData, RS_ModuleData[1]) == 0)
|
||
{
|
||
if(rs_phy_valid(&RS_TranFrame) && rs_mac_valid(&RS_TranFrame, RS_DIR_M2S))
|
||
{
|
||
// 收到一帧
|
||
printf("\r\nRS recv %d bytes:\r\n", RS_ModuleData[1]);
|
||
for(i = 0; i < RS_ModuleData[1]; i++)
|
||
printf(" %02X", RS_ModuleData[i]);
|
||
printf("\r\n");
|
||
|
||
// 处理这一帧
|
||
memmove(&mask, RS_TranFrame.data, 4);
|
||
mask = ntohl(mask);
|
||
if(RS_TranFrame.srcAddr == 0x51)
|
||
{
|
||
// 泄漏报警数据
|
||
if((mask & 0x61000000) == 0x61000000) // 检查数据掩码
|
||
{
|
||
modbus_sample->leak.typeLeak = LEAK_TYPE_MODBUS;
|
||
if(rsData->measureState > 1)
|
||
modbus_sample->leak.staLeak = LEAK_STATUS_FAULT;
|
||
else if(rsData->warnState == 4)
|
||
modbus_sample->leak.staLeak = LEAK_STATUS_A2_ALARM;
|
||
else
|
||
modbus_sample->leak.staLeak = LEAK_STATUS_OK;
|
||
|
||
if(rsData->warnState < 3)
|
||
modbus_sample->leak.concentrations = 0;
|
||
else
|
||
{
|
||
memmove(&mask, &rsData->measureValue, 4);
|
||
mask = ntohl(mask);
|
||
memmove(&rsData->measureValue, &mask, 4);
|
||
modbus_sample->leak.concentrations = rsData->measureValue / 1000;
|
||
}
|
||
}
|
||
}
|
||
else if(RS_TranFrame.srcAddr == 0x31)
|
||
{
|
||
// 差压/电容数据,在采集模块里计算
|
||
if((mask & 0xE0000000) == 0xE0000000) // 检查数据掩码
|
||
{
|
||
if(dcBuff.configDisplay.op_USE_CAPACITY_SENSOR)
|
||
{
|
||
// 电容测量:只要电容值,不管归一化状态
|
||
modbus_sample->staDPress.status = SENSOR_STATUS_NORMAL;
|
||
}
|
||
else
|
||
modbus_sample->staDPress.status = rsData->measureState;
|
||
modbus_sample->adDPress = ntohs(rsData->adc);
|
||
modbus_sample->diff = ntohf(rsData->measureValue);
|
||
if(dcBuff.configDisplay.op_USE_CAPACITY_SENSOR)
|
||
{
|
||
// 电容只保留1位小数
|
||
modbus_sample->diff = ((int16_t) (modbus_sample->diff * 10)) * 0.1;
|
||
}
|
||
}
|
||
}
|
||
else if(RS_TranFrame.srcAddr == 0x41)
|
||
{
|
||
// 压力数据,在采集模块里计算
|
||
if((mask & 0xE0000000) == 0xE0000000) // 检查数据掩码
|
||
{
|
||
modbus_sample->staPress.status = rsData->measureState;
|
||
modbus_sample->adPress = ntohs(rsData->adc);
|
||
modbus_sample->pressure = ntohf(rsData->measureValue);
|
||
}
|
||
}
|
||
// 退出超时等待
|
||
modbus_outTick = GetDelayTick(0);
|
||
}
|
||
|
||
// 继续寻找下一帧
|
||
modbus_idx -= RS_ModuleData[1];
|
||
memmove(RS_ModuleData, RS_ModuleData + RS_ModuleData[1], modbus_idx);
|
||
// 从0开始寻找SOF
|
||
RS_SearchSOF(RS_ModuleData, 0, &modbus_idx);
|
||
}
|
||
else
|
||
{
|
||
// 从1开始寻找SOF
|
||
RS_SearchSOF(RS_ModuleData, 1, &modbus_idx);
|
||
}
|
||
}
|
||
} while(frameOk || frameErr);
|
||
}
|
||
|
||
void Sensor_Init()
|
||
{
|
||
LL_GPIO_InitTypeDef GPIO_InitStruct = {0};
|
||
|
||
LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_GPIOA);
|
||
/**LPUART1 GPIO Configuration
|
||
PA2 ------> LPUART1_TX
|
||
PA3 ------> LPUART1_RX
|
||
PB1 ------> LPUART1_DE
|
||
*/
|
||
GPIO_InitStruct.Pin = LL_GPIO_PIN_2|LL_GPIO_PIN_3;
|
||
GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE;
|
||
GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_MEDIUM;
|
||
GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL;
|
||
GPIO_InitStruct.Pull = LL_GPIO_PULL_NO;
|
||
GPIO_InitStruct.Alternate = LL_GPIO_AF_8;
|
||
LL_GPIO_Init(GPIOA, &GPIO_InitStruct);
|
||
|
||
LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_GPIOB);
|
||
|
||
GPIO_InitStruct.Pin = LL_GPIO_PIN_1;
|
||
GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE;
|
||
GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_MEDIUM;
|
||
GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL;
|
||
GPIO_InitStruct.Pull = LL_GPIO_PULL_NO;
|
||
GPIO_InitStruct.Alternate = LL_GPIO_AF_8;
|
||
LL_GPIO_Init(GPIOB, &GPIO_InitStruct);
|
||
|
||
//RS485_DIS();
|
||
}
|
||
|
||
void Sensor_Open(uint32_t baudrate)
|
||
{
|
||
LL_LPUART_InitTypeDef LPUART_InitStruct = {0};
|
||
|
||
/* Peripheral clock enable */
|
||
LL_APB1_GRP2_EnableClock(LL_APB1_GRP2_PERIPH_LPUART1);
|
||
|
||
NVIC_SetPriority(LPUART1_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(),5, 0));
|
||
NVIC_EnableIRQ(LPUART1_IRQn);
|
||
|
||
LPUART_InitStruct.BaudRate = baudrate;
|
||
LPUART_InitStruct.DataWidth = LL_LPUART_DATAWIDTH_8B;
|
||
LPUART_InitStruct.StopBits = LL_LPUART_STOPBITS_1;
|
||
LPUART_InitStruct.Parity = LL_LPUART_PARITY_NONE;
|
||
LPUART_InitStruct.TransferDirection = LL_LPUART_DIRECTION_TX_RX;
|
||
LPUART_InitStruct.HardwareFlowControl = LL_LPUART_HWCONTROL_NONE;
|
||
LL_LPUART_Init(LPUART1, &LPUART_InitStruct);
|
||
LL_LPUART_EnableDEMode(LPUART1);
|
||
LL_LPUART_SetDESignalPolarity(LPUART1, LL_LPUART_DE_POLARITY_HIGH);
|
||
LL_LPUART_SetDEAssertionTime(LPUART1, 0);
|
||
LL_LPUART_SetDEDeassertionTime(LPUART1, 0);
|
||
|
||
SET_BIT(LPUART1->CR1, USART_CR1_PEIE | USART_CR1_RXNEIE);
|
||
LL_LPUART_Enable(LPUART1);
|
||
}
|
||
|
||
// 切换串口至Modubs通信模式
|
||
void Modbus_Open()
|
||
{
|
||
LL_LPUART_Disable(hlpuart1.Instance);
|
||
// 设置中断回调函数
|
||
hlpuart1.RxISR = Modbus_Read;
|
||
// 修改波特率
|
||
Sensor_Open(9600);
|
||
}
|
||
|
||
// 切换到O2浓度传感器通信模式
|
||
void LeakO2_Open()
|
||
{
|
||
LL_LPUART_Disable(hlpuart1.Instance);
|
||
// 设置中断回调函数
|
||
hlpuart1.RxISR = LeakO2_Read;
|
||
// 修改波特率
|
||
Sensor_Open(9600);
|
||
}
|
||
|
||
// 切换串口至DYQ-7通信模式
|
||
void Modbus_Close()
|
||
{
|
||
LL_LPUART_Disable(hlpuart1.Instance);
|
||
// 设置中断回调函数
|
||
hlpuart1.RxISR = RS_ParseFrame;
|
||
// 修改波特率
|
||
Sensor_Open(19200);
|
||
}
|
||
|
||
static void RS485_SendDataByte(uint8_t *pu8TxBuf, uint32_t u32WriteBytes)
|
||
{
|
||
// RS485_EN();
|
||
// delay_us(1);
|
||
// 设置超时和结果
|
||
modbus_outTick = GetDelayTick(500);
|
||
UART_Transmit_IT(&hlpuart1, pu8TxBuf, u32WriteBytes);
|
||
// delay_ms(9); // 至少8ms,保险起见9ms
|
||
// RS485_DIS();
|
||
}
|
||
|
||
// 物理层发送
|
||
uint8_t rs_uart_send(rs_frame_t *frame, uint8_t destAddr, uint8_t dir)
|
||
{
|
||
uint16_t crc;
|
||
uint8_t i;
|
||
|
||
// 填写固定字段
|
||
frame->sof = RS_FRAME_SOF;
|
||
frame->destAddr = destAddr;
|
||
frame->srcAddr = dcBuff.configBottle.addr;
|
||
memmove(frame->srcPSN, dcBuff.configBottle.PSN, 6);
|
||
frame->dir = dir;
|
||
frame->protocol_ver = RS_PROTOCOL_VER;
|
||
|
||
crc = MODBUS_RTU_CRC16((uint8_t *) frame, frame->len - 2);
|
||
((uint8_t *) frame)[frame->len - 2] = crc >> 8;
|
||
((uint8_t *) frame)[frame->len - 1] = crc & 0xFF;
|
||
|
||
printf("\r\nRS send %d bytes:\r\n", frame->len);
|
||
for(i = 0; i < frame->len; i++)
|
||
printf(" %02X", ((uint8_t *) frame)[i]);
|
||
printf("\r\n");
|
||
|
||
RS485_SendDataByte((uint8_t *) frame, frame->len);
|
||
|
||
return 1;
|
||
}
|
||
|
||
// 读取真空计数据
|
||
void Sensor_ReadVacuum(uint8_t sensorIdx, data_sample_t *sample)
|
||
{
|
||
Modbus_Open();
|
||
|
||
// 默认读取失败
|
||
sample->vacuum[sensorIdx].staVacuum = VACUUM_STATUS_COMM_FAULT;
|
||
sample->vacuum[sensorIdx].lifeVacuum = 0;
|
||
sample->vacuum[sensorIdx].vacuum = 0;
|
||
sample->vacuum[sensorIdx].rateVacuum = 0;
|
||
|
||
// 初始化
|
||
modbus_sample = sample;
|
||
vaccum_idx = sensorIdx;
|
||
modbus_idx = 0;
|
||
|
||
// 发送
|
||
modbus.send.id = VACUUM_ID[sensorIdx];
|
||
modbus.send.cmd = VACUUM_CMD;
|
||
modbus.send.addr = htons(VACUUM_ADDR - 1);
|
||
modbus.send.len = htons(VACUUM_LEN);
|
||
modbus.send.crc = htons(MODBUS_RTU_CRC16(modbus.buff, sizeof(modbus_send_t) - 2));
|
||
RS485_SendDataByte(modbus.buff, sizeof(modbus_send_t));
|
||
|
||
// 等待中断处理
|
||
}
|
||
|
||
// 读取流量计数据
|
||
void Sensor_ReadFlow(data_sample_t *sample)
|
||
{
|
||
Modbus_Open();
|
||
|
||
// 默认读取失败
|
||
memset(&sample->flow, 0, sizeof(sample->flow));
|
||
|
||
// 初始化
|
||
modbus_sample = sample;
|
||
modbus_idx = 0;
|
||
|
||
// 发送
|
||
modbus.send.id = FLOW_ID;
|
||
modbus.send.cmd = FLOW_CMD;
|
||
modbus.send.addr = htons(FLOW_ADDR);
|
||
modbus.send.len = htons(FLOW_LEN);
|
||
modbus.send.crc = htons(MODBUS_RTU_CRC16(modbus.buff, sizeof(modbus_send_t) - 2));
|
||
RS485_SendDataByte(modbus.buff, sizeof(modbus_send_t));
|
||
|
||
// 等待中断处理
|
||
}
|
||
|
||
// 读取氧传感器数据
|
||
void Sensor_ReadLeakO2(data_sample_t *sample)
|
||
{
|
||
uint8_t reSample = 0;
|
||
|
||
LeakO2_Open();
|
||
|
||
// 默认读取失败
|
||
sample->leak.staLeak = LEAK_STATUS_COMM_FAULT;
|
||
sample->leak.concentrations = 0;
|
||
// 传感器类型
|
||
sample->leak.typeLeak = LEAK_TYPE_SWITCH | LEAK_TYPE_CURRENT | LEAK_TYPE_MODBUS;
|
||
|
||
// 初始化
|
||
modbus_sample = sample;
|
||
modbus_idx = 0;
|
||
|
||
// 发送
|
||
leak_o2_init_frame(&leakO2);
|
||
leakO2.send.addr = LEAK_O2_ID;
|
||
leakO2.send.cmd = LEAK_O2_CMD;
|
||
leakO2.cs = leak_o2_calcuCS(leakO2.buff + 1, sizeof(leak_o2_comm_t) - 2);
|
||
RS485_SendDataByte(leakO2.buff, sizeof(leak_o2_comm_t));
|
||
|
||
// 等待中断处理
|
||
}
|
||
|
||
// 读取泄漏报警数据
|
||
void Sensor_ReadLeak(data_sample_t *sample)
|
||
{
|
||
uint8_t reSample = 0;
|
||
|
||
Modbus_Close();
|
||
|
||
// 默认读取失败
|
||
sample->leak.staLeak = LEAK_STATUS_COMM_FAULT;
|
||
sample->leak.concentrations = 0;
|
||
// 传感器类型
|
||
sample->leak.typeLeak = LEAK_TYPE_SWITCH | LEAK_TYPE_CURRENT | LEAK_TYPE_MODBUS;
|
||
|
||
// 初始化
|
||
modbus_sample = sample;
|
||
modbus_idx = 0;
|
||
|
||
// 发送
|
||
#if 0
|
||
modbus.send.id = LEAK_ID;
|
||
modbus.send.cmd = LEAK_CMD;
|
||
modbus.send.addr = htons(LEAK_ADDR);
|
||
modbus.send.len = htons(LEAK_LEN);
|
||
modbus.send.crc = htons(MODBUS_RTU_CRC16(modbus.buff, sizeof(modbus_send_t) - 2));
|
||
RS485_SendDataByte(modbus.buff, sizeof(modbus_send_t));
|
||
#else
|
||
rs_initial_frame(&RS_TranFrame);
|
||
RS_TranFrame.cmd = RS_CMD_READ_DATA;
|
||
rs_append_data(&RS_TranFrame, (uint8_t *) &reSample, 1);
|
||
rs_uart_send(&RS_TranFrame, 0x50, RS_DIR_M2S);
|
||
#endif
|
||
|
||
// 等待中断处理
|
||
}
|
||
|
||
// 读取差压/电容数据
|
||
void Sensor_ReadDPress(data_sample_t *sample)
|
||
{
|
||
uint8_t reSample = 0;
|
||
|
||
Modbus_Close();
|
||
|
||
// 默认读取失败
|
||
sample->staDPress.status = SENSOR_STATUS_NOCONNECT;
|
||
sample->adDPress = 0;
|
||
sample->diff = 0;
|
||
|
||
// 初始化
|
||
modbus_sample = sample;
|
||
modbus_idx = 0;
|
||
|
||
// 发送
|
||
rs_initial_frame(&RS_TranFrame);
|
||
RS_TranFrame.cmd = RS_CMD_READ_DATA;
|
||
rs_append_data(&RS_TranFrame, (uint8_t *) &reSample, 1);
|
||
rs_uart_send(&RS_TranFrame, 0x31, RS_DIR_M2S);
|
||
|
||
// 等待中断处理
|
||
}
|
||
|
||
// 读取压力数据
|
||
void Sensor_ReadPress(data_sample_t *sample)
|
||
{
|
||
uint8_t reSample = 0;
|
||
|
||
Modbus_Close();
|
||
|
||
// 默认读取失败
|
||
sample->staPress.status = SENSOR_STATUS_NOCONNECT;
|
||
sample->adPress = 0;
|
||
sample->pressure = 0;
|
||
|
||
// 初始化
|
||
modbus_sample = sample;
|
||
modbus_idx = 0;
|
||
|
||
// 发送
|
||
rs_initial_frame(&RS_TranFrame);
|
||
RS_TranFrame.cmd = RS_CMD_READ_DATA;
|
||
rs_append_data(&RS_TranFrame, (uint8_t *) &reSample, 1);
|
||
rs_uart_send(&RS_TranFrame, 0x41, RS_DIR_M2S);
|
||
|
||
// 等待中断处理
|
||
}
|