#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[22] = 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[23] = 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(__HAL_UART_GET_FLAG(&huart6, UART_FLAG_IDLE) != RESET) { //清除空闲中断 __HAL_UART_CLEAR_IDLEFLAG(&huart6); 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(__HAL_UART_GET_FLAG(&huart1, UART_FLAG_RXNE) != RESET) { uint8_t rx_res = 0; HAL_UART_Receive(&huart6, &rx_res, 1, 1000); __HAL_UART_CLEAR_FLAG(&huart6, UART_FLAG_RXNE); //清楚接收中断 // 如果数组长度大于设置的data最大长度,直接停止接收 if(mf_cnt > 50) mf_cnt = 0; // wait for the next data usart6_rx_buf[mf_cnt] = rx_res; mf_cnt ++; } }