237 lines
5.4 KiB
C
237 lines
5.4 KiB
C
#include "mf.h"
|
||
|
||
int flow_addr = 1; //流量计地址
|
||
double flow1 = 0; //小流量计mf4700累积流量
|
||
double flow2 = 0; //大流量计mf5003累积流量
|
||
double flow3 = 0; //大流量计mf5008累积流量
|
||
int mf_cnt = 0; //数据接收计数
|
||
|
||
uint8_t tx_buf[20] = {0}; //数据发送数组
|
||
|
||
uint8_t mf4700_buf[36] = {0};//小流量计mf4700累积流量数据接收数组
|
||
uint8_t mf5003_buf[36] = {0};//大流量计mf5003累积流量数据接收数组
|
||
uint8_t mf5008_buf[36] = {0};//大流量计mf5008累积流量数据接收数组
|
||
|
||
/*
|
||
*发送:[硬件地址][03][起始地址高][起始地址低][总寄存器数高][总寄存器数低][CRC低][CRC高]
|
||
*返回:[硬件地址][03][字节数][寄存器0高][寄存器0低][寄存器1高][寄存器1低][寄存器n高][寄存器n低][CRC低][CRC高]
|
||
*/
|
||
void read_mf(uint8_t local_addr, uint16_t start_addr, uint16_t read_len)
|
||
{
|
||
uint8_t tx_len = 0;
|
||
uint16_t CRC_Num = 0;
|
||
|
||
tx_buf[tx_len ++] = local_addr; //通讯地址
|
||
tx_buf[tx_len ++] = Read_Hold; //命令字 0x03
|
||
tx_buf[tx_len ++] = (uint8_t)(start_addr >> 8);
|
||
tx_buf[tx_len ++] = (uint8_t)(start_addr & 0xFF); //起始地址
|
||
tx_buf[tx_len ++] = (uint8_t)(read_len >> 8);
|
||
tx_buf[tx_len ++] = (uint8_t)(read_len & 0xFF); //读取寄存器数
|
||
|
||
CRC_Num = ModbusCRC16(tx_buf,tx_len);
|
||
tx_buf[tx_len ++] = (uint8_t)(CRC_Num & 0xFF);
|
||
tx_buf[tx_len ++] = (uint8_t)(CRC_Num >> 8); //CRC校验,低位在前
|
||
|
||
usart6_send(tx_buf,tx_len);
|
||
}
|
||
|
||
/*
|
||
*发送:[硬件地址][06][寄存器地址高][寄存器地址低][寄存器值高][寄存器值低][CRC低][CRC高]
|
||
*返回:[硬件地址][06][寄存器地址高][寄存器地址低][寄存器值高][寄存器值低][CRC低][CRC高]
|
||
*/
|
||
void write_mf(uint8_t local_addr, uint16_t reg_addr, uint16_t write_data)
|
||
{
|
||
uint8_t tx_len = 0;
|
||
uint16_t CRC_Num = 0;
|
||
|
||
tx_buf[tx_len ++] = local_addr; //通讯地址
|
||
tx_buf[tx_len ++] = Write_Single; //命令字 0x06
|
||
tx_buf[tx_len ++] = (uint8_t)(reg_addr >> 8);
|
||
tx_buf[tx_len ++] = (uint8_t)(reg_addr & 0xFF); //起始地址
|
||
tx_buf[tx_len ++] = (uint8_t)(write_data >> 8);
|
||
tx_buf[tx_len ++] = (uint8_t)(write_data & 0xFF); //写入数据
|
||
|
||
CRC_Num = ModbusCRC16(tx_buf,tx_len);
|
||
tx_buf[tx_len ++] = (uint8_t)(CRC_Num & 0xFF);
|
||
tx_buf[tx_len ++] = (uint8_t)(CRC_Num >> 8); //CRC校验,低位在前
|
||
|
||
usart6_send(tx_buf,tx_len);
|
||
}
|
||
|
||
//读mf4700瞬时流量
|
||
void read_mf4700_flow(void)
|
||
{
|
||
read_mf(MF4700_ADDR,MF4700_Ins_Flow_Addr,2);
|
||
}
|
||
|
||
//读mf4701累积流量
|
||
void read_mf4701_flow(void)
|
||
{
|
||
read_mf(MF4700_ADDR,MF4700_Cum_Flow_Addr,3);
|
||
}
|
||
|
||
//读mf5600瞬时流量
|
||
void read_mf5000_flow(void)
|
||
{
|
||
read_mf(MF5003_ADDR,MF5000_Ins_Flow_Addr,2);
|
||
}
|
||
|
||
//读mf5603累积流量
|
||
void read_mf5003_flow(void)
|
||
{
|
||
read_mf(MF5003_ADDR,MF5000_Cum_Flow_Addr,3);
|
||
}
|
||
|
||
//读mf5608累积流量
|
||
void read_mf5008_flow(void)
|
||
{
|
||
read_mf(MF5008_ADDR,MF5000_Cum_Flow_Addr,3);
|
||
}
|
||
|
||
//mf4700自动校零
|
||
void mf4700_zero(void)
|
||
{
|
||
write_mf(MF4700_ADDR,MF4700_Auto_Zero_Addr,General_Data);
|
||
}
|
||
|
||
//mf5600自动校零
|
||
void mf5000_zero(void)
|
||
{
|
||
write_mf(MF5003_ADDR,MF5000_Auto_Zero_Addr,General_Data);
|
||
}
|
||
|
||
//获取流量计读数,存入保持寄存器
|
||
void mf_read(void)
|
||
{
|
||
switch(flow_addr)
|
||
{
|
||
case 1 :
|
||
{
|
||
read_mf4701_flow();
|
||
flow1 = mf4700_buf[3] * pow(2,24) + mf4700_buf[4] * pow(2,16) + mf4700_buf[5] * pow(2,8) + mf4700_buf[6]
|
||
+ ( mf4700_buf[7] * pow(2,8) + mf4700_buf[8] ) / 1000;
|
||
if(flow1 > 655) flow1 = 655;
|
||
InputReg[5] = flow1 * 100;
|
||
flow_addr++;
|
||
}
|
||
break;
|
||
case 2 :
|
||
{
|
||
read_mf5003_flow();
|
||
flow2 = mf5003_buf[3] * pow(2,24) + mf5003_buf[4] * pow(2,16) + mf5003_buf[5] * pow(2,8) + mf5003_buf[6]
|
||
+ ( mf5003_buf[7] * pow(2,8) + mf5003_buf[8] ) / 1000;
|
||
if(flow2 > 65) flow2 = 65;
|
||
InputReg[6] = flow2 * 1000;
|
||
flow_addr++;
|
||
}
|
||
break;
|
||
case 3 :
|
||
{
|
||
// read_mf5008_flow();
|
||
// flow3 = mf5008_buf[3] * pow(2,24) + mf5008_buf[4] * pow(2,16) + mf5008_buf[5] * pow(2,8) + mf5008_buf[6]
|
||
// + ( mf5008_buf[7] * pow(2,8) + mf5008_buf[8] ) / 1000;
|
||
// memset(usart6_rx_buf,0,12);
|
||
flow_addr = 1;
|
||
}
|
||
break;
|
||
}
|
||
}
|
||
|
||
//清除累积流量
|
||
//mf4700需要手动向累积流量寄存器写0
|
||
//mf5003和mf5008需要先向写保护寄存器写入0xAA55关闭写保护,然后向指定寄存器写入0x0001清除累积流量
|
||
void mf_clear(void)
|
||
{
|
||
switch(flow_state)
|
||
{
|
||
case 0 :
|
||
{
|
||
write_mf(MF4700_ADDR,0x04,0x0000);
|
||
flow_state++;
|
||
}
|
||
break;
|
||
case 1 :
|
||
{
|
||
write_mf(MF4700_ADDR,0x05,0x0000);
|
||
flow_state++;
|
||
}
|
||
break;
|
||
case 2 :
|
||
{
|
||
write_mf(MF4700_ADDR,0x06,0x0000);
|
||
flow_state++;
|
||
}
|
||
break;
|
||
case 3 :
|
||
{
|
||
write_mf(MF5003_ADDR,MF5000_Write_Protec,General_Data);
|
||
flow_state++;
|
||
}
|
||
break;
|
||
case 4 :
|
||
{
|
||
write_mf(MF5003_ADDR,MF5000_Clear_Addr,Clear_Data);
|
||
flow_state++;
|
||
}
|
||
break;
|
||
case 5 :
|
||
{
|
||
//memset(usart6_rx_buf,0,12);
|
||
flow_state++;
|
||
}
|
||
break;
|
||
}
|
||
}
|
||
|
||
|
||
|
||
void mf_rx_cb(void)
|
||
{
|
||
// 空闲中断,表明接收到了1帧所有的数据
|
||
if(LL_USART_IsActiveFlag_IDLE(USART6))
|
||
{
|
||
//清除空闲中断
|
||
LL_USART_ClearFlag_IDLE(USART6);
|
||
int j = 0;
|
||
//根据地址将数据分别存入不同的数组
|
||
if(usart6_rx_buf[0] == 0x01 && usart6_rx_buf[1] == 0x03)
|
||
{
|
||
for(j = 0;j < mf_cnt+1;j++)
|
||
{
|
||
mf4700_buf[j] = usart6_rx_buf[j];
|
||
}
|
||
}
|
||
else if(usart6_rx_buf[0] == 0x02 && usart6_rx_buf[1] == 0x03)
|
||
{
|
||
for(j = 0;j < mf_cnt+1;j++)
|
||
{
|
||
mf5003_buf[j] = usart6_rx_buf[j];
|
||
}
|
||
}
|
||
else if(usart6_rx_buf[0] == 0x03 && usart6_rx_buf[1] == 0x03)
|
||
{
|
||
for(j = 0;j < mf_cnt+1;j++)
|
||
{
|
||
mf5008_buf[j] = usart6_rx_buf[j];
|
||
}
|
||
}
|
||
else
|
||
{
|
||
|
||
}
|
||
mf_cnt = 0;
|
||
|
||
}
|
||
|
||
// Rx非空中断,表明接收到了一个字节
|
||
// 读取Rx可自动清除中断标志位
|
||
if(LL_USART_IsActiveFlag_RXNE(USART6))
|
||
{
|
||
// 如果数组长度大于设置的data最大长度,直接停止接收
|
||
if(mf_cnt > 50)
|
||
mf_cnt = 0; // wait for the next data
|
||
usart6_rx_buf[mf_cnt] = LL_USART_ReceiveData8(USART6);
|
||
mf_cnt ++;
|
||
}
|
||
}
|