ShipCentralControl/Anjiehui7_DTU/User/dwin_form.c

2844 lines
87 KiB
C
Raw 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.

/*
*********************************************************************************************************
* 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;
static int16_t topPtr=0;
// 屏幕读取结果队列
#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 == 0x9100
|| readData.Addr == 0x5022 || readData.Addr == 0x502C || readData.Addr == 0x502E|| readData.Addr == 0x5040
|| 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);
}
//boxCnt.count=12;
formData.oper = DWIN_OPER_WRITE;
formData.Addr = 0x9002;
formData.count = 2;
formData.word[0] = htons((boxCnt.count/30)+1);
LoopBuff_PutItem(&Form_DataM, (uint8_t *) &formData);
formData.oper = DWIN_OPER_WRITE;
formData.Addr = 0x9000;
formData.count = 2;
formData.word[0] = htons((topPtr/30)+1);
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 = gridBox.hdrAddr+0x1000;
// sprintf(data.str, "%6s",
// "00");
// 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, "pres-MPa");
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, "Temp-℃%");
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);
formData.Addr = 0x5038;
formData.count = 2;
formData.dword[0] = htons(dcBuff.configBottle.lora_freq);
LoopBuff_PutItem(&Form_DataM, (uint8_t *) &formData);
// 解锁
xSemaphoreGive(Form_DataLock);
// 发送消息给任务
xSemaphoreGive(Form_DataQ);
}
// 保存参数
uint8_t Form_SaveParam()
{
uint16_t emptyPct, fullPct, lora_freq;
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(!Form_ReadUInt16(0x5038, &lora_freq))
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(lora_freq != dcBuff.configBottle.lora_freq)
{
dcBuff.configBottle.lora_freq = lora_freq;
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 %10s %5s %6s %4s%8s %12s %5s %5s %7s",
"Num", "Box_number", "Per.", "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 %10s %7s %6s %8s %11s %5s %6s %4s %13s",
"Data", "Time", "Box_number", "Level", "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);
if(dcBuff.configDisplay.ch_en)
Form_SwitchPage(67 + (formQuery.func - 1));
else
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, data20%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);
}
void Form_BOX_PSN()
{
// static form_data_t data2;
int i=0;
uint8_t row = 0;
int16_t rowCount=0;
topPtr=0;
gridBox.rowCount=boxCnt.count;//
rowCount=gridBox.rowCount;
if(rowCount>30)
{
rowCount=30;
gridBox.rowCount=30;
}
for(i=0; i<rowCount; i++)
{
sprintf(gridBox.rowStr[row++], "%s 20%02d%02d%02d%02d%03d",
boxTGGU[i].TGGU, boxTGGU[i].PSN[0], boxTGGU[i].PSN[1], boxTGGU[i].PSN[2],
boxTGGU[i].PSN[3], (boxTGGU[i].PSN[4] << 8) | boxTGGU[i].PSN[5]);
}
Form_RefreshGrid2(&gridBox);
// boxCnt.count=12;
// data2.oper = DWIN_OPER_WRITE;
// data2.Addr = 0x9000;
// data2.count = 2;
// data2.word[0] = htons(boxCnt.count);
// DWIN_Refresh(&data2);
}
void Form_BOX_PSN_D0WN()
{
int i=0;
int16_t rowCount=0;
uint8_t row = 0;
//boxCnt.count
rowCount=boxCnt.count-topPtr;
if(rowCount<31) return;
topPtr+=30;
rowCount-=30;
row=0;
if(rowCount>30)rowCount=30;
memset(gridBox.rowStr, 0, sizeof(gridBox.rowStr));
for(i=0; i<rowCount; i++)
{
sprintf(gridBox.rowStr[row++], "%s 20%02d%02d%02d%02d%03d",
boxTGGU[topPtr+i].TGGU, boxTGGU[topPtr+i].PSN[0], boxTGGU[topPtr+i].PSN[1], boxTGGU[topPtr+i].PSN[2],
boxTGGU[topPtr+i].PSN[3], (boxTGGU[topPtr+i].PSN[4] << 8) | boxTGGU[topPtr+i].PSN[5]);
}
Form_RefreshGrid2(&gridBox);
}
void Form_BOX_PSN_UP()
{
int i=0;
int16_t rowCount=0;
uint8_t row = 0;
if(topPtr<30)return;
topPtr-=30;
for(i=0; i<30; i++)
{
sprintf(gridBox.rowStr[row++], "%s 20%02d%02d%02d%02d%03d",
boxTGGU[topPtr+i].TGGU, boxTGGU[topPtr+i].PSN[0], boxTGGU[topPtr+i].PSN[1], boxTGGU[topPtr+i].PSN[2],
boxTGGU[topPtr+i].PSN[3], (boxTGGU[topPtr+i].PSN[4] << 8) | boxTGGU[topPtr+i].PSN[5]);
}
Form_RefreshGrid2(&gridBox);
}
// 按键任务主体
void Key_Task(void *p_arg)
{
static form_data_t key;
uint8_t page = 0;
uint16_t val;
char msg[40];
while(1)
{
// 处理其它显示任务
if(xSemaphoreTake(Form_KeyQ, 500) != pdTRUE)
continue;
while(LoopBuff_GetCount(&Form_KeyM) > 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)||(val == 0x16)) // 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 == 0x5040) // chu罐
{
// Form_DispMessage("请输入密码!", DWIN_COLOR_GREEN);
DWIN_Touch(1265, 105);
}
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);
}
}
}
else if(key.Addr == 0x9100) // PSN输入
{
// if(!Form_ModifyPSN(&key, msg))
// Form_DispMessage(msg, DWIN_COLOR_RED);
// else
if(ntohs(key.dword[0]) == atoi(dcBuff.configDisplay.pwd1))
{
bottleCnt.count = 0;
FRAM_SaveInfo(0, 0, FRAM_SIZE);
if(dcBuff.configDisplay.ch_en)
{
Form_DispMessage("Successfully deleted.", DWIN_COLOR_GREEN);
}
else
{
Form_DispMessage("删除成功!", DWIN_COLOR_GREEN);
}
osDelay(1000);
HAL_NVIC_SystemReset();
}
else
{
if(dcBuff.configDisplay.ch_en)
{
Form_DispMessage("password error!", DWIN_COLOR_GREEN);
}
else
{
Form_DispMessage("密码错误!", DWIN_COLOR_GREEN);
}
}
}
}
}
}