acdt/board/Src/mf.c

235 lines
5.4 KiB
C
Raw Permalink 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 "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 ++;
}
}