#include "frt_protocol.h" #include "cmsis_os.h" #include "assertions.h" #include "inflash.h" #include "anemometer_dev.h" #include "sht30.h" #include "hp203b.h" extern u_int8_t rs485_out_buff[50]; extern uart_device_info uart_devices[]; /* 静态函数申明 */ static void send_uart_pack(device_handle device,FRT_MsgFunctionCode_e cmd_type, const void *data, u_int16_t len); static void FRT_MsgProc_ReadRegister(device_handle device, void *pMsg); static void FRT_MsgProc_WriteRegister(device_handle device, void *pMsg); static u_int16_t FRT_ReadReg(unsigned char regId); static u_int16_t FRT_ReadRegMinWindDiretion(void *pMsg); static u_int16_t FRT_ReadRegAverageWindDirection(void *pMsg); static u_int16_t FRT_ReadRegMaxWindDirection(void *pMsg); static u_int16_t FRT_ReadRegMinWindSpeed(void *pMsg); static u_int16_t FRT_ReadRegAverageWindSpeed(void *pMsg); static u_int16_t FRT_ReadRegMaxWindSpeed(void *pMsg); static u_int16_t FRT_ReadRegTemperature(void *pMsg); static u_int16_t FRT_ReadRegHumidity(void *pMsg); static u_int16_t FRT_ReadRegPressure(void *pMsg); static u_int16_t FRT_ReadRegRain(void *pMsg); static u_int16_t FRT_ReadRegPrecipitationIntensity(void *pMsg); static u_int16_t FRT_ReadRegDeviceAddr(void *pMsg); static u_int16_t FRT_ReadRegCommuBaudRate(void *pMsg); static u_int16_t FRT_ReadRegSpeedAverageTime(void *pMsg); static u_int16_t FRT_ReadRegTempHumUpdateTime(void *pMsg); static u_int16_t FRT_ReadRegRainPowerCtl(void *pMsg); static u_int16_t FRT_WriteRegDeviceAddr(void *pMsg); static u_int16_t FRT_WriteRegCommuBaudRate(void *pMsg); static u_int16_t FRT_WriteRegSpeedAverageTime(void *pMsg); static u_int16_t FRT_WriteRegTempHumUpdateTime(void *pMsg); static u_int16_t FRT_WriteRegSoftReset(void *pMsg); static u_int16_t FRT_WriteRegResetDefault(void *pMsg); static void pdebug_mcs_info(); /* 功能码处理表 */ FRT_FuncionMsgProcTable_s g_MsgTbl[] = { { FRT_FUNCTION_CODE_READ_REGISTER, FRT_MsgProc_ReadRegister }, { FRT_FUNCTION_CODE_WRITE_REGISTER, FRT_MsgProc_WriteRegister }, }; /* 读寄存器处理表 */ FRT_RegProcTable_s g_RegTbl[] = { { FRT_REGISTER_MIN_WIND_DIRECTION, FRT_ReadRegMinWindDiretion }, /* 最小风向 */ { FRT_REGISTER_AVERAGE_WIND_DIRECTION, FRT_ReadRegAverageWindDirection }, /* 平均风向 */ { FRT_REGISTER_MAX_WIND_DIRECTION, FRT_ReadRegMaxWindDirection }, /* 最大风向 */ { FRT_REGISTER_MIN_WIND_SPEED, FRT_ReadRegMinWindSpeed }, /* 最小风速 */ { FRT_REGISTER_AVERAGE_WIND_SPEED, FRT_ReadRegAverageWindSpeed }, /* 平均风速 */ { FRT_REGISTER_MAX_WIND_SPEED, FRT_ReadRegMaxWindSpeed }, /* 最大风速 */ { FRT_REGISTER_TEMPERATURE, FRT_ReadRegTemperature }, /* 大气温度 */ { FRT_REGISTER_HUMIDITY, FRT_ReadRegHumidity }, /* 大气湿度 */ { FRT_REGISTER_PRESSURE, FRT_ReadRegPressure }, /* 大气压 */ { FRT_REGISTER_RAIN, FRT_ReadRegRain }, /* 雨量 */ { FRT_REGISTER_PRECIPITATION_INTENSITY, FRT_ReadRegPrecipitationIntensity }, /* 总辐射 */ { FRT_REGISTER_DEVICE_ADDR, FRT_ReadRegDeviceAddr }, /* 设备地址 */ { FRT_REGISTER_COMMU_BAUDRATE, FRT_ReadRegCommuBaudRate }, /* 波特率 */ { FRT_REGISTER_SPEED_AVERAGE_TIME, FRT_ReadRegSpeedAverageTime }, /* 风速平均时间 */ { FRT_REGISTER_TEMPHUM_UPDATE_TIME, FRT_ReadRegTempHumUpdateTime }, /* 温湿度更新时间 */ { FRT_REGISTER_RAIN_POWER_CONTROL, FRT_ReadRegRainPowerCtl }, /* 雨量电源时间 */ }; /* 写寄存器处理表 */ FRT_RegProcTable_s g_Write_RegTbl[] = { { FRT_REGISTER_DEVICE_ADDR, FRT_WriteRegDeviceAddr }, /* 写设备地址 */ { FRT_REGISTER_COMMU_BAUDRATE, FRT_WriteRegCommuBaudRate }, /* 写波特率 */ { FRT_REGISTER_SPEED_AVERAGE_TIME, FRT_WriteRegSpeedAverageTime }, /* 写风速平均时间 */ { FRT_REGISTER_TEMPHUM_UPDATE_TIME, FRT_WriteRegTempHumUpdateTime }, /* 写温湿度更新时间 */ { FRT_REGISTER_SOFT_REST, FRT_WriteRegSoftReset }, /* 软件复位 */ { FRT_REGISTER_REST_DEFAULT_SETTING, FRT_WriteRegResetDefault }, /* 恢复出厂设置 */ }; /** * @brief modbus crc16算法 * @param * @retval */ unsigned short CRC16(unsigned char *arr_buff, unsigned char len) { unsigned short crc=0xFFFF; unsigned char i, j; for ( j=0; j0){ crc=crc>>1; crc=crc^ 0xa001; }else{ crc=crc>>1; } } } return crc; } /** * @brief 交换高低字节 * @param * @retval */ static u_int16_t FRT_swap_endian_16(u_int16_t value) { return ((value << 8) | (value >> 8)); } /** * @brief 读最小风向寄存器值 * @param * @retval */ static u_int16_t FRT_ReadRegMinWindDiretion(void *pMsg) { u_int16_t value = (u_int16_t)(g_stMcs_Para.min_wind_direction *10); return FRT_swap_endian_16(value); } /** * @brief 读平均风向寄存器值 * @param * @retval */ static u_int16_t FRT_ReadRegAverageWindDirection(void *pMsg) { u_int16_t value = (u_int16_t)(g_stMcs_Para.average_wind_direction *10); return FRT_swap_endian_16(value); } /** * @brief 读最大风向寄存器值 * @param * @retval */ static u_int16_t FRT_ReadRegMaxWindDirection(void *pMsg) { u_int16_t value=(u_int16_t)(g_stMcs_Para.max_wind_direction *10); return FRT_swap_endian_16(value); } /** * @brief 读最小风速寄存器值 * @param * @retval */ static u_int16_t FRT_ReadRegMinWindSpeed(void *pMsg) { u_int16_t value=(u_int16_t)(g_stMcs_Para.min_wind_speed *10); return FRT_swap_endian_16(value); } /** * @brief 读平均风速寄存器值 * @param * @retval */ static u_int16_t FRT_ReadRegAverageWindSpeed(void *pMsg) { u_int16_t value=(u_int16_t)(g_stMcs_Para.average_wind_speed *10); return FRT_swap_endian_16(value); } /** * @brief 读最大风速寄存器值 * @param * @retval */ static u_int16_t FRT_ReadRegMaxWindSpeed(void *pMsg) { u_int16_t value=(u_int16_t)(g_stMcs_Para.max_wind_speed *10); return FRT_swap_endian_16(value); } /** * @brief 读温度寄存器值 * @param * @retval */ static u_int16_t FRT_ReadRegTemperature(void *pMsg) { u_int16_t value= (u_int16_t)(g_stMcs_Para.temperature*10); return FRT_swap_endian_16(value); } /** * @brief 读湿度寄存器值 * @param * @retval */ static u_int16_t FRT_ReadRegHumidity(void *pMsg) { u_int16_t value=(u_int16_t)(g_stMcs_Para.humidity*10); return FRT_swap_endian_16(value); } /** * @brief 读气压寄存器值 * @param * @retval */ static u_int16_t FRT_ReadRegPressure(void *pMsg) { u_int16_t value=(u_int16_t)(g_stMcs_Para.pressure*10); return FRT_swap_endian_16(value); } /** * @brief 读雨量寄存器值 * @param * @retval */ static u_int16_t FRT_ReadRegRain(void *pMsg) { u_int16_t value=9; return FRT_swap_endian_16(value); } /** * @brief 读光辐射强度寄存器值 * @param * @retval */ static u_int16_t FRT_ReadRegPrecipitationIntensity(void *pMsg) { u_int16_t value=10; return FRT_swap_endian_16(value); } /** * @brief 读设备地址寄存器值 * @param * @retval */ static u_int16_t FRT_ReadRegDeviceAddr(void *pMsg) { read_config_info(); u_int16_t value=g_stConfigInfo.addr; return FRT_swap_endian_16(value); } /** * @brief 读波特率寄存器值 * @param * @retval */ static u_int16_t FRT_ReadRegCommuBaudRate(void *pMsg) { read_config_info(); u_int16_t value=g_stConfigInfo.uart_baud; // term_printf("%x", value); return FRT_swap_endian_16(value); } /** * @brief 读风速平均时间值 * @param * @retval */ static u_int16_t FRT_ReadRegSpeedAverageTime(void *pMsg) { read_config_info(); u_int16_t value=g_stConfigInfo.speed_average_time; return FRT_swap_endian_16(value); } /** * @brief 读温湿度更新时间值 * @param * @retval */ static u_int16_t FRT_ReadRegTempHumUpdateTime(void *pMsg) { read_config_info(); u_int16_t value=g_stConfigInfo.temp_hum_update_time; return FRT_swap_endian_16(value); } /** * @brief 读雨量电源控制值 * @param * @retval */ static u_int16_t FRT_ReadRegRainPowerCtl(void *pMsg) { return 0; } /** * @brief 写设备地址 * @param * @retval */ static u_int16_t FRT_WriteRegDeviceAddr(void *pMsg) { uint16_t *pMsgAddr = (uint16_t *)pMsg; uint16_t data = *pMsgAddr; g_stConfigInfo.addr = data; save_config_info(g_stConfigInfo); return 0; } /** * @brief 写波特率 * @param * @retval */ static u_int16_t FRT_WriteRegCommuBaudRate(void *pMsg) { uint16_t *pMsgAddr = (uint16_t *)pMsg; uint16_t data = *pMsgAddr; g_stConfigInfo.uart_baud = data; save_config_info(g_stConfigInfo); MX_USART3_UART_Init(g_stConfigInfo.uart_baud); MX_USART1_UART_Init(g_stConfigInfo.uart_baud); return 0; } /** * @brief 写风速平均时间 * @param * @retval */ static u_int16_t FRT_WriteRegSpeedAverageTime(void *pMsg) { uint16_t *pMsgAddr = (uint16_t *)pMsg; uint16_t data = *pMsgAddr; g_stConfigInfo.speed_average_time = data; save_config_info(g_stConfigInfo); return 0; } /** * @brief 写温湿度更新时间 * @param * @retval */ static u_int16_t FRT_WriteRegTempHumUpdateTime(void *pMsg) { uint16_t *pMsgAddr = (uint16_t *)pMsg; uint16_t data = *pMsgAddr; g_stConfigInfo.temp_hum_update_time = data; save_config_info(g_stConfigInfo); return 0; } /** * @brief 软件复位 * @param * @retval */ static u_int16_t FRT_WriteRegSoftReset(void *pMsg) { uint16_t *pMsgAddr = (uint16_t *)pMsg; uint16_t data = *pMsgAddr; if(data == 0x0001) { __iar_builtin_set_FAULTMASK(1); NVIC_SystemReset(); } return 0; } /** * @brief 恢复出厂设置 * @param * @retval */ static u_int16_t FRT_WriteRegResetDefault(void *pMsg) { uint16_t *pMsgAddr = (uint16_t *)pMsg; uint16_t data = *pMsgAddr; if(data == 0x0001) { delete_config_info(); __iar_builtin_set_FAULTMASK(1); NVIC_SystemReset(); } return 0; } /** * @brief 封装协议发送 * @param * @retval 数据正确返回TRUE,数据异常返回FALSE */ static void send_uart_pack(device_handle device,FRT_MsgFunctionCode_e cmd_type, const void *data, u_int16_t len) { memset(rs485_out_buff,0,sizeof(rs485_out_buff)); frt_climate_pack_resp *pack = (frt_climate_pack_resp*)rs485_out_buff; pack->addr = g_stConfigInfo.addr; pack->func = FRT_FUNCTION_CODE_READ_REGISTER; pack->data_len = len; memcpy(pack->data, data, len); *(u_int16_t*)&pack->data[len] = CRC16((u_int8_t *)&pack->addr,pack->data_len+3); uart_dev_write(device,(u_int8_t*)pack,pack->data_len+5); } /** * @brief 遍历读取寄存器 * @param * @retval */ u_int16_t FRT_ReadReg(unsigned char regId) { for(u_int16_t i = 0; i < sizeof(g_RegTbl) / sizeof(FRT_RegProcTable_s); i++){ //term_printf("regId:%d, g_RegTbl.regId :%d\r\n",regId,g_RegTbl[i].regId); if (regId == g_RegTbl[i].regId){ return g_RegTbl[i].pRegProc(NULL); } } return 0; } /** * @brief 处理读取寄存器数据 * @param * @retval */ void FRT_MsgProc_ReadRegister(device_handle device, void *pMsg) { // static u_int8_t reg_value_buff[2*100]={0x00}; // // memset(reg_value_buff,0,sizeof(reg_value_buff)); // frt_climate_pack *pack = (frt_climate_pack*)pMsg; // // u_int16_t start_reg_addr = (pack->addr_begin_high_byte<<8)| pack->addr_begin_low_byte; // u_int16_t reg_num= (pack->regnum_begin_high_byte<<8)| pack->regnum_begin_low_byte; // // AssertError(start_reg_addr < 100,return, "读取寄存器起始地址错误%d",start_reg_addr); // AssertError(reg_num < 100,return, "读取寄存器数量错误%d",reg_num); // // /* 采集sht30数据 */ // AssertError(get_temp_humi_data(&g_stMcs_Para.temperature, &g_stMcs_Para.humidity),g_stMcs_Para.temperature=0;g_stMcs_Para.humidity=0,"采集sht30温湿度数据失败" ); // //// /* 调试信息 */ //// pdebug_mcs_info(); // // for(u_int16_t pos=0; pos 0x08 && start_reg_addr < 0x14) || start_reg_addr > 0x17) { term_printf("start_reg_addr error:%d", start_reg_addr); return; } if (reg_num < 0x01 || (((reg_num + start_reg_addr - 1) > 0x08) && ((reg_num + start_reg_addr - 1) < 0x14)) || ((reg_num + start_reg_addr -1) > 0x17)) { term_printf("reg_num error:%d", reg_num); return; } //采集气压数据 uint8_t tttt[] = {0xff, 0xff}; HAL_I2C_Master_Transmit(&hi2c3, 0xEE, tttt, 1, 0xFF); /* 采集sht30数据 */ // AssertError(get_temp_humi_data(&g_stMcs_Para.temperature, &g_stMcs_Para.humidity),g_stMcs_Para.temperature=0;g_stMcs_Para.humidity=0,"采集sht30温湿度数据失败" ); // /* 调试信息 */ // pdebug_mcs_info(); static u_int8_t reg_value_buff[2*100]={0x00}; memset(reg_value_buff,0,sizeof(reg_value_buff)); for(u_int16_t pos=0; pos 0x1C ) { term_printf("start_reg_addr error:%d", start_reg_addr); return; } if (reg_num < 0x01 || ((reg_num + start_reg_addr - 1) < 0x14) || ((reg_num + start_reg_addr -1) > 0x1C)) { term_printf("reg_num error:%d", reg_num); return; } // 取出数据 uint16_t content[50] = {0}; for (uint16_t var = 0; var < reg_num; var++) { content[var] = data[7 + 2 * var] << 8 | data[7 + 2 * var + 1]; } //// 调试 // for (int i = 0; i < 20; i++) // { // term_printf("%x", content[i]); // } // 发回数据 uint8_t Trans_data[6]; Trans_data[0] = g_stConfigInfo.addr; Trans_data[1] = data[1]; Trans_data[2] = start_reg_addr; Trans_data[3] = reg_num; return_crc_value = CRC16(Trans_data, 4); Trans_data[4] = return_crc_value; Trans_data[5] = return_crc_value >> 8; uart_dev_write(device, Trans_data, 6); for(u_int16_t pos=0; pos addr)){ // if (pack->addr != g_stConfigInfo.addr){ // memcpy(buff, buff+1, offset-1); // offset--; // buff_size--; // } // }else if (offset == FRT_CLIMATE_PACK_SIZE(pack)){ // return offset; // } // } return 0; } /** * @brief 读取处理后的485BUFF数据 * @param * @retval */ static int buff_read_frt_climate_pack(u_int8_t *buff, u_int32_t buff_size) { u_int32_t offset = 0; // frt_climate_pack *pack = (frt_climate_pack *)buff; unsigned char new_buff[50]; buff_size--; //预留一个'\0'位置 int start_index = buff_size; // 初始化为一个不可能的值 // 遍历数组以找到符合条件的字节对 for (int i = 0; i < buff_size; i += 1) { if ((buff[i] == g_stConfigInfo.addr) && ((buff[i + 1] == FRT_FUNCTION_CODE_READ_REGISTER) || (buff[i + 1] == FRT_FUNCTION_CODE_WRITE_REGISTER))) { start_index = i; // 从符合条件的字节对开始复制 // term_printf("%d", i); break; } } if (start_index == buff_size) { return 0; } memcpy(new_buff, buff + start_index, buff_size - start_index); // for (int i = 0; i < buff_size; i++) { // term_printf("%x ", new_buff[i]); // } // term_printf("\r\n"); memcpy(buff, 0, buff_size); memcpy(buff, new_buff, buff_size - start_index); if (new_buff[1] == FRT_FUNCTION_CODE_READ_REGISTER) { offset = 8; return offset; } if (new_buff[1] == FRT_FUNCTION_CODE_WRITE_REGISTER) { u_int32_t regnum = 0; offset = 7; regnum = new_buff[6]; offset = offset + regnum * 2 + 2; return offset; } // for (offset = 0; offset < buff_size;){ // c = uart_dev_in_char(uart_handle); // buff[offset++] = c; // if (offset == sizeof(pack->addr)){ // if (pack->addr != g_stConfigInfo.addr){ // memcpy(buff, buff+1, offset-1); // offset--; // buff_size--; // } // }else if (offset == FRT_CLIMATE_PACK_SIZE(pack)){ // return offset; // } // } return 0; } /** * @brief 处理一条消息 * @param * @retval */ void FRT_MsgHandler(device_handle device, u_int8_t *pMsg, u_int32_t MsgLen) { // frt_climate_pack *pack = (frt_climate_pack*)pMsg; // // //AssertErrorNoPrint((CRC16(pMsg, MsgLen-2) == FRT_CLIMATE_PACK_CRC16(pHeader)),return); //// AssertError((CRC16(pMsg, MsgLen-2) == FRT_CLIMATE_PACK_CRC16(pack)),return,"crc16校验失败"); //// AssertError((pack->func == FRT_FUNCTION_CODE_READ_REGISTER) ||\ //// (pack->func == FRT_FUNCTION_CODE_WRITE_REGISTER),return,"crc16校验失败"); //// 断言有问题,CRC出错卡死 // if(CRC16(pMsg, MsgLen-2) != FRT_CLIMATE_PACK_CRC16(pack)) // { //// term_printf("CRC不过"); // return; // } // if((pack->func != FRT_FUNCTION_CODE_READ_REGISTER) && (pack->func != FRT_FUNCTION_CODE_WRITE_REGISTER)) // { //// term_printf("功能码不过"); // return; // } // // for (u_int16_t i = 0; i < sizeof(g_MsgTbl) / sizeof(FRT_FuncionMsgProcTable_s); i++){ // if (pack->func == g_MsgTbl[i].msgId){ // g_MsgTbl[i].pMsgProc(device, pMsg); // } // } if(CRC16(pMsg, MsgLen-2) != FRT_CLIMATE_BUFF_CRC16(pMsg)) { // term_printf("CRC不过"); return; } if((pMsg[1] != FRT_FUNCTION_CODE_READ_REGISTER) && (pMsg[1] != FRT_FUNCTION_CODE_WRITE_REGISTER)) { // term_printf("功能码不过"); return; } for (u_int16_t i = 0; i < sizeof(g_MsgTbl) / sizeof(FRT_FuncionMsgProcTable_s); i++){ if (pMsg[1] == g_MsgTbl[i].msgId){ g_MsgTbl[i].pMsgProc(device, pMsg); } } } /** * @brief 读取并解析串口数据 * @param * @retval */ static u_int8_t rs485_buff[50]={0x00}; void read_and_process_uart_data(device_handle device) { if(uart_dev_char_present(device)){ osDelay(20); memset(rs485_buff,0,sizeof(rs485_buff)); int ret = uart_read_frt_climate_pack(device, rs485_buff, sizeof(rs485_buff)); // for(int temp = 0; temp < 10; temp++) // { // if(temp != 0){ // ret = buff_read_frt_climate_pack(rs485_buff, sizeof(rs485_buff));} if(ret > 0){ FRT_MsgHandler(device, rs485_buff, ret); } // } } } /* 打印微气象数据 */ static void pdebug_mcs_info() { term_printf("min_wind_direction: %.2f\r\n", g_stMcs_Para.min_wind_direction); term_printf("average_wind_direction: %.2f\r\n", g_stMcs_Para.average_wind_direction); term_printf("max_wind_direction: %.2f\r\n", g_stMcs_Para.max_wind_direction); term_printf("min_wind_speed: %.2f\r\n", g_stMcs_Para.min_wind_speed); term_printf("average_wind_speed: %.2f\r\n", g_stMcs_Para.average_wind_speed); term_printf("max_wind_speed: %.2f\r\n", g_stMcs_Para.max_wind_speed); term_printf("temperature: %.2f\r\n", g_stMcs_Para.temperature); term_printf("humidity: %.2f\r\n", g_stMcs_Para.humidity); term_printf("pressure: %.2f\r\n", g_stMcs_Para.pressure); term_printf("rain: %.2f\r\n", g_stMcs_Para.precipitation); // term_printf("precipitation_intensity: %.2f\r\n", g_stMcs_Para.precipitation_intensity); } // 30 03 00 00 00 0B 00 2C