#include "rain.h" #include "gpio.h" #include "main.h" #include "cmsis_os.h" #include "anemometer_dev.h" //开电 void rainLightPowerOn(void) { HAL_GPIO_WritePin(GPIO_RAIN_PWR_CTRL_GPIO_Port, GPIO_RAIN_PWR_CTRL_Pin, GPIO_PIN_SET); } //关电 void rainLightPowerOff(void) { HAL_GPIO_WritePin(GPIO_RAIN_PWR_CTRL_GPIO_Port, GPIO_RAIN_PWR_CTRL_Pin, GPIO_PIN_RESET); } //获取雨量指令,返回的雨量是十倍,两个字节 void getRainData(void) { uint8_t getRainDataCmd[] = {0x01, 0x03, 0x00, 0x03, 0x00, 0x01, 0x74, 0x0A}; uart_dev_write(g_rain_uart_handle, getRainDataCmd, sizeof(getRainDataCmd)); } //清空雨量指令 void clearRainData(void) { uint8_t getRainDataCmd[] = {0x01, 0x06, 0x01, 0x05, 0x00, 0x00, 0x98, 0x37}; uart_dev_write(g_rain_uart_handle, getRainDataCmd, sizeof(getRainDataCmd)); } //获取光照指令,返回一倍光照,四个字节 void getLightData(void) { uint8_t getRainDataCmd[] = {0x01, 0x03, 0x00, 0x05, 0x00, 0x02, 0xD4, 0x0A}; uart_dev_write(g_rain_uart_handle, getRainDataCmd, sizeof(getRainDataCmd)); } //同时获取光照雨量指令,返回一倍光照,四个字节;十倍雨量两个字节 void getLightRainData(void) { uint8_t getRainDataCmd[] = {0x01, 0x03, 0x00, 0x03, 0x00, 0x04, 0xB4, 0x09}; uart_dev_write(g_rain_uart_handle, getRainDataCmd, sizeof(getRainDataCmd)); } /** * @brief 读取串口数据 * @param * @retval */ static int read_rain_pack(device_handle uart_handle,u_int8_t *buff, u_int32_t buff_size) { u_int32_t offset = 0; char c = 0; unsigned char new_buff[50]; buff_size--; //预留一个'\0'位置 for (int offset = 0; offset < buff_size;) { // 逐字符读取 c = uart_dev_in_char(uart_handle); buff[offset++] = c; // 判断首字符是否是地址,是地址再开始读取,不是则将索引退一步 if(offset == sizeof(unsigned char)) { if(buff[0] != 0x01) { memcpy(buff, buff + 1, offset - 1); offset--; buff_size--; } } // 判断功能码对不对,不对缩一位 else if(buff[1] != 0x06 && buff[1] != 0x03) { memcpy(buff, buff + 1, offset - 1); offset--; buff_size--; } // 读雨量 else if (buff[1] == 0x03 && buff[2] == 0x02 && offset == 7) { return offset; } // 读光照 else if (buff[1] == 0x03 && buff[2] == 0x04 && offset == 9) { return offset; } // 读光照雨量 else if (buff[1] == 0x03 && buff[2] == 0x08 && offset == 13) { return offset; } // 清除雨量 else if (buff[1] == 0x06 & offset == 8) { return offset; } } return 0; } /** * @brief 处理光照数据 * @param * @retval */ static void processLightData(u_int8_t *pMsg) { uint32_t lightVal = pMsg[0]<<24|pMsg[1]<<16|pMsg[2]<<8|pMsg[3]; g_stMcs_Para.lightIntensity = lightVal; // term_printf("lightVal:%d", lightVal); } /** * @brief 处理雨量数据 * @param * @retval */ static void processRainData(u_int8_t *pMsg) { uint32_t rainVal = pMsg[0]<<8|pMsg[1]; g_stMcs_Para.precipitation = rainVal; // term_printf("lightVal:%d", rainVal); } /** * @brief 处理光照雨量数据 * @param * @retval */ static void processLightRainData(u_int8_t *lightMsg, u_int8_t *rainMsg) { uint32_t rainVal = rainMsg[0]<<8|rainMsg[1]; uint32_t lightVal = lightMsg[0]<<24|lightMsg[1]<<16|lightMsg[2]<<8|lightMsg[3]; g_stMcs_Para.precipitation = rainVal; g_stMcs_Para.lightIntensity = lightVal; // term_printf("lightVal:%d", rainVal); } /** * @brief 处理雨量清零数据 * @param * @retval */ static void process0RainData(u_int8_t *pMsg) { } /** * @brief modbus crc16算法 * @param * @retval */ static 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 */ #define RAIN_BUFF_CRC16(x) ((x[MsgLen - 2]) | (x[MsgLen - 1] << 8)) static void rainMsgHandler(device_handle device, u_int8_t *pMsg, u_int32_t MsgLen) { if(CRC16(pMsg, MsgLen-2) != RAIN_BUFF_CRC16(pMsg)) { // term_printf("CRC不过"); return; } if((pMsg[1] != 0x03) && (pMsg[1] != 0x06)) { // term_printf("功能码不过"); return; } uint8_t msgData[4] = {0}; switch(MsgLen) { //雨量数据 case 7: msgData[0] = pMsg[3]; msgData[1] = pMsg[4]; processRainData(msgData); break; //清空雨量返回 case 8: msgData[0] = pMsg[4]; msgData[1] = pMsg[5]; process0RainData(msgData); break; //数据光照 case 9: msgData[0] = pMsg[3]; msgData[1] = pMsg[4]; msgData[2] = pMsg[5]; msgData[3] = pMsg[6]; processLightData(msgData); break; //数据光照雨量 case 13: msgData[0] = pMsg[7]; msgData[1] = pMsg[8]; msgData[2] = pMsg[9]; msgData[3] = pMsg[10]; uint8_t rainMsg[] = {pMsg[3], pMsg[4]};//雨量 processLightRainData(msgData, rainMsg); break; default: break; } } /** * @brief 读取并解析串口数据 * @param * @retval */ static u_int8_t rs485_buff[20]={0x00}; void readProcessRainData(device_handle device) { if(uart_dev_char_present(device)) { osDelay(20); memset(rs485_buff,0,sizeof(rs485_buff)); int ret = read_rain_pack(device, rs485_buff, sizeof(rs485_buff)); if(ret > 0) { rainMsgHandler(device, rs485_buff, ret); } } }