/* ********************************************************************************************************* * IAR Development Kits * on the * * M451 * * Filename : dwin_form.c * Version : V1.00 * Programmer(s) : Qian Xianghong ********************************************************************************************************* */ /* ********************************************************************************************************* * INCLUDE FILES ********************************************************************************************************* */ #include "includes.h" // 提示信息显示时间 uint32_t Form_messageSeconds = 0; // 显示屏读写操作 #define DWIN_OPER_WRITE (0x82) #define DWIN_OPER_READ (0x83) // 显示颜色 #define DWIN_COLOR_BLACK (0x00) #define DWIN_COLOR_WHITE (0xFFFF) #define DWIN_COLOR_RED (0xF800) #define DWIN_COLOR_GREEN (0x07E0) #define DWIN_COLOR_BLUE (0x001F) #define DWIN_COLOR_YELLOW (0xFFE0) // 向屏幕写命令队列 #define FORM_DATA_COUNT 100 loopbuff_t Form_DataM; uint8_t Form_DataM_Data[sizeof(form_data_t) * (FORM_DATA_COUNT + 1)] = {0}; SemaphoreHandle_t Form_DataQ = NULL; SemaphoreHandle_t Form_DataLock = NULL; // 屏幕读取结果队列 #define FORM_READ_COUNT 3 loopbuff_t Form_ReadM; uint8_t Form_ReadM_Data[sizeof(form_data_t) * (FORM_READ_COUNT + 1)] = {0}; SemaphoreHandle_t Form_ReadQ = NULL; // 屏幕按键返回队列 #define FORM_KEY_COUNT 3 loopbuff_t Form_KeyM; uint8_t Form_KeyM_Data[sizeof(form_data_t) * (FORM_KEY_COUNT + 1)] = {0}; SemaphoreHandle_t Form_KeyQ = NULL; // 首页表格,报警页表格,查询表格, 关于表格 form_grid_t gridAll, gridWarn, gridQuery, gridAbout,gridAboutEn; form_grid2_t gridBox; // 用于生成显示屏命令 form_data_t formData; // 记录查询功能(储罐、数据或曲线)和查询条件 form_query_t formQuery; // 重新寻找SOF void DWIN_SearchSOF(uint8_t *buf, uint16_t fromPos, uint16_t *len) { uint16_t i; for(i = fromPos; i < *len && buf[i] != 0x5A; i++) { } *len -= i; memmove(buf, buf + i, *len); } // 分析串口数据,组帧 void DWIN_ParseFrame(uint8_t c) { BaseType_t xHigherPriorityTaskWoken; static uint16_t RdIdx = 0; static uint8_t DWIN_Data[512]; static form_data_t readData; uint8_t frameOk, frameErr; uint16_t i; while(1) { if(RdIdx == 0 && c != 0x5A) return; if(RdIdx == 1 && c != 0xA5) { RdIdx = 0; continue; } if(RdIdx == 3 && c != DWIN_OPER_READ && c != DWIN_OPER_WRITE) { RdIdx = 0; continue; } break; } DWIN_Data[RdIdx++] = c; do { frameErr = ((RdIdx >= 1 && DWIN_Data[0] != 0x5A) || (RdIdx >= 2 && DWIN_Data[1] != 0xA5) || (RdIdx >= 4 && DWIN_Data[3] != DWIN_OPER_READ && DWIN_Data[3] != DWIN_OPER_WRITE)); if(frameErr) { // 从1开始寻找SOF DWIN_SearchSOF(DWIN_Data, 1, &RdIdx); } frameOk = (RdIdx >= 4 && DWIN_Data[0] == 0x5A && DWIN_Data[1] == 0xA5 && (DWIN_Data[3] == DWIN_OPER_READ || DWIN_Data[3] == DWIN_OPER_WRITE) && RdIdx >= DWIN_Data[2] + 3); if(frameOk) { if(DWIN_Data[3] == DWIN_OPER_READ) { readData.oper = DWIN_OPER_READ; readData.Addr = (DWIN_Data[4] << 8) | DWIN_Data[5]; readData.count = DWIN_Data[6] * 2; memmove(readData.byte, DWIN_Data + 7, readData.count); printf("\nRead from screen, 0x%04X (%d bytes):\n", readData.Addr, readData.count); for(i = 0; i < readData.count; i++) printf(" %02X", readData.byte[i]); printf("\n"); // 触摸按键返回 if(readData.Addr == 0x5000 || readData.Addr == 0x5012 || readData.Addr == 0x5030 || readData.Addr == 0x5022 || readData.Addr == 0x502C || readData.Addr == 0x502E || readData.Addr == 0x5032|| readData.Addr == 0x5034|| readData.Addr == 0x5036|| readData.Addr == 0x6F00) { LoopBuff_PutItem(&Form_KeyM, (uint8_t *) &readData); // 发消息给任务 xSemaphoreGiveFromISR(Form_KeyQ, &xHigherPriorityTaskWoken); } else { LoopBuff_PutItem(&Form_ReadM, (uint8_t *) &readData); // 发消息给任务 xSemaphoreGiveFromISR(Form_ReadQ, &xHigherPriorityTaskWoken); } } // 继续寻找下一帧 RdIdx -= (DWIN_Data[2] + 3); memmove(DWIN_Data, DWIN_Data + (DWIN_Data[2] + 3), RdIdx); // 从0开始寻找SOF DWIN_SearchSOF(DWIN_Data, 0, &RdIdx); } } while(frameOk || frameErr); } // DWIN screen uart void DWIN_IRQHandler(USART_Handle *huart) { uint8_t u8DTU = (uint8_t) huart->Instance->DR; //printf("%02X ", u8DTU); DWIN_ParseFrame(u8DTU); } void DWIN_Refresh(form_data_t *pData) { uint16_t i = 0; static uint8_t buf[128]; buf[i++] = 0x5A; buf[i++] = 0xA5; if(pData->oper == DWIN_OPER_WRITE) buf[i++] = 3 + pData->count; else buf[i++] = 3 + 1; buf[i++] = pData->oper; buf[i++] = (pData->Addr >> 8); buf[i++] = (pData->Addr & 0xFF); if(pData->oper == DWIN_OPER_WRITE) { memmove(buf + i, pData->byte, pData->count); i += pData->count; } else buf[i++] = pData->count / 2; UART_Transmit(&huart10, buf, i); } // 模拟一次触控点击 void DWIN_Touch(uint16_t x, uint16_t y) { // 加锁 xSemaphoreTake(Form_DataLock, portMAX_DELAY); formData.oper = DWIN_OPER_WRITE; formData.Addr = 0x00D4; formData.count = 8; formData.word[0] = htons(0x5AA5); formData.word[1] = htons(0x0004); formData.word[2] = htons(x); formData.word[3] = htons(y); // 加入队列 LoopBuff_PutItem(&Form_DataM, (uint8_t *) &formData); // 解锁 xSemaphoreGive(Form_DataLock); // 发送消息给任务 xSemaphoreGive(Form_DataQ); } // 清除提示信息 void Form_ClearMessage() { // 加锁 xSemaphoreTake(Form_DataLock, portMAX_DELAY); formData.oper = DWIN_OPER_WRITE; formData.Addr = 0x5D80; formData.count = 26; memset(formData.str, ' ', formData.count); // 加入队列 LoopBuff_PutItem(&Form_DataM, (uint8_t *) &formData); // 解锁 xSemaphoreGive(Form_DataLock); // 发送消息给任务 xSemaphoreGive(Form_DataQ); } // 提示信息: 最多显示26个字符 void Form_DispMessage(char *str, uint16_t color) { static uint16_t last_color = DWIN_COLOR_WHITE; // 先清除提示信息 Form_ClearMessage(); // 提示信息显示5秒 Form_messageSeconds = rf_get_seconds() + 5; // 加锁 xSemaphoreTake(Form_DataLock, portMAX_DELAY); formData.oper = DWIN_OPER_WRITE; formData.Addr = 0x5D80; formData.count = strlen(str); memmove(formData.str, str, formData.count); // 加入队列 LoopBuff_PutItem(&Form_DataM, (uint8_t *) &formData); if(color != last_color) { formData.oper = DWIN_OPER_WRITE; formData.Addr = 0xA273; formData.count = 2; formData.word[0] = htons(color); // 加入队列 LoopBuff_PutItem(&Form_DataM, (uint8_t *) &formData); // 保存当前提示信息的颜色 last_color = color; } // 解锁 xSemaphoreGive(Form_DataLock); // 发送消息给任务 xSemaphoreGive(Form_DataQ); } // 切换显示页面 void Form_SwitchPage(uint16_t pageNo) { // 加锁 xSemaphoreTake(Form_DataLock, portMAX_DELAY); formData.oper = DWIN_OPER_WRITE; // 加入队列 formData.Addr = 0x0084; formData.count = 4; formData.word[0] = htons(0x5A01); formData.word[1] = htons(pageNo); LoopBuff_PutItem(&Form_DataM, (uint8_t *) &formData); // 解锁 xSemaphoreGive(Form_DataLock); // 发送消息给任务 xSemaphoreGive(Form_DataQ); } // 清除表格内容 void Form_ClearGrid(form_grid_t *grid) { memset(grid->rowStr, 0, sizeof(grid->rowStr)); Form_RefreshGrid(grid); } // 刷新表格 void Form_RefreshGrid(form_grid_t *grid) { int16_t i, len; // 加锁 xSemaphoreTake(Form_DataLock, portMAX_DELAY); // 先将数据写入备份缓冲 for(i = 0; i < grid->rowCount; i++) { formData.oper = DWIN_OPER_WRITE; formData.Addr = grid->rowPtr[i] + (grid->bufIdx == 0 ? 0x40 : 0); strcpy(formData.str, grid->rowStr[i]); len = strlen(formData.str); memset(formData.str + len, ' ', sizeof(formData.str) - len); formData.count = sizeof(formData.str); // 加入队列 LoopBuff_PutItem(&Form_DataM, (uint8_t *) &formData); } // 再将备份缓冲作为显示缓冲 for(i = 0; i < 10; i++) { formData.oper = DWIN_OPER_WRITE; formData.Addr = grid->rowDesc[i]; formData.count = 2; formData.word[0] = htons(grid->rowPtr[i] + (grid->bufIdx == 0 ? 0x40 : 0)); // 加入队列 LoopBuff_PutItem(&Form_DataM, (uint8_t *) &formData); } // 将原显示缓冲作为备份缓冲 grid->bufIdx = 1 - grid->bufIdx; // 解锁 xSemaphoreGive(Form_DataLock); // 发送消息给任务 xSemaphoreGive(Form_DataQ); } // 刷新表格 void Form_RefreshGrid2(form_grid2_t *grid) { int16_t i, len; // 加锁 xSemaphoreTake(Form_DataLock, portMAX_DELAY); // 先将数据写入备份缓冲 for(i = 0; i < grid->rowCount; i++) { formData.oper = DWIN_OPER_WRITE; formData.Addr = grid->rowPtr[i] + (grid->bufIdx == 0 ? 0x40 : 0); strcpy(formData.str, grid->rowStr[i]); len = strlen(formData.str); memset(formData.str + len, ' ', sizeof(formData.str) - len); formData.count = sizeof(formData.str); // 加入队列 LoopBuff_PutItem(&Form_DataM, (uint8_t *) &formData); } // 再将备份缓冲作为显示缓冲 for(i = 0; i < 30; i++) { formData.oper = DWIN_OPER_WRITE; formData.Addr = grid->rowDesc[i]; formData.count = 2; formData.word[0] = htons(grid->rowPtr[i] + (grid->bufIdx == 0 ? 0x40 : 0)); // 加入队列 LoopBuff_PutItem(&Form_DataM, (uint8_t *) &formData); } // 将原显示缓冲作为备份缓冲 grid->bufIdx = 1 - grid->bufIdx; // 解锁 xSemaphoreGive(Form_DataLock); // 发送消息给任务 xSemaphoreGive(Form_DataQ); } // 滚动表格 void Form_ScrollGrid(form_grid_t *grid) { int16_t i, len; uint16_t tempPtr; // 加锁 xSemaphoreTake(Form_DataLock, portMAX_DELAY); tempPtr = grid->rowPtr[grid->rowCount - 1]; // 先将第2~10行往下移 for(i = grid->rowCount - 1; i > 0; i--) { formData.oper = DWIN_OPER_WRITE; formData.Addr = grid->rowDesc[i]; formData.count = 2; formData.word[0] = htons(grid->rowPtr[i - 1] + (grid->bufIdx == 1 ? 0x40 : 0)); // 加入队列 LoopBuff_PutItem(&Form_DataM, (uint8_t *) &formData); // 记录新的文本指针 grid->rowPtr[i] = grid->rowPtr[i - 1]; } // 写入第1行的内容 formData.oper = DWIN_OPER_WRITE; formData.Addr = tempPtr + (grid->bufIdx == 1 ? 0x40 : 0); strcpy(formData.str, grid->rowStr[0]); len = strlen(formData.str); memset(formData.str + len, ' ', sizeof(formData.str) - len); formData.count = sizeof(formData.str); // 加入队列 LoopBuff_PutItem(&Form_DataM, (uint8_t *) &formData); // 显示第1行内容 formData.oper = DWIN_OPER_WRITE; formData.Addr = grid->rowDesc[0]; formData.count = 2; formData.word[0] = htons(tempPtr + (grid->bufIdx == 1 ? 0x40 : 0)); // 加入队列 LoopBuff_PutItem(&Form_DataM, (uint8_t *) &formData); // 记录新的文本指针 grid->rowPtr[0] = tempPtr; // 解锁 xSemaphoreGive(Form_DataLock); // 发送消息给任务 xSemaphoreGive(Form_DataQ); } // 初始化 void Form_Open() { int16_t i; // 创建信号量 Form_DataQ = xSemaphoreCreateBinary(); Form_ReadQ = xSemaphoreCreateBinary(); Form_KeyQ = xSemaphoreCreateBinary(); // 创建互斥锁 Form_DataLock = xSemaphoreCreateMutex(); // 创建消息队列 LoopBuff_Create(&Form_DataM, sizeof(form_data_t), FORM_DATA_COUNT, 0, (uint32_t) Form_DataM_Data); LoopBuff_Create(&Form_ReadM, sizeof(form_data_t), FORM_READ_COUNT, 0, (uint32_t) Form_ReadM_Data); LoopBuff_Create(&Form_KeyM, sizeof(form_data_t), FORM_KEY_COUNT, 0, (uint32_t) Form_KeyM_Data); // 初始化表格 memset(&gridAll, 0, sizeof(gridAll)); memset(&gridWarn, 0, sizeof(gridWarn)); memset(&gridQuery, 0, sizeof(gridQuery)); memset(&gridAbout, 0, sizeof(gridAbout)); memset(&gridAboutEn, 0, sizeof(gridAboutEn)); gridAll.rowCount = 10; gridWarn.rowCount = 10; gridQuery.rowCount = 10; gridAbout.rowCount = 10; gridAboutEn.rowCount = 10; gridBox.rowCount=30; gridAll.hdrAddr = 0x5200; for(i = 0; i < gridAll.rowCount; i++) { gridAll.rowDesc[i] = 0xA0A0 + 0x10 * i; gridAll.rowPtr[i] = 0x5280 + 0x80 * i; } gridWarn.hdrAddr = 0x5780; for(i = 0; i < gridWarn.rowCount; i++) { gridWarn.rowDesc[i] = 0xA150 + 0x10 * i; gridWarn.rowPtr[i] = 0x5800 + 0x80 * i; } gridQuery.hdrAddr = 0x6000; for(i = 0; i < gridQuery.rowCount; i++) { gridQuery.rowDesc[i] = 0xA350 + 0x10 * i; gridQuery.rowPtr[i] = 0x6080 + 0x80 * i; } gridAbout.hdrAddr = 0x6980; for(i = 0; i < gridAbout.rowCount; i++) { gridAbout.rowDesc[i] = 0xA7F0 + 0x10 * i; gridAbout.rowPtr[i] = 0x6A00 + 0x80 * i; } gridAboutEn.hdrAddr = 0x7980; for(i = 0; i < gridAboutEn.rowCount; i++) { gridAboutEn.rowDesc[i] = 0xB7F0 + 0x10 * i; gridAboutEn.rowPtr[i] = 0x7A00 + 0x80 * i; } gridBox.hdrAddr=0x8000; for(i = 0; i < gridBox.rowCount; i++) { gridBox.rowDesc[i] = 0xC010 + 0x10 * i; gridBox.rowPtr[i] = 0x8080 + 0x80 * i; } // 启动串口 huart10.RxISR = DWIN_IRQHandler; SET_BIT(UART10->CR1, USART_CR1_PEIE | USART_CR1_RXNEIE); LL_USART_Enable(UART10); } // 导入首页和报警页最近数据 void Form_LoadRecent() { int32_t lastRec = -1; int16_t idx; uint8_t rowAll = 0, rowWarn = 0; S_RTC_TIME_DATA_T sRTC; char tggu[16], pct[8], mmWC[8], kg[8], press[8], tempr[8]; static ext_data_t Gprs; rf_app_data_t *pData = (rf_app_data_t *) Gprs.payload; // 查询所有储罐 if(LoopBuff_GetCount(&RF_DataM) > 0) { if(RF_DataM.info.wtPtr == 0) lastRec = RF_DataM.maxItemCount; else lastRec = RF_DataM.info.wtPtr - 1; } while(lastRec != -1 && (rowAll < gridAll.rowCount || rowWarn < gridWarn.rowCount)) { // 读取最后一条记录 SFlash_LoadInfo(LoopBuff_GetDataPos(&RF_DataM, lastRec), (uint8_t *) &Gprs, sizeof(ext_data_t)); // 前一条记录 if(lastRec == RF_DataM.info.rdPtr) lastRec = -1; else if(lastRec == 0) lastRec = RF_DataM.maxItemCount; else lastRec--; // 转换绝对时间 Wakeup_CalcUTCTime(Gprs.recvTime - pData->relative_time, &sRTC); // 查找储罐档案 idx = Ext_Lookup_Box_PSN(Gprs.oriPSN, boxCnt.count); if(idx >= 0) strcpy(tggu, boxPSN[idx].TGGU); else strcpy(tggu, ""); if(pData->Sensor.staDiff == RF_SENSOR_STATUS_NOCONNECT) { strcpy(mmWC, "---"); strcpy(kg, "---"); strcpy(pct, "---"); } else if(pData->Sensor.staDiff == RF_SENSOR_STATUS_UNDERFLOW) { strcpy(mmWC, "-EE"); strcpy(kg, "-EE"); strcpy(pct, "-EE"); } else if(pData->Sensor.staDiff == RF_SENSOR_STATUS_OVERFLOW) { strcpy(mmWC, "+EE"); strcpy(kg, "+EE"); strcpy(pct, "+EE"); } else { sprintf(mmWC, "%d", (uint32_t) KPa2mmH2O(pData->diff * 0.01)); sprintf(kg, "%d", (uint32_t) Vol2Quantity(Gprs.volume, pData->density * 0.001)); sprintf(pct, "%.1f", Gprs.volumePct * 0.01); } if(pData->Sensor.staPress == RF_SENSOR_STATUS_NOCONNECT) strcpy(press, "---"); else if(pData->Sensor.staPress == RF_SENSOR_STATUS_UNDERFLOW) strcpy(press, "-EE"); else if(pData->Sensor.staPress == RF_SENSOR_STATUS_OVERFLOW) strcpy(press, "+EE"); else sprintf(press, "%.2f", pData->press * 0.001); if(pData->Sensor.staETempr1 == RF_SENSOR_STATUS_NOCONNECT) strcpy(tempr, "---"); else if(pData->Sensor.staETempr1 == RF_SENSOR_STATUS_UNDERFLOW) strcpy(tempr, "-EE"); else if(pData->Sensor.staETempr1 == RF_SENSOR_STATUS_OVERFLOW) strcpy(tempr, "+EE"); else sprintf(tempr, "%d", pData->tempr); if(rowAll < gridAll.rowCount) { sprintf(gridAll.rowStr[rowAll++], " %02d-%02d %02d:%02d %11s %7s %7s %5s %7s %6s %2s %2s 20%02d%02d%02d%02d%03d", sRTC.u32Month, sRTC.u32Day, sRTC.u32Hour, sRTC.u32Minute, tggu, mmWC, kg, pct, press, tempr, (Gprs.warn ? "W" : ""), (Gprs.fault ? "F" : ""), Gprs.oriPSN[0], Gprs.oriPSN[1], Gprs.oriPSN[2], Gprs.oriPSN[3], (Gprs.oriPSN[4] << 8) | Gprs.oriPSN[5]); } if((Gprs.warn || Gprs.fault) && rowWarn < gridWarn.rowCount) { sprintf(gridWarn.rowStr[rowWarn++], " %02d-%02d %02d:%02d %11s %7s %7s %5s %7s %6s %2s %2s 20%02d%02d%02d%02d%03d", sRTC.u32Month, sRTC.u32Day, sRTC.u32Hour, sRTC.u32Minute, tggu, mmWC, kg, pct, press, tempr, (Gprs.warn ? "W" : ""), (Gprs.fault ? "F" : ""), Gprs.oriPSN[0], Gprs.oriPSN[1], Gprs.oriPSN[2], Gprs.oriPSN[3], (Gprs.oriPSN[4] << 8) | Gprs.oriPSN[5]); } } // 刷新表格 while(rowAll < gridAll.rowCount) strcpy(gridAll.rowStr[rowAll++], ""); Form_RefreshGrid(&gridAll); while(rowWarn < gridWarn.rowCount) strcpy(gridWarn.rowStr[rowWarn++], ""); Form_RefreshGrid(&gridWarn); } // 显示任务主体 void Form_Task(void *p_arg) { static form_data_t data; ext_bottle_t bottle; uint32_t seconds, seconds1, rtcSeconds = 0, statisSeconds = 0; uint8_t last_lora = 0, last_gps = 0, last_net = 0, last_rssi = 0; int16_t last_totalCount = 0, last_offlineCount = 0, last_faultCount = 0, last_warnCount = 0; int16_t i, idx, val, val1, val2, val3; uint32_t tick = 0; S_RTC_TIME_DATA_T sRTC; int32_t axisMax, axisMin, axisSeg = 10; // 屏幕复位 data.oper = DWIN_OPER_WRITE; data.Addr = 0x0004; data.count = 4; data.dword[0] = htonl(0x55AA5AA5); DWIN_Refresh(&data); // 延时200毫秒 osDelay(200); // 设置表头 data.oper = DWIN_OPER_WRITE; data.Addr = gridAll.hdrAddr; sprintf(data.str, " %5s %5s %11s %10s %8s %6s %9s %8s %4s %4s %13s", " 日期", " 时间", " 罐箱号 ", "液位(mmWC)", "质量(kg)", "百分比", "压力(MPa)", "温度(℃)", "报警", "故障", " PSN "); data.count = strlen(data.str); DWIN_Refresh(&data); // 设置表头 data.oper = DWIN_OPER_WRITE; data.Addr = gridAll.hdrAddr+0x2000; sprintf(data.str, " %5s %5s %11s %10s %8s %6s %9s %6s %4s %4s %13s", " data", " time", "Number_Box", "Level(mmWC)", "Qual(kg)", "Per(%)", "Pres(MPa)", "T(deg)", "Warn", "Err", " PSN "); data.count = strlen(data.str); DWIN_Refresh(&data); data.oper = DWIN_OPER_WRITE; data.Addr = gridWarn.hdrAddr; sprintf(data.str, " %5s %5s %11s %10s %8s %6s %9s %8s %4s %4s %13s", " 日期", " 时间", " 罐箱号 ", "液位(mmWC)", "质量(kg)", "百分比", "压力(MPa)", "温度(℃)", "报警", "故障", " PSN "); data.count = strlen(data.str); DWIN_Refresh(&data); data.oper = DWIN_OPER_WRITE; data.Addr = gridWarn.hdrAddr+0x2000; sprintf(data.str, " %5s %5s %11s %10s %8s %6s %9s %6s %4s %4s %13s", " data", " time", "Number_Box", "Level(mmWC)", "Qual(kg)", "Per(%)", "Pres(MPa)", "T(deg)", "Warn", "Err", " PSN "); data.count = strlen(data.str); DWIN_Refresh(&data); data.oper = DWIN_OPER_WRITE; data.Addr = gridBox.hdrAddr; sprintf(data.str, " %11s %13s %11s %13s %11s %13s ", "BOX ", "PSN "," BOX ", "PSN "," BOX ", "PSN "); data.count = strlen(data.str); DWIN_Refresh(&data); // 设置曲线的纵坐标 // 绿轴:液位(百分比) data.oper = DWIN_OPER_WRITE; data.Addr = 0x6580; if(dcBuff.configDisplay.ch_en) strcpy(data.str, " Level-%"); else strcpy(data.str, " 液位-%"); data.count = strlen(data.str); DWIN_Refresh(&data); axisMax = 100; axisMin = 0; for(i = 0; i <= axisSeg; i++) { data.oper = DWIN_OPER_WRITE; data.Addr = 0x65B0 + i * 0x10; sprintf(data.str, "%7d", axisMin + (axisMax - axisMin) / axisSeg * i); data.count = strlen(data.str); DWIN_Refresh(&data); } // 黄轴:压力(MPa) data.oper = DWIN_OPER_WRITE; data.Addr = 0x6590; if(dcBuff.configDisplay.ch_en) strcpy(data.str, "pressure-%"); else strcpy(data.str, "压力-MPa"); data.count = strlen(data.str); DWIN_Refresh(&data); axisMax = 5; axisMin = 0; for(i = 0; i <= axisSeg; i++) { data.oper = DWIN_OPER_WRITE; data.Addr = 0x6660 + i * 0x10; sprintf(data.str, "%7.2f", ((float) axisMin + (axisMax - axisMin)) / axisSeg * i); data.count = strlen(data.str); DWIN_Refresh(&data); } // 红轴:温度(℃) data.oper = DWIN_OPER_WRITE; data.Addr = 0x65A0; if(dcBuff.configDisplay.ch_en) strcpy(data.str, "Temperature-%"); else strcpy(data.str, "温度-℃"); data.count = strlen(data.str); DWIN_Refresh(&data); axisMax = 90; axisMin = -210; for(i = 0; i <= axisSeg; i++) { data.oper = DWIN_OPER_WRITE; data.Addr = 0x6710 + i * 0x10; sprintf(data.str, "%7d", axisMin + (axisMax - axisMin) / axisSeg * i); data.count = strlen(data.str); DWIN_Refresh(&data); } // 导入首页和报警页最近数据 Form_LoadRecent(); // 开机画面等待4秒 osDelay(3000); // 跳转到首页 if(dcBuff.configDisplay.ch_en) Form_SwitchPage(50); else Form_SwitchPage(0); while(1) { if(IsTickOut(tick)) { // 每半秒刷新一次状态 tick = GetDelayTick(500); // 清除提示信息 // 网络连接状态 val = Ethernet_connected; if(last_net != val) { data.oper = DWIN_OPER_WRITE; data.Addr = 0x5006; data.count = 2; data.word[0] = htons(val); DWIN_Refresh(&data); last_net = val; } // 4G信号强度 val = (dcBuff.dtuData.rssi + 12) / 25; if(last_rssi != val) { data.oper = DWIN_OPER_WRITE; data.Addr = 0x5008; data.count = 2; data.word[0] = htons(val); DWIN_Refresh(&data); last_rssi = val; } seconds = rf_get_seconds(); //apex // // LORA: 最新接收时间在3秒以内 // val = (RF_initStatus && RF_seconds > 0 && RF_seconds + 3 > seconds); // if(last_lora != val) // { // data.oper = DWIN_OPER_WRITE; // data.Addr = 0x5002; // data.count = 2; // data.word[0] = htons(val); // DWIN_Refresh(&data); // last_lora = val; // } // GPS标志: 最新定位时间在180秒以内 if(dcBuff.dtuData.posState) { seconds1 = Calc_SecondsFromYear(INITIAL_YEAR, dcBuff.dtuData.sysTime.year + 2000, dcBuff.dtuData.sysTime.month, dcBuff.dtuData.sysTime.day, dcBuff.dtuData.sysTime.hour, dcBuff.dtuData.sysTime.minute, dcBuff.dtuData.sysTime.second); } val = (RTC_offsetSeconds > 0 && dcBuff.dtuData.posState && seconds1 + 180 > RTC_offsetSeconds + seconds); if(last_gps != val) { data.oper = DWIN_OPER_WRITE; data.Addr = 0x5004; data.count = 2; data.word[0] = htons(val); DWIN_Refresh(&data); last_gps = val; } if(Form_messageSeconds > 0 && seconds >= Form_messageSeconds) { Form_messageSeconds = 0; Form_ClearMessage(); } // 每30秒统计一次设备数量 if(/*RTC_offsetSeconds > 0 &&*/ seconds >= statisSeconds) { statisSeconds = seconds + 30; // 离线总数 val1 = boxCnt.count; val2 = 0; val3 = 0; for(i = 0; i < boxCnt.count; i++) { idx = Ext_Lookup_Bottle_PSN(boxPSN[i].PSN, bottleCnt.count); if(idx >= 0) { FRAM_BufferRead(FRAM_BOTTLE_DATA_BASE + sizeof(ext_bottle_t) * bottlePSN[idx].recNo, (uint8_t *) &bottle, sizeof(ext_bottle_t)); if(bottle.recvTime + dcBuff.configBottle.offlineSeconds > RTC_offsetSeconds + seconds) { // 设备在线,离线数量-1 val1--; } // 故障和报警只统计在线设备 if(bottle.fault) val2++; if(bottle.warn) val3++; } } // 设备总数 val = boxCnt.count; if(last_totalCount != val) { data.oper = DWIN_OPER_WRITE; data.Addr = 0x500A; data.count = 2; data.word[0] = htons(val); DWIN_Refresh(&data); last_totalCount = val; } // 离线总数 val = val1; if(last_offlineCount != val) { data.oper = DWIN_OPER_WRITE; data.Addr = 0x500C; data.count = 2; data.word[0] = htons(val); DWIN_Refresh(&data); // 修改白色/红色 if((last_offlineCount > 0 && val == 0) || (last_offlineCount == 0 && val > 0)) { data.oper = DWIN_OPER_WRITE; data.Addr = 0xA053; data.count = 2; data.word[0] = htons(val == 0 ? DWIN_COLOR_WHITE : DWIN_COLOR_RED); DWIN_Refresh(&data); } last_offlineCount = val; } // 故障总数 val = val2; if(last_faultCount != val) { data.oper = DWIN_OPER_WRITE; data.Addr = 0x500E; data.count = 2; data.word[0] = htons(val); DWIN_Refresh(&data); // 修改白色/红色 if((last_faultCount > 0 && val == 0) || (last_faultCount == 0 && val > 0)) { data.oper = DWIN_OPER_WRITE; data.Addr = 0xA063; data.count = 2; data.word[0] = htons(val == 0 ? DWIN_COLOR_WHITE : DWIN_COLOR_RED); DWIN_Refresh(&data); } last_faultCount = val; } // 报警总数 val = val3; if(last_warnCount != val) { data.oper = DWIN_OPER_WRITE; data.Addr = 0x5010; data.count = 2; data.word[0] = htons(val); DWIN_Refresh(&data); // 修改白色/黄色 if((last_warnCount > 0 && val == 0) || (last_warnCount == 0 && val > 0)) { data.oper = DWIN_OPER_WRITE; data.Addr = 0xA073; data.count = 2; data.word[0] = htons(val == 0 ? DWIN_COLOR_WHITE : DWIN_COLOR_YELLOW); DWIN_Refresh(&data); } last_warnCount = val; } } // 每小时重设一次显示屏的RTC时钟 if(RTC_offsetSeconds > 0 && seconds >= rtcSeconds) { rtcSeconds = seconds + 3600; // 设置RTC时钟 Wakeup_CalcUTCTime(RTC_offsetSeconds + seconds, &sRTC); data.oper = DWIN_OPER_WRITE; data.Addr = 0x009C; data.count = 8; data.byte[0] = 0x5A; data.byte[1] = 0xA5; data.byte[2] = sRTC.u32Year - 2000; data.byte[3] = sRTC.u32Month; data.byte[4] = sRTC.u32Day; data.byte[5] = sRTC.u32Hour; data.byte[6] = sRTC.u32Minute; data.byte[7] = sRTC.u32Second; DWIN_Refresh(&data); } } // 处理其它显示任务 if(xSemaphoreTake(Form_DataQ, 500) != pdTRUE) continue; while(LoopBuff_GetCount(&Form_DataM) > 0) { memmove(&data, LoopBuff_GetDataPtr(&Form_DataM, Form_DataM.info.rdPtr), sizeof(form_data_t)); LoopBuff_RemoveItems(&Form_DataM, 1); DWIN_Refresh(&data); } } } // 从屏幕读取数据 uint8_t Form_ReadInt16(uint16_t addr, int16_t *val) { form_data_t resp; uint8_t count; uint16_t uval; uint32_t tick; // 先发送读取命令 // 加锁 xSemaphoreTake(Form_DataLock, portMAX_DELAY); formData.oper = DWIN_OPER_READ; formData.Addr = addr; formData.count = 2; // 加入队列 LoopBuff_PutItem(&Form_DataM, (uint8_t *) &formData); // 解锁 xSemaphoreGive(Form_DataLock); // 发送消息给任务 xSemaphoreGive(Form_DataQ); // 等待服务器返回:4秒 tick = GetDelayTick(4000); while(!IsTickOut(tick)) { if(xSemaphoreTake(Form_ReadQ, 500) != pdTRUE) continue; count = LoopBuff_GetCount(&Form_ReadM); while(count--) { memmove(&resp, LoopBuff_GetDataPtr(&Form_ReadM, Form_ReadM.info.rdPtr), sizeof(resp)); LoopBuff_RemoveItems(&Form_ReadM, 1); if(resp.Addr == addr && resp.count == 2) { uval = ntohs(resp.word[0]); memmove(val, &uval, 2); return 1; } } } return 0; } // 从屏幕读取数据 uint8_t Form_ReadUInt16(uint16_t addr, uint16_t *val) { form_data_t resp; uint8_t count; uint16_t uval; uint32_t tick; // 先发送读取命令 // 加锁 xSemaphoreTake(Form_DataLock, portMAX_DELAY); formData.oper = DWIN_OPER_READ; formData.Addr = addr; formData.count = 2; // 加入队列 LoopBuff_PutItem(&Form_DataM, (uint8_t *) &formData); // 解锁 xSemaphoreGive(Form_DataLock); // 发送消息给任务 xSemaphoreGive(Form_DataQ); // 等待服务器返回:4秒 tick = GetDelayTick(4000); while(!IsTickOut(tick)) { if(xSemaphoreTake(Form_ReadQ, 500) != pdTRUE) continue; count = LoopBuff_GetCount(&Form_ReadM); while(count--) { memmove(&resp, LoopBuff_GetDataPtr(&Form_ReadM, Form_ReadM.info.rdPtr), sizeof(resp)); LoopBuff_RemoveItems(&Form_ReadM, 1); if(resp.Addr == addr && resp.count == 2) { uval = ntohs(resp.word[0]); memmove(val, &uval, 2); return 1; } } } return 0; } // 从屏幕读取数据 uint8_t Form_ReadInt32(uint16_t addr, int32_t *val) { form_data_t resp; uint8_t count; uint32_t uval; uint32_t tick; // 先发送读取命令 // 加锁 xSemaphoreTake(Form_DataLock, portMAX_DELAY); formData.oper = DWIN_OPER_READ; formData.Addr = addr; formData.count = 4; // 加入队列 LoopBuff_PutItem(&Form_DataM, (uint8_t *) &formData); // 解锁 xSemaphoreGive(Form_DataLock); // 发送消息给任务 xSemaphoreGive(Form_DataQ); // 等待服务器返回:4秒 tick = GetDelayTick(4000); while(!IsTickOut(tick)) { if(xSemaphoreTake(Form_ReadQ, 500) != pdTRUE) continue; count = LoopBuff_GetCount(&Form_ReadM); while(count--) { memmove(&resp, LoopBuff_GetDataPtr(&Form_ReadM, Form_ReadM.info.rdPtr), sizeof(resp)); LoopBuff_RemoveItems(&Form_ReadM, 1); if(resp.Addr == addr && resp.count == 4) { uval = ntohl(resp.dword[0]); memmove(val, &uval, 4); return 1; } } } return 0; } // 从屏幕读取数据 uint8_t Form_ReadUInt32(uint16_t addr, uint32_t *val) { form_data_t resp; uint8_t count; uint32_t uval; uint32_t tick; // 先发送读取命令 // 加锁 xSemaphoreTake(Form_DataLock, portMAX_DELAY); formData.oper = DWIN_OPER_READ; formData.Addr = addr; formData.count = 4; // 加入队列 LoopBuff_PutItem(&Form_DataM, (uint8_t *) &formData); // 解锁 xSemaphoreGive(Form_DataLock); // 发送消息给任务 xSemaphoreGive(Form_DataQ); // 等待服务器返回:4秒 tick = GetDelayTick(4000); while(!IsTickOut(tick)) { if(xSemaphoreTake(Form_ReadQ, 500) != pdTRUE) continue; count = LoopBuff_GetCount(&Form_ReadM); while(count--) { memmove(&resp, LoopBuff_GetDataPtr(&Form_ReadM, Form_ReadM.info.rdPtr), sizeof(resp)); LoopBuff_RemoveItems(&Form_ReadM, 1); if(resp.Addr == addr && resp.count == 4) { uval = ntohl(resp.dword[0]); memmove(val, &uval, 4); return 1; } } } return 0; } // 从屏幕读取数据 uint8_t Form_ReadStr(uint16_t addr, char *val, uint8_t size) { form_data_t resp; uint8_t count, i = 0; uint32_t tick; // 先发送读取命令 // 加锁 xSemaphoreTake(Form_DataLock, portMAX_DELAY); formData.oper = DWIN_OPER_READ; formData.Addr = addr; formData.count = size; // 加入队列 LoopBuff_PutItem(&Form_DataM, (uint8_t *) &formData); // 解锁 xSemaphoreGive(Form_DataLock); // 发送消息给任务 xSemaphoreGive(Form_DataQ); // 等待服务器返回:4秒 tick = GetDelayTick(4000); while(!IsTickOut(tick)) { if(xSemaphoreTake(Form_ReadQ, 500) != pdTRUE) continue; count = LoopBuff_GetCount(&Form_ReadM); while(count--) { memmove(&resp, LoopBuff_GetDataPtr(&Form_ReadM, Form_ReadM.info.rdPtr), sizeof(resp)); LoopBuff_RemoveItems(&Form_ReadM, 1); if(resp.Addr == addr) { while(i < resp.count && resp.byte[i] != 0xFF && resp.byte[i] != 0) i++; memset(val, 0, size); if(i >= size) memmove(val, resp.byte, size - 1); else memmove(val, resp.byte, i); return 1; } } } return 0; } // 恢复参数 void Form_RestoreParam() { // 加锁 xSemaphoreTake(Form_DataLock, portMAX_DELAY); formData.oper = DWIN_OPER_WRITE; // 加入队列 formData.Addr = 0x5014; formData.count = 2; formData.word[0] = htons(dcBuff.configBottle.emptyPct / 100); LoopBuff_PutItem(&Form_DataM, (uint8_t *) &formData); formData.Addr = 0x5016; formData.count = 2; formData.word[0] = htons(dcBuff.configBottle.fullPct / 100); LoopBuff_PutItem(&Form_DataM, (uint8_t *) &formData); formData.Addr = 0x5018; formData.count = 4; formData.dword[0] = htonl(dcBuff.configBottle.warnPress / 10); LoopBuff_PutItem(&Form_DataM, (uint8_t *) &formData); formData.Addr = 0x501A; formData.count = 4; formData.dword[0] = htonl(dcBuff.configBottle.warnPressH / 10); LoopBuff_PutItem(&Form_DataM, (uint8_t *) &formData); formData.Addr = 0x501C; formData.count = 4; formData.dword[0] = htonl(dcBuff.configBottle.warnTempr); LoopBuff_PutItem(&Form_DataM, (uint8_t *) &formData); formData.Addr = 0x501E; formData.count = 4; formData.dword[0] = htonl(dcBuff.configBottle.warnTemprH); LoopBuff_PutItem(&Form_DataM, (uint8_t *) &formData); formData.Addr = 0x5020; formData.count = 4; formData.dword[0] = htonl(dcBuff.configBottle.offlineSeconds); LoopBuff_PutItem(&Form_DataM, (uint8_t *) &formData); // 解锁 xSemaphoreGive(Form_DataLock); // 发送消息给任务 xSemaphoreGive(Form_DataQ); } // 保存参数 uint8_t Form_SaveParam() { uint16_t emptyPct, fullPct; uint32_t warnPress, warnPressH, offlineSeconds; int32_t warnTempr, warnTemprH; uint8_t save = 0; if(!Form_ReadUInt16(0x5014, &emptyPct)) return 0; if(!Form_ReadUInt16(0x5016, &fullPct)) return 0; if(!Form_ReadUInt32(0x5018, &warnPress)) return 0; if(!Form_ReadUInt32(0x501A, &warnPressH)) return 0; if(!Form_ReadInt32(0x501C, &warnTempr)) return 0; if(!Form_ReadInt32(0x501E, &warnTemprH)) return 0; if(!Form_ReadUInt32(0x5020, &offlineSeconds)) return 0; if(emptyPct * 100 != dcBuff.configBottle.emptyPct) { dcBuff.configBottle.emptyPct = emptyPct * 100; save = 1; } if(fullPct * 100 != dcBuff.configBottle.fullPct) { dcBuff.configBottle.fullPct = fullPct * 100; save = 1; } if(warnPress * 10 != dcBuff.configBottle.warnPress) { dcBuff.configBottle.warnPress = warnPress * 10; save = 1; } if(warnPressH * 10 != dcBuff.configBottle.warnPressH) { dcBuff.configBottle.warnPressH = warnPressH * 10; save = 1; } if(warnTempr != dcBuff.configBottle.warnTempr) { dcBuff.configBottle.warnTempr = warnTempr; save = 1; } if(warnTemprH != dcBuff.configBottle.warnTemprH) { dcBuff.configBottle.warnTemprH = warnTemprH; save = 1; } if(offlineSeconds != dcBuff.configBottle.offlineSeconds) { dcBuff.configBottle.offlineSeconds = offlineSeconds; save = 1; } if(save) Config_SaveConfig(); return 1; } // 修改PSN uint8_t Form_ModifyPSN(form_data_t *key, char *msg) { uint8_t PSN[6]; char str[26]; uint8_t len, i = 0; u16 serial = 0; char errMsg[20] = "PSN输入有误!"; char errMsgEn[20] = "PSN incorrect"; if(dcBuff.configDisplay.ch_en) { strcpy(errMsg, errMsgEn); } // 读取PSN while(i < key->count && key->byte[i] != 0xFF && key->byte[i] != 0) i++; memset(str, 0, sizeof(str)); if(i >= sizeof(str)) memmove(str, key->byte, sizeof(str) - 1); else memmove(str, key->byte, i); len = strlen(str); if(len != 13) { strcpy(msg, errMsg); return 0; } if(str[0] != '2' || str[1] != '0') { strcpy(msg, errMsg); return 0; } for(i = 0; i < len; i++) { if(!isdigit(str[i])) { strcpy(msg, errMsg); return 0; } } \ serial = atoi(str + 10); PSN[5] = serial & 0xFF; PSN[4] = serial >> 8; str[10] = 0; PSN[3] = atoi(str + 8); str[8] = 0; PSN[2] = atoi(str + 6); str[6] = 0; PSN[1] = atoi(str + 4); str[4] = 0; PSN[0] = atoi(str + 2); if(memcmp(dcBuff.configBottle.PSN, PSN, 6) != 0) { memmove(dcBuff.configBottle.PSN, PSN, 6); Config_SaveConfig(); } return 1; } // 读取查询条件 uint8_t Form_GetQuery(uint16_t func, char *msg) { char str[26]; uint8_t len, i; u16 serial = 0, y = 2000, m = 1, d = 1; char errMsg[5][20] = { "通信故障!", "罐箱号输入有误!", "PSN输入有误!", "起始日期输入有误!", "查询天数输入有误!" }; char errMsgEn[5][20] = { "Commu failure!", "Box number err", "The PSN err", "startdate err.", " days err" }; if(dcBuff.configDisplay.ch_en) { for (i = 0; i < 5; ++i) { strcpy(errMsg[i], errMsgEn[i]); } } // 读取罐箱号 if(!Form_ReadStr(0x5E00, str, sizeof(str))) { strcpy(msg, errMsg[0]); return 0; } len = strlen(str); if(len != 0 && len != 11) { strcpy(msg, errMsg[1]); return 0; } // 转换成大写 for(i = 0; i < len; i++) { if(str[i] >= 'a' && str[i] <= 'z') str[i] -= 32; } strcpy(formQuery.TGGU, str); formQuery.tgguFlag = (len > 0); // 读取PSN if(!Form_ReadStr(0x5E80, str, sizeof(str))) { strcpy(msg, errMsg[0]); return 0; } len = strlen(str); if(len != 0 && len != 13) { strcpy(msg, errMsg[2]); return 0; } if(len > 0 && (str[0] != '2' || str[1] != '0')) { strcpy(msg, errMsg[2]); return 0; } for(i = 0; i < len; i++) { if(!isdigit(str[i])) { strcpy(msg, errMsg[2]); return 0; } } if(len > 0) { serial = atoi(str + 10); formQuery.PSN[5] = serial & 0xFF; formQuery.PSN[4] = serial >> 8; str[10] = 0; formQuery.PSN[3] = atoi(str + 8); str[8] = 0; formQuery.PSN[2] = atoi(str + 6); str[6] = 0; formQuery.PSN[1] = atoi(str + 4); str[4] = 0; formQuery.PSN[0] = atoi(str + 2); } formQuery.psnFlag = (len > 0); // 读取起始日期 if(func == 2 || func == 3) { if(!Form_ReadStr(0x5F00, str, sizeof(str))) { strcpy(msg, errMsg[0]); return 0; } len = strlen(str); if(len != 0 && len != 8) { strcpy(msg, errMsg[3]); return 0; } if(len > 0) { for(i = 0; i < len; i++) { if(!isdigit(str[i])) { strcpy(msg, errMsg[3]); return 0; } } d = atoi(str + 6); str[6] = 0; m = atoi(str + 4); str[4] = 0; y = atoi(str); if( y < 2000 || y > 2099 || m < 1 || m > 12 || d < 1 || d > get_month_days(y, m)) { strcpy(msg, errMsg[3]); return 0; } formQuery.date = y * 10000 + m * 100 + d; } formQuery.dateFlag = (len > 0); } // 读取查询天数 if(func == 3) { if(!Form_ReadStr(0x5F80, str, sizeof(str))) { strcpy(msg, errMsg[0]); return 0; } len = strlen(str); if(len == 0) formQuery.days = 1; else { for(i = 0; i < len; i++) { if(!isdigit(str[i])) { strcpy(msg, errMsg[4]); return 0; } } formQuery.days = atoi(str); if(formQuery.days < 1 || formQuery.days > 12) { strcpy(msg, errMsg[4]); return 0; } } } if(func == 1 || func == 2) { // 读取正常选项 if(!Form_ReadInt16(0x5024, &formQuery.normal)) { strcpy(msg, errMsg[0]); return 0; } // 读取故障选项 if(!Form_ReadInt16(0x5026, &formQuery.fault)) { strcpy(msg, errMsg[0]); return 0; } // 读取报警选项 if(!Form_ReadInt16(0x5028, &formQuery.warn)) { strcpy(msg, errMsg[0]); return 0; } } if(func == 1) { // 读取离线选项 if(!Form_ReadInt16(0x502A, &formQuery.offline)) { strcpy(msg, errMsg[0]); return 0; } } return 1; } // 设置查询表头 uint8_t Form_PreQuery() { int16_t idx, len; // 储罐要判断是否离线 if(formQuery.func == 1 && RTC_offsetSeconds == 0) { if(dcBuff.configDisplay.ch_en) Form_DispMessage("The time not obtained!", DWIN_COLOR_RED); else Form_DispMessage("尚未获取基站时间!", DWIN_COLOR_RED); return 0; } // 曲线只能查询唯一PSN的数据 if(formQuery.func == 3 && !formQuery.tgguFlag && !formQuery.psnFlag) { if(dcBuff.configDisplay.ch_en) Form_DispMessage("Enter the Box number or PSN", DWIN_COLOR_RED); else Form_DispMessage("请输入罐箱号或PSN!", DWIN_COLOR_RED); return 0; } // 如果输入了罐箱号或PSN,只能查询一个罐子的数据,罐箱号或PSN不能冲突 if(formQuery.tgguFlag) { // 查找储罐扩展档案 idx = Ext_Lookup_Box_TGGU(formQuery.TGGU, boxCnt.count); if(idx == -1) { if(dcBuff.configDisplay.ch_en) Form_DispMessage("There is no box number", DWIN_COLOR_RED); else Form_DispMessage("无此罐箱号!", DWIN_COLOR_RED); return 0; } if(formQuery.psnFlag && memcmp(formQuery.PSN, boxTGGU[idx].PSN, 6) != 0) { if(dcBuff.configDisplay.ch_en) Form_DispMessage("Box number conflicts with PSN", DWIN_COLOR_RED); else Form_DispMessage("罐箱号和PSN冲突!", DWIN_COLOR_RED); return 0; } // 记录PSN,用于查询显示 memmove(formQuery.PSN, boxTGGU[idx].PSN, 6); } else if(formQuery.psnFlag) { // 查找储罐扩展档案 idx = Ext_Lookup_Box_PSN(formQuery.PSN, boxCnt.count); if(idx >= 0) { // 记录TGGU,用于显示 strcpy(formQuery.TGGU, boxPSN[idx].TGGU); } } // 加锁 xSemaphoreTake(Form_DataLock, portMAX_DELAY); if(formQuery.func == 1 || formQuery.func == 2) { // 加入队列 formData.oper = DWIN_OPER_WRITE; formData.Addr = gridQuery.hdrAddr; if(formQuery.func == 1) { if(dcBuff.configDisplay.ch_en) sprintf(formData.str, " %4s %11s %6s %9s %8s %4s %4s %4s %13s %5s %5s %7s", "Num", " Box_number ", "Percentage", "Press(MPa)", "Temp(℃)", "Alarm", "Err", "Offline", " PSN ", "Date", "Time", "Vol(v)"); else sprintf(formData.str, " %4s %11s %6s %9s %8s %4s %4s %4s %13s %5s %5s %7s", "序号", " 罐箱号 ", "百分比", "压力(MPa)", "温度(℃)", "报警", "故障", "离线", " PSN ", "日期", "时间", "电压(v)"); } else if(formQuery.func == 2) { if(dcBuff.configDisplay.ch_en) sprintf(formData.str, " %5s %5s %11s %10s %8s %6s %9s %8s %4s %4s %13s", "Data", "Time", " Box_number ", "Level(mmWC)", "m(kg)", "Percent", "Press(MPa)", "Temp(℃)", "Alarm", "Err", " PSN "); else sprintf(formData.str, " %5s %5s %11s %10s %8s %6s %9s %8s %4s %4s %13s", " 日期", " 时间", " 罐箱号 ", "液位(mmWC)", "质量(kg)", "百分比", "压力(MPa)", "温度(℃)", "报警", "故障", " PSN "); } len = strlen(formData.str); memset(formData.str + len, ' ', sizeof(formData.str) - len); formData.count = sizeof(formData.str); LoopBuff_PutItem(&Form_DataM, (uint8_t *) &formData); } else if(formQuery.func == 3) { // 显示标题 formData.oper = DWIN_OPER_WRITE; formData.Addr = 0x6960; sprintf(formData.str, "%s / 20%02d%02d%02d%02d%03d", formQuery.TGGU, formQuery.PSN[0], formQuery.PSN[1], formQuery.PSN[2], formQuery.PSN[3], (formQuery.PSN[4] << 8) | formQuery.PSN[5]); formData.count = strlen(formData.str); LoopBuff_PutItem(&Form_DataM, (uint8_t *) &formData); } // 解锁 xSemaphoreGive(Form_DataLock); // 发送消息给任务 xSemaphoreGive(Form_DataQ); // 切换页面 Form_ClearGrid(&gridQuery); Form_SwitchPage(17 + (formQuery.func - 1)); // 用于翻页的序号 gridQuery.topPtr = -1; return 1; } // 查询储罐 void Form_QueryBox(int32_t lastRec) { int16_t idx; int32_t i, topPtr; ext_box_t boxRec; ext_bottle_t bottleRec; uint32_t seconds; uint8_t offline, included, row = 0; S_RTC_TIME_DATA_T sRTC; char pct[8], press[8], tempr[8], date[6], time[6], voltage[8]; static int16_t dispNo = 1; static ext_data_t Gprs; rf_app_data_t *pData = (rf_app_data_t *) Gprs.payload; // 初始化记录序号 if(lastRec == -1) dispNo = 1; // 获取实时时钟 seconds = rf_get_seconds(); // 查询记录:按罐箱号排序 for(i = lastRec + 1; i < boxCnt.count && row < gridQuery.rowCount; i++) { FRAM_BufferRead(FRAM_BOX_DATA_BASE + sizeof(ext_box_t) * boxTGGU[i].recNo, (uint8_t *) &boxRec, sizeof(ext_box_t)); // 记录用于翻页 topPtr = i; idx = Ext_Lookup_Bottle_PSN(boxRec.PSN, bottleCnt.count); if(idx >= 0) { // 判断是否离线 FRAM_BufferRead(FRAM_BOTTLE_DATA_BASE + sizeof(ext_bottle_t) * bottlePSN[idx].recNo, (uint8_t *) &bottleRec, sizeof(ext_bottle_t)); offline = (bottleRec.recvTime + dcBuff.configBottle.offlineSeconds <= RTC_offsetSeconds + seconds); } // 判断筛选条件 included = 0; // 如果输入了罐箱号或PSN, 则忽略储罐状态 if(formQuery.psnFlag || formQuery.tgguFlag) included = 1; // 复选框为或的逻辑关系 if(formQuery.offline && (idx < 0 || offline)) included = 1; else if(formQuery.normal && (idx >= 0 && !bottleRec.warn && !bottleRec.fault && !offline)) included = 1; else if(formQuery.fault && (idx >= 0 && bottleRec.fault)) included = 1; else if(formQuery.warn && (idx >= 0 && bottleRec.warn)) included = 1; // 如果输入了罐箱号或PSN if(formQuery.psnFlag && memcmp(boxRec.PSN, formQuery.PSN, 6) != 0) included = 0; else if(formQuery.tgguFlag && strcmp(boxRec.TGGU, formQuery.TGGU) != 0) included = 0; if(!included) continue; strcpy(pct, ""); strcpy(press, ""); strcpy(tempr, ""); strcpy(date, ""); strcpy(time, ""); strcpy(voltage, ""); if(idx >= 0 && bottleRec.lastData >= 0) { // 读取最后一条记录 SFlash_LoadInfo(LoopBuff_GetDataPos(&RF_DataM, bottleRec.lastData), (uint8_t *) &Gprs, sizeof(ext_data_t)); if(pData->Sensor.staDiff == RF_SENSOR_STATUS_NOCONNECT) strcpy(pct, "---"); else if(pData->Sensor.staDiff == RF_SENSOR_STATUS_UNDERFLOW) strcpy(pct, "-EE"); else if(pData->Sensor.staDiff == RF_SENSOR_STATUS_OVERFLOW) strcpy(pct, "+EE"); else sprintf(pct, "%.1f", Gprs.volumePct * 0.01); if(pData->Sensor.staPress == RF_SENSOR_STATUS_NOCONNECT) strcpy(press, "---"); else if(pData->Sensor.staPress == RF_SENSOR_STATUS_UNDERFLOW) strcpy(press, "-EE"); else if(pData->Sensor.staPress == RF_SENSOR_STATUS_OVERFLOW) strcpy(press, "+EE"); else sprintf(press, "%.2f", pData->press * 0.001); if(pData->Sensor.staETempr1 == RF_SENSOR_STATUS_NOCONNECT) strcpy(tempr, "---"); else if(pData->Sensor.staETempr1 == RF_SENSOR_STATUS_UNDERFLOW) strcpy(tempr, "-EE"); else if(pData->Sensor.staETempr1 == RF_SENSOR_STATUS_OVERFLOW) strcpy(tempr, "+EE"); else sprintf(tempr, "%d", pData->tempr); Wakeup_CalcUTCTime(Gprs.recvTime - pData->relative_time, &sRTC); sprintf(date, "%02d-%02d", sRTC.u32Month, sRTC.u32Day); sprintf(time, "%02d:%02d", sRTC.u32Hour, sRTC.u32Minute); sprintf(voltage, "%.2f", pData->voltage * 0.01); } sprintf(gridQuery.rowStr[row++], " %3d %11s %5s %7s %6s %2s %2s %2s 20%02d%02d%02d%02d%03d %5s %5s %5s ", dispNo++, boxRec.TGGU, pct, press, tempr, ((idx >= 0 && bottleRec.warn) ? "W" : ""), ((idx >= 0 && bottleRec.fault) ? "F" : ""), ((idx < 0 || offline) ? "L" : ""), boxRec.PSN[0], boxRec.PSN[1], boxRec.PSN[2], boxRec.PSN[3], (boxRec.PSN[4] << 8) | boxRec.PSN[5], date, time, voltage); } if(row < gridQuery.rowCount) { if(dcBuff.configDisplay.ch_en) Form_DispMessage("There are no more records.", DWIN_COLOR_RED); else Form_DispMessage("没有更多记录!", DWIN_COLOR_GREEN); } else { Form_ClearMessage(); // 满页才更新起始序号 gridQuery.topPtr = topPtr; } if(row > 0) { // 清除未满的记录 while(row < gridQuery.rowCount) strcpy(gridQuery.rowStr[row++], ""); // 刷新表格 Form_RefreshGrid(&gridQuery); } } // 查询数据 void Form_QueryData(int32_t lastRec) { int16_t idx; int32_t topPtr; ext_bottle_t bottleRec; uint8_t included, row = 0; S_RTC_TIME_DATA_T sRTC; char tggu[16], pct[8], mmWC[8], kg[8], press[8], tempr[8]; uint32_t minTime = 0xFFFFFFFF; static ext_data_t Gprs; rf_app_data_t *pData = (rf_app_data_t *) Gprs.payload; if(lastRec == -1) // 首页 { // 查询单个储罐 if(formQuery.tgguFlag || formQuery.psnFlag) { // 查找储罐档案 idx = Ext_Lookup_Bottle_PSN(formQuery.PSN, bottleCnt.count); if(idx >= 0) FRAM_BufferRead(FRAM_BOTTLE_DATA_BASE + sizeof(ext_bottle_t) * bottlePSN[idx].recNo, (uint8_t *) &bottleRec, sizeof(ext_bottle_t)); if(idx < 0 || bottleRec.lastData < 0) { if(dcBuff.configDisplay.ch_en) Form_DispMessage("There is no data for PSN", DWIN_COLOR_RED); else Form_DispMessage("无此PSN的数据!", DWIN_COLOR_RED); return; } lastRec = bottleRec.lastData; } else // 查询所有储罐 { if(LoopBuff_GetCount(&RF_DataM) > 0) { if(RF_DataM.info.wtPtr == 0) lastRec = RF_DataM.maxItemCount; else lastRec = RF_DataM.info.wtPtr - 1; } } } else // 翻页 { // 查询单个储罐 if(formQuery.tgguFlag || formQuery.psnFlag) { // 读取上一条记录 SFlash_LoadInfo(LoopBuff_GetDataPos(&RF_DataM, lastRec), (uint8_t *) &Gprs, sizeof(ext_data_t)); minTime = Gprs.recvTime - pData->relative_time; if(lastRec == RF_DataM.info.rdPtr) lastRec = -1; else lastRec = Gprs.prevData; } else // 查询所有储罐 { if(lastRec == RF_DataM.info.rdPtr) lastRec = -1; else if(lastRec == 0) lastRec = RF_DataM.maxItemCount; else lastRec--; } } while(lastRec != -1 && row < gridQuery.rowCount) { // 读取最后一条记录 SFlash_LoadInfo(LoopBuff_GetDataPos(&RF_DataM, lastRec), (uint8_t *) &Gprs, sizeof(ext_data_t)); // 记录用于翻页 topPtr = lastRec; // 前一条记录 if(formQuery.tgguFlag || formQuery.psnFlag) // 查询单个储罐 { // 记录已被覆盖 if(memcmp(Gprs.oriPSN, formQuery.PSN, 6) != 0 || Gprs.recvTime - pData->relative_time > minTime) break; minTime = Gprs.recvTime - pData->relative_time; if(lastRec == RF_DataM.info.rdPtr) lastRec = -1; else lastRec = Gprs.prevData; } else // 查询所有储罐 { if(lastRec == RF_DataM.info.rdPtr) lastRec = -1; else if(lastRec == 0) lastRec = RF_DataM.maxItemCount; else lastRec--; } // 判断日期 Wakeup_CalcUTCTime(Gprs.recvTime - pData->relative_time, &sRTC); if(formQuery.dateFlag && sRTC.u32Year * 10000 + sRTC.u32Month * 100 + sRTC.u32Day > formQuery.date) continue; // 判断筛选条件 included = 0; if(formQuery.normal && (!Gprs.warn && !Gprs.fault)) included = 1; else if(formQuery.fault && Gprs.fault) included = 1; else if(formQuery.warn && Gprs.warn) included = 1; if(!included) continue; if(formQuery.tgguFlag || formQuery.psnFlag) strcpy(tggu, formQuery.TGGU); else { // 查找储罐档案 idx = Ext_Lookup_Box_PSN(Gprs.oriPSN, boxCnt.count); if(idx >= 0) strcpy(tggu, boxPSN[idx].TGGU); else strcpy(tggu, ""); } if(pData->Sensor.staDiff == RF_SENSOR_STATUS_NOCONNECT) { strcpy(mmWC, "---"); strcpy(kg, "---"); strcpy(pct, "---"); } else if(pData->Sensor.staDiff == RF_SENSOR_STATUS_UNDERFLOW) { strcpy(mmWC, "-EE"); strcpy(kg, "-EE"); strcpy(pct, "-EE"); } else if(pData->Sensor.staDiff == RF_SENSOR_STATUS_OVERFLOW) { strcpy(mmWC, "+EE"); strcpy(kg, "+EE"); strcpy(pct, "+EE"); } else { sprintf(mmWC, "%d", (uint32_t) KPa2mmH2O(pData->diff * 0.01)); sprintf(kg, "%d", (uint32_t) Vol2Quantity(Gprs.volume, pData->density * 0.001)); sprintf(pct, "%.1f", Gprs.volumePct * 0.01); } if(pData->Sensor.staPress == RF_SENSOR_STATUS_NOCONNECT) strcpy(press, "---"); else if(pData->Sensor.staPress == RF_SENSOR_STATUS_UNDERFLOW) strcpy(press, "-EE"); else if(pData->Sensor.staPress == RF_SENSOR_STATUS_OVERFLOW) strcpy(press, "+EE"); else sprintf(press, "%.2f", pData->press * 0.001); if(pData->Sensor.staETempr1 == RF_SENSOR_STATUS_NOCONNECT) strcpy(tempr, "---"); else if(pData->Sensor.staETempr1 == RF_SENSOR_STATUS_UNDERFLOW) strcpy(tempr, "-EE"); else if(pData->Sensor.staETempr1 == RF_SENSOR_STATUS_OVERFLOW) strcpy(tempr, "+EE"); else sprintf(tempr, "%d", pData->tempr); sprintf(gridQuery.rowStr[row++], " %02d-%02d %02d:%02d %11s %7s %7s %5s %7s %6s %2s %2s 20%02d%02d%02d%02d%03d", sRTC.u32Month, sRTC.u32Day, sRTC.u32Hour, sRTC.u32Minute, tggu, mmWC, kg, pct, press, tempr, (Gprs.warn ? "W" : ""), (Gprs.fault ? "F" : ""), Gprs.oriPSN[0], Gprs.oriPSN[1], Gprs.oriPSN[2], Gprs.oriPSN[3], (Gprs.oriPSN[4] << 8) | Gprs.oriPSN[5]); } if(row < gridQuery.rowCount) { if(dcBuff.configDisplay.ch_en) Form_DispMessage("There are no more records.", DWIN_COLOR_GREEN); else Form_DispMessage("没有更多记录!", DWIN_COLOR_GREEN); } else { Form_ClearMessage(); // 满页才更新起始序号 gridQuery.topPtr = topPtr; } if(row > 0) { // 清除未满的记录 while(row < gridQuery.rowCount) strcpy(gridQuery.rowStr[row++], ""); // 刷新表格 Form_RefreshGrid(&gridQuery); } } // 清除一条曲线的作图区域 void Form_ClearCurve(uint16_t curveAddr) { // 加锁 xSemaphoreTake(Form_DataLock, portMAX_DELAY); // 清除曲线: 在区域以外打一个点 formData.oper = DWIN_OPER_WRITE; formData.Addr = curveAddr; formData.count = 10; formData.word[0] = htons(0x0001); formData.word[1] = htons(1); formData.word[2] = htons(0xFFFF); formData.word[3] = htons(0xFFFF); formData.word[4] = htons(0); // 加入队列 LoopBuff_PutItem(&Form_DataM, (uint8_t *) &formData); // 解锁 xSemaphoreGive(Form_DataLock); // 发送消息给任务 xSemaphoreGive(Form_DataQ); } // 清除全部作图区域 void Form_ClearCurves() { uint16_t levelAddr = 0x2800, pressAddr = 0x3555, temprAddr = 0x42AA; Form_ClearCurve(levelAddr); Form_ClearCurve(pressAddr); Form_ClearCurve(temprAddr); } // 查询曲线 void Form_QueryCurve(int32_t lastRec) { #if 1 int16_t idx, i; ext_bottle_t bottleRec; uint16_t levelRow, pressRow, temprRow; uint16_t levelCnt = 0, pressCnt = 0, temprCnt = 0, done = 0; int32_t topPtr; S_RTC_TIME_DATA_T sRTC; static uint16_t levelBuff[40], pressBuff[40], temprBuff[40]; static ext_data_t Gprs; rf_app_data_t *pData = (rf_app_data_t *) Gprs.payload; uint32_t axisMin, axisMax, axisRange, axisTime, axisSeg = 12; const float x0 = 282, w = 930, y0 = 579, h = -421; const float levelMin = 0, levelRange = 10000, pressMin = 0, pressRange = 5000, temprMin = -210, temprRange = 300; uint16_t levelAddr = 0x2800, pressAddr = 0x3555, temprAddr = 0x42AA; uint16_t levelColor = DWIN_COLOR_GREEN, pressColor = DWIN_COLOR_YELLOW, temprColor = DWIN_COLOR_RED; uint16_t x, y; uint32_t minTime = 0xFFFFFFFF; // 计算日期范围 axisRange = formQuery.days * 86400; if(lastRec == -1) // 首页 { // 查找储罐档案 idx = Ext_Lookup_Bottle_PSN(formQuery.PSN, bottleCnt.count); if(idx >= 0) FRAM_BufferRead(FRAM_BOTTLE_DATA_BASE + sizeof(ext_bottle_t) * bottlePSN[idx].recNo, (uint8_t *) &bottleRec, sizeof(ext_bottle_t)); if(idx < 0 || bottleRec.lastData < 0) { Form_ClearCurves(); if(dcBuff.configDisplay.ch_en) Form_DispMessage("There is no data for PSN", DWIN_COLOR_RED); else Form_DispMessage("无此PSN的数据!", DWIN_COLOR_RED); return; } if(!formQuery.dateFlag) { bottleRec.recvTime -= bottleRec.recvTime % 86400; bottleRec.recvTime += 86400; bottleRec.recvTime -= 86400 * formQuery.days; Wakeup_CalcUTCTime(bottleRec.recvTime, &sRTC); formQuery.date = sRTC.u32Year * 10000 + sRTC.u32Month * 100 + sRTC.u32Day; } lastRec = bottleRec.lastData; // 设置时间轴范围 sRTC.u32Year = formQuery.date / 10000; sRTC.u32Month = (formQuery.date % 10000) / 100; sRTC.u32Day = formQuery.date % 100; sRTC.u32Hour = 0; sRTC.u32Minute = 0; sRTC.u32Second = 0; axisMin = Calc_SecondsFromYear(INITIAL_YEAR, sRTC.u32Year, sRTC.u32Month, sRTC.u32Day, sRTC.u32Hour, sRTC.u32Minute, sRTC.u32Second); axisMax = axisMin + axisRange; } else // 翻页 { // 读取上一条记录 SFlash_LoadInfo(LoopBuff_GetDataPos(&RF_DataM, lastRec), (uint8_t *) &Gprs, sizeof(ext_data_t)); minTime = Gprs.recvTime - pData->relative_time; if(lastRec == RF_DataM.info.rdPtr) lastRec = -1; else lastRec = Gprs.prevData; // 设置时间轴范围 sRTC.u32Year = formQuery.date / 10000; sRTC.u32Month = (formQuery.date % 10000) / 100; sRTC.u32Day = formQuery.date % 100; sRTC.u32Hour = 0; sRTC.u32Minute = 0; sRTC.u32Second = 0; axisMax = Calc_SecondsFromYear(INITIAL_YEAR, sRTC.u32Year, sRTC.u32Month, sRTC.u32Day, sRTC.u32Hour, sRTC.u32Minute, sRTC.u32Second); axisMin = axisMax - axisRange; // 重置日期 Wakeup_CalcUTCTime(axisMin, &sRTC); formQuery.date = sRTC.u32Year * 10000 + sRTC.u32Month * 100 + sRTC.u32Day; } // 设置时间轴 for(i = 0; i <= axisSeg; i++) { axisTime = axisMin + (axisMax - axisMin) / axisSeg * i; Wakeup_CalcUTCTime(axisTime, &sRTC); // 时间标签 formData.oper = DWIN_OPER_WRITE; formData.Addr = 0x67C0 + i * 0x10; sprintf(formData.str, "%02d:%02d", sRTC.u32Hour, sRTC.u32Minute); formData.count = strlen(formData.str); LoopBuff_PutItem(&Form_DataM, (uint8_t *) &formData); // 日期标签 formData.oper = DWIN_OPER_WRITE; formData.Addr = 0x6890 + i * 0x10; sprintf(formData.str, "%02d-%02d", sRTC.u32Month, sRTC.u32Day); formData.count = strlen(formData.str); LoopBuff_PutItem(&Form_DataM, (uint8_t *) &formData); } while(lastRec != -1 && !done) { for(levelRow = 0, pressRow = 0, temprRow = 0; lastRec != -1 && !done; ) { // 读取最后一条记录 SFlash_LoadInfo(LoopBuff_GetDataPos(&RF_DataM, lastRec), (uint8_t *) &Gprs, sizeof(ext_data_t)); // 记录用于翻页 topPtr = lastRec; // 记录已被覆盖 if(memcmp(Gprs.oriPSN, formQuery.PSN, 6) != 0 || Gprs.recvTime - pData->relative_time > minTime) break; minTime = Gprs.recvTime - pData->relative_time; if(lastRec == RF_DataM.info.rdPtr) lastRec = -1; else lastRec = Gprs.prevData; // 判断日期 axisTime = Gprs.recvTime - pData->relative_time; if(axisTime >= axisMax) continue; if(axisTime < axisMin) { done = 1; break; } // 计算坐标点 x = (uint16_t) (x0 + (axisTime - axisMin) * w / axisRange); if(pData->Sensor.staDiff == 0) { y = (uint16_t) (y0 + (Gprs.volumePct - levelMin) * h / levelRange); //y += rand() % 100; levelBuff[levelRow * 2] = htons(x); levelBuff[levelRow * 2 + 1] = htons(y); levelRow++; levelCnt++; } if(pData->Sensor.staPress == 0) { y = (uint16_t) (y0 + (pData->press - pressMin) * h / pressRange); //y += rand() % 100; pressBuff[pressRow * 2] = htons(x); pressBuff[pressRow * 2 + 1] = htons(y); pressRow++; pressCnt++; } if(pData->Sensor.staETempr1 == 0) { y = (uint16_t) (y0 + (pData->tempr - temprMin) * h / temprRange); //y += rand() % 100; temprBuff[temprRow * 2] = htons(x); temprBuff[temprRow * 2 + 1] = htons(y); temprRow++; temprCnt++; } // 一次最多发送20个点 if(levelRow >= 20 || pressRow >= 20 || temprRow >= 20) break; // 总共最多查询1700个点 if(levelCnt >= 1700 || pressCnt >= 1700 || temprCnt >= 1700) { done = 1; break; } } // 加锁 xSemaphoreTake(Form_DataLock, portMAX_DELAY); if(levelRow > 0) { formData.oper = DWIN_OPER_WRITE; formData.Addr = levelAddr + 3 + (levelCnt - levelRow) * 2; formData.count = levelRow * 4; memmove(formData.byte, levelBuff, formData.count); // 加入队列 LoopBuff_PutItem(&Form_DataM, (uint8_t *) &formData); } if(pressRow > 0) { formData.oper = DWIN_OPER_WRITE; formData.Addr = pressAddr + 3 + (pressCnt - pressRow) * 2; formData.count = pressRow * 4; memmove(formData.byte, pressBuff, formData.count); // 加入队列 LoopBuff_PutItem(&Form_DataM, (uint8_t *) &formData); } if(temprRow > 0) { formData.oper = DWIN_OPER_WRITE; formData.Addr = temprAddr + 3 + (temprCnt - temprRow) * 2; formData.count = temprRow * 4; memmove(formData.byte, temprBuff, formData.count); // 加入队列 LoopBuff_PutItem(&Form_DataM, (uint8_t *) &formData); } // 解锁 xSemaphoreGive(Form_DataLock); // 发送消息给任务 xSemaphoreGive(Form_DataQ); } // 加锁 xSemaphoreTake(Form_DataLock, portMAX_DELAY); if(levelCnt > 1) { // 画曲线 formData.oper = DWIN_OPER_WRITE; formData.Addr = levelAddr; formData.count = 6; formData.word[0] = htons(0x0002); formData.word[1] = htons(levelCnt - 1); formData.word[2] = htons(levelColor); // 加入队列 LoopBuff_PutItem(&Form_DataM, (uint8_t *) &formData); } else if(levelCnt == 1) { // 打一个点 formData.oper = DWIN_OPER_WRITE; formData.Addr = levelAddr; formData.count = 10; formData.word[0] = htons(0x0001); formData.word[1] = htons(1); formData.word[2] = levelBuff[0]; formData.word[3] = levelBuff[1]; formData.word[4] = htons(levelColor); // 加入队列 LoopBuff_PutItem(&Form_DataM, (uint8_t *) &formData); } if(pressCnt > 1) { // 画曲线 formData.oper = DWIN_OPER_WRITE; formData.Addr = pressAddr; formData.count = 6; formData.word[0] = htons(0x0002); formData.word[1] = htons(pressCnt - 1); formData.word[2] = htons(pressColor); // 加入队列 LoopBuff_PutItem(&Form_DataM, (uint8_t *) &formData); } else if(pressCnt == 1) { // 打一个点 formData.oper = DWIN_OPER_WRITE; formData.Addr = pressAddr; formData.count = 10; formData.word[0] = htons(0x0001); formData.word[1] = htons(1); formData.word[2] = pressBuff[0]; formData.word[3] = pressBuff[1]; formData.word[4] = htons(pressColor); // 加入队列 LoopBuff_PutItem(&Form_DataM, (uint8_t *) &formData); } if(temprCnt > 1) { // 画曲线 formData.oper = DWIN_OPER_WRITE; formData.Addr = temprAddr; formData.count = 6; formData.word[0] = htons(0x0002); formData.word[1] = htons(temprCnt - 1); formData.word[2] = htons(temprColor); // 加入队列 LoopBuff_PutItem(&Form_DataM, (uint8_t *) &formData); } else if(temprCnt == 1) { // 打一个点 formData.oper = DWIN_OPER_WRITE; formData.Addr = temprAddr; formData.count = 10; formData.word[0] = htons(0x0001); formData.word[1] = htons(1); formData.word[2] = temprBuff[0]; formData.word[3] = temprBuff[1]; formData.word[4] = htons(temprColor); // 加入队列 LoopBuff_PutItem(&Form_DataM, (uint8_t *) &formData); } // 解锁 xSemaphoreGive(Form_DataLock); // 发送消息给任务 xSemaphoreGive(Form_DataQ); // 翻页设置 if(lastRec >= 0) gridQuery.topPtr = topPtr; // 清除空曲线 if(levelCnt == 0) Form_ClearCurve(levelAddr); if(pressCnt == 0) Form_ClearCurve(pressAddr); if(temprCnt == 0) Form_ClearCurve(temprAddr); if(levelCnt == 0 && pressCnt == 0 && temprCnt == 0) { if(dcBuff.configDisplay.ch_en) Form_DispMessage("No data for this time period", DWIN_COLOR_GREEN); else Form_DispMessage("无此时间段内的数据!", DWIN_COLOR_GREEN); } else if(lastRec < 0) { if(dcBuff.configDisplay.ch_en) Form_DispMessage("No data from an earlier time", DWIN_COLOR_GREEN); else Form_DispMessage("无更早时间的数据!", DWIN_COLOR_GREEN); } else Form_ClearMessage(); #else // 测试代码,沿着边框画一个蓝色矩形 osDelay(1000); uint8_t cmd1[50] = { 0x5A, 0xA5, 0x0F, 0x82, 0x28, 0x03, 282 >> 8, 282 & 0xFF, 579 >> 8, 579 & 0xFF, 282 >> 8, 282 & 0xFF, 158 >> 8, 158 & 0xFF, 1212 >> 8, 1212 & 0xFF, 158 >> 8, 158 & 0xFF }; uint8_t cmd2[50] = { 0x5A, 0xA5, 0x0B, 0x82, 0x28, 0x09, 1212 >> 8, 1212 & 0xFF, 579 >> 8, 579 & 0xFF, 282 >> 8, 282 & 0xFF, 579 >> 8, 579 & 0xFF }; uint8_t cmd3[50] = { 0x5A, 0xA5, 0x09, 0x82, 0x28, 0x00, 0x00, 0x02, 0x00, 0x04, 0x00, 0x1F }; UART_Transmit(&huart10, cmd1, cmd1[2] + 3); UART_Transmit(&huart10, cmd2, cmd2[2] + 3); UART_Transmit(&huart10, cmd3, cmd3[2] + 3); #endif } // 查询数据 void Form_Query(int32_t lastRec) { if(formQuery.func == 1) Form_QueryBox(lastRec); else if(formQuery.func == 2) Form_QueryData(lastRec); else if(formQuery.func == 3) Form_QueryCurve(lastRec); } // 关于信息 void Form_About() { uint8_t row = 0; sprintf(gridAbout.rowStr[row++], " 本机PSN: 20%02d%02d%02d%02d%03d", dcBuff.configBottle.PSN[0], dcBuff.configBottle.PSN[1], dcBuff.configBottle.PSN[2], dcBuff.configBottle.PSN[3], (dcBuff.configBottle.PSN[4] << 8) | dcBuff.configBottle.PSN[5]); sprintf(gridAbout.rowStr[row++], " 硬件版本: %d.%d, 软件版本: %d.%d, 软件日期:20%02d-%02d-%02d", dcBuff.powerInfo.hardVer.major, dcBuff.powerInfo.hardVer.minor, dcBuff.powerInfo.softVer.major, dcBuff.powerInfo.softVer.minor, dcBuff.powerInfo.softDate.year, dcBuff.powerInfo.softDate.month, dcBuff.powerInfo.softDate.day); sprintf(gridAbout.rowStr[row++], " 通信模块: %s", dcBuff.powerInfo.dtuRevison); sprintf(gridAbout.rowStr[row++], " IMEI号: %s", dcBuff.powerInfo.imeiNumber); sprintf(gridAbout.rowStr[row++], " SIM卡号: %s", dcBuff.powerInfo.simNumber); sprintf(gridAbout.rowStr[row++], " 4G信号: %d%%, 错误代码: %s", dcBuff.dtuData.rssi, dcBuff.powerInfo.gprsFailCode); sprintf(gridAbout.rowStr[row++], " 定位位置: %.6f, %.6f", dcBuff.dtuData.longitude * 0.000001, dcBuff.dtuData.latitude * 0.000001); sprintf(gridAbout.rowStr[row++], " 定位时间: 20%02d-%02d-%02d %02d:%02d:%02d", dcBuff.dtuData.sysTime.year, dcBuff.dtuData.sysTime.month, dcBuff.dtuData.sysTime.day, dcBuff.dtuData.sysTime.hour, dcBuff.dtuData.sysTime.minute, dcBuff.dtuData.sysTime.second); sprintf(gridAbout.rowStr[row++], " Copyright 安捷汇物联信息技术(苏州)有限公司"); Form_RefreshGrid(&gridAbout); } // 关于信息 void Form_En_About() { uint8_t row = 0; sprintf(gridAboutEn.rowStr[row++], " PSN: 20%02d%02d%02d%02d%03d", dcBuff.configBottle.PSN[0], dcBuff.configBottle.PSN[1], dcBuff.configBottle.PSN[2], dcBuff.configBottle.PSN[3], (dcBuff.configBottle.PSN[4] << 8) | dcBuff.configBottle.PSN[5]); sprintf(gridAboutEn.rowStr[row++], " Hard ver: %d.%d, Soft ver: %d.%d, data:20%02d-%02d-%02d", dcBuff.powerInfo.hardVer.major, dcBuff.powerInfo.hardVer.minor, dcBuff.powerInfo.softVer.major, dcBuff.powerInfo.softVer.minor, dcBuff.powerInfo.softDate.year, dcBuff.powerInfo.softDate.month, dcBuff.powerInfo.softDate.day); sprintf(gridAboutEn.rowStr[row++], " Communication module version: %s", dcBuff.powerInfo.dtuRevison); sprintf(gridAboutEn.rowStr[row++], " IMEI:%s", dcBuff.powerInfo.imeiNumber); sprintf(gridAboutEn.rowStr[row++], " SIM: %s", dcBuff.powerInfo.simNumber); sprintf(gridAboutEn.rowStr[row++], " The signal of 4G: %d%%, Err Code: %s", dcBuff.dtuData.rssi, dcBuff.powerInfo.gprsFailCode); sprintf(gridAboutEn.rowStr[row++], " Location : %.6f, %.6f", dcBuff.dtuData.longitude * 0.000001, dcBuff.dtuData.latitude * 0.000001); sprintf(gridAboutEn.rowStr[row++], " Positioning Time: 20%02d-%02d-%02d %02d:%02d:%02d", dcBuff.dtuData.sysTime.year, dcBuff.dtuData.sysTime.month, dcBuff.dtuData.sysTime.day, dcBuff.dtuData.sysTime.hour, dcBuff.dtuData.sysTime.minute, dcBuff.dtuData.sysTime.second); sprintf(gridAboutEn.rowStr[row++], " Copyright Anjiehui Internet of Things Information Technology (Suzhou) Co., LTD"); Form_RefreshGrid(&gridAboutEn); } static int16_t topPtr=0; void Form_BOX_PSN() { int i=0; uint8_t row = 0; int16_t rowCount=0; topPtr=0; rowCount=gridBox.rowCount; if(rowCount>30)rowCount=30; for(i=0; i30)rowCount=30; memset(gridBox.rowStr, 0, sizeof(gridBox.rowStr)); for(i=0; i 0) { memmove(&key, LoopBuff_GetDataPtr(&Form_KeyM, Form_KeyM.info.rdPtr), sizeof(form_data_t)); LoopBuff_RemoveItems(&Form_KeyM, 1); val = ntohs(key.word[0]); if(key.Addr == 0x5000) // 菜单 { // 点击当前页面,不处理 if(page == val) continue; if((val == 3)||(val == 0x13)) // 进入设置页 Form_RestoreParam(); else if(val == 4) // 显示关于信息 { // Form_SwitchPage(23); // 切换到开机画面 // osDelay(2000); // 延时2秒 Form_About(); // 显示关于信息 } else if(val == 0x14) // 显示关于信息 { // Form_SwitchPage(23); // 切换到开机画面 Form_En_About(); // 显示关于信息 } else if(val == 0x15) // 显示关于信息 { if(3==page) Form_En_About(); // 显示关于信息 dcBuff.configDisplay.ch_en=0; Config_SaveConfig(); } else if(val == 0x05) // 显示关于信息 { dcBuff.configDisplay.ch_en=1; if(4==page) Form_En_About(); // 显示关于信息 Config_SaveConfig(); } else if(val == 0x06) // chu罐 { Form_BOX_PSN(); } page = val; } else if(key.Addr == 0x5034) // chu罐 { Form_BOX_PSN_UP(); } else if(key.Addr == 0x5036) // chu罐 { Form_BOX_PSN_D0WN(); } else if(key.Addr == 0x5012) // 设置 { if(val == 1) // 保存参数 { if(dcBuff.configDisplay.ch_en) Form_DispMessage("Please enter the password.", DWIN_COLOR_GREEN); else Form_DispMessage("请输入密码!", DWIN_COLOR_GREEN); // 弹出密码输入对话(触控区域在可视区域之外,只能由程序弹出) DWIN_Touch(2040, 257); } else // 取消 Form_RestoreParam(); } else if(key.Addr == 0x5030) // 保存参数的密码输入 { if(ntohl(key.dword[0]) == atoi(dcBuff.configDisplay.pwd1)) { if(Form_SaveParam()) { if(dcBuff.configDisplay.ch_en) Form_DispMessage("Save successfully", DWIN_COLOR_GREEN); else Form_DispMessage("保存成功!", DWIN_COLOR_GREEN); } else { if(dcBuff.configDisplay.ch_en) Form_DispMessage("Communication and save failure", DWIN_COLOR_RED); else Form_DispMessage("通信故障,保存失败!", DWIN_COLOR_RED); } } else { if(dcBuff.configDisplay.ch_en) Form_DispMessage("Password error", DWIN_COLOR_RED); else Form_DispMessage("密码错误!", DWIN_COLOR_RED); } } else if(key.Addr == 0x5022) // 查询储罐、数据和曲线 { // 读取查询条件 if(!Form_GetQuery(val, msg)) { Form_DispMessage(msg, DWIN_COLOR_RED); continue; } // 设置查询功能 formQuery.func = val; // 设置表头 if(!Form_PreQuery()) continue; // 首页查询 Form_Query(-1); } else if(key.Addr == 0x502C) // 翻页 { // 翻页查询 Form_Query(gridQuery.topPtr); } else if(key.Addr == 0x5032) // 修改PSN { if(dcBuff.configDisplay.ch_en) Form_DispMessage("Please enter the password.", DWIN_COLOR_GREEN); else Form_DispMessage("请输入密码!", DWIN_COLOR_GREEN); // 弹出密码输入对话(触控区域在可视区域之外,只能由程序弹出) DWIN_Touch(1541, 166); } else if(key.Addr == 0x502E) // 修改PSN的密码输入 { if(ntohl(key.dword[0]) == atoi(dcBuff.configDisplay.pwd2)) { // 设置PSN输入的默认值 // 加锁 xSemaphoreTake(Form_DataLock, portMAX_DELAY); formData.oper = DWIN_OPER_WRITE; // 加入队列 formData.Addr = 0x6F00; sprintf(formData.str, "20%02d%02d%02d%02d%03d", dcBuff.configBottle.PSN[0], dcBuff.configBottle.PSN[1], dcBuff.configBottle.PSN[2], dcBuff.configBottle.PSN[3], (dcBuff.configBottle.PSN[4] << 8) | dcBuff.configBottle.PSN[5]); formData.count = strlen(formData.str); LoopBuff_PutItem(&Form_DataM, (uint8_t *) &formData); // 解锁 xSemaphoreGive(Form_DataLock); // 发送消息给任务 xSemaphoreGive(Form_DataQ); if(dcBuff.configDisplay.ch_en) Form_DispMessage("Please enter a new PSN", DWIN_COLOR_GREEN); else Form_DispMessage("请输入新的PSN!", DWIN_COLOR_GREEN); // 弹出PSN输入对话(触控区域在可视区域之外,只能由程序弹出) DWIN_Touch(2179, 166); } else { if(dcBuff.configDisplay.ch_en) Form_DispMessage("Password error", DWIN_COLOR_GREEN); else Form_DispMessage("密码错误!", DWIN_COLOR_RED); } } else if(key.Addr == 0x6F00) // PSN输入 { if(!Form_ModifyPSN(&key, msg)) Form_DispMessage(msg, DWIN_COLOR_RED); else { if(dcBuff.configDisplay.ch_en) { Form_En_About(); // 刷新关于页的内容 Form_DispMessage("The modification was successful.", DWIN_COLOR_GREEN); } else { Form_About(); // 刷新关于页的内容 Form_DispMessage("修改成功!", DWIN_COLOR_GREEN); } } } } } }