1.窗体间传值
- 委托
//声明委托
public delegate void BtnClickDelagate(object sender, EventArgs e);
//创建委托事件
public event BtnClickDelagate UserControlClick;
- 全局变量
//创建变量实例
public Variable_Modbus var;
//创建报警变量实例
public VarAlarm_Modbus varAlarm;
2.在类库中创建文件想放到文件夹中,不要直接在文件夹中创建,应该在类库中创建,然后拖入到文件夹里,不然命名空间会报错
3.引用新的类库后,仍然报错找不到,此时应该关闭项目在重新打开
4.当使用dateGradView的时候,表格内容如果需要从下位机获取,那么该如何设计呢?
我之前的做法:
1.下位机是c语言实现,并没有类的概念,所以使用结构体来实现一条记录。但是在填充表格控件的时候没法设置数据源,只好我手动添加一行,添加一列,写个for循环,如果结构体还有嵌套的话,那么在fort循环里还要继续for,如果你的表格结构字段又添加一个或者删除一个,之前的工作还有再重新做一遍,非常麻烦!!!对了,还没有说当上位机接收到这个结构体之后如何解析呢,怎么解析,c#也是支持结构体的,所以我把这个结构拷贝一份,拿到c#中,再写个字节数组转结构体的方法,获取到对应字段的值,如果不用这种方法的话,智只能通过数组下标来解析结构体中各个字段的值了,很头疼吧。。。
新的方法:
上位机的表格控件绑定数据源,数据源可以是一个集合。
this.dgv_data.DataSource = this.VarList;
- 如何获取list ?
这个集合是从单片机获取的,那么单片机的数据结构里没有集合,只有结构体
结构体 —> 集合
集合也没有协议规定啊,怎么转换呢?所以需要一个协议或者格式把结构体转换一下
结构体 —> json/xml —> 集合 - 单片机端何如使用 json/xml
xml的解析可以使用mxml(开源xml解析器)
json解析可以使用cjson,我感觉json更简单,所以我选择json - 单片机发送json到上位机
单片机把结构体数组转换为json字符串(json中也是有数组概念的)进行传输,传输json文件也可以,因为这个是需要保存的,系统上电的时候把这个文件读到ram里面,然后应用程序需要使用里面的数据。话说字符串传输和文件传输也没啥区别。。。 - 上位机将json显示到表格中
上位机收到数据之后,遍历一下,取出数据保存到实体类中,然后依次加入到集合,最后设置表格的DataSource属性,完成。
c#解析json用到Newtonsoft,基本使用方法学习https://blog.csdn.net/u013667796/article/details/83826592
代码:
public static List<Variable_Sensor> LoadSensorJSON(string jsonpath)
{
List<Variable_Sensor> VarSensorList = null;
if (!File.Exists(jsonpath))
{
MessageBox.Show("IO配置变量的json文件不存在!");
}
else
{
VarSensorList = new List<Variable_Sensor>();
StreamReader file = File.OpenText(jsonpath);
JsonTextReader reader = new JsonTextReader(file);
JObject jsonObject = (JObject)JToken.ReadFrom(reader);
JObject json_root = (JObject)jsonObject["Root"];
var json_root_var = json_root["Variable"];
foreach (JObject obj in json_root_var)
{
Variable_Sensor objVar = new Variable_Sensor();
objVar.VarName = obj["VarName"].ToString();
objVar.Address = obj["Address"].ToString();
objVar.DataType = obj["DataType"].ToString();
objVar.StoreArea = obj["StoreArea"].ToString();
objVar.Note = obj["Note"].ToString();
objVar.RegAdd = obj["RegAdd"].ToString();
objVar.RegAddLen = obj["RegAddLen"].ToString();
objVar.Unit = obj["Unit"].ToString();
objVar.IsUse = obj["IsUse"].ToString();
VarSensorList.Add(objVar);
}
reader.Close();
file.Close();
}
return VarSensorList;
}
效果图:
下位机结构体与json互转的方法:
struct.h
#ifndef __TAB_STRUCT_
#define __TAB_STRUCT_
#include "data_type.h"
#include "cJSON.h"
#define LINKAGE_COUNT 8//联动输出数量
#pragma pack (1)
#pragma pack ()
//状态 0或者1
typedef enum _TAB_STA_ENUM
{
DISABLE_STA,
ENABLE_STA,
}TAB_STA_ENUM;
//接口类型 上位机也有一份 在json文件里
typedef enum _INTERFACE_ENUM
{
TYPE_4851,
TYPE_4852,
TYPE_232_1,
TYPE_232_2,
TYPE_TCP,
TYPE_LORA,
DI_1,
DI_2,
DI_3,
DI_4,
DI_5,
DI_6,
DI_7,
DI_8
}INTERFACE_ENUM;
/* 数值类型 */
typedef enum _VALUE_TYPE
{
VALUE_BOOL,
VALUE_INT,
VALUE_FLOAT,
}VALUE_TYPE_ENUM;
/* 报警类型 */
typedef enum _WARNTYPE
{
WARN_DISABLE,//禁用告警 VALUE_BOOL
WARN_CLOSE,//闭合告警 VALUE_BOOL
WARN_BREAK,//断开告警 VALUE_BOOL
WARN_DEST,//定值报警
WARN_HI,//高报警 高于设定值
WARN_LI,//低报警 低于设定值
WARN_HILI//高低报警 范围内
}WARNTYPE_ENUM;
//协议类型
typedef enum _AMT_TYPE_ENUM
{
AMT_DI,
AMT_MODBUS,
AMT_DOOR,
AMT_UPS,
AMT_SCREEN,
AMT_COUNT,
AMT_NONE
}AMT_TYPE_ENUM;
/* 用户表记录的数量 */
#define USERTAB_RECORD_NUM 50
#define ROOT_TAB_SENIOR_LEN 20//传感器型号长度
#define TAB_UARTPARAMS_NUM 12+1//接口参数 "115200,8,1,0" 数据区最大长度+1 +'\0'
#define TAB_NOTE_NUM 30+1 //设备表 设备描述 安装位置 备注 的长度 中文占2字节 +'\0'
#define TAB_UNIT_LEN 10+1//单位长度 +'\0'
#define AMT_TAG_LEN 20+1//单位长度 +'\0'
#define LINKAGE_OUT_NUM 4//联动输出的数量
#define CACHE_DATA_SIZE 50//缓存表中数据长度
//报警
typedef struct _WarningTypedef
{
/* 报警方式 */
WARNTYPE_ENUM type;
/* 报警值类型 根据WARNTYPE_ENUM得到 VALUE_BOOL用不到下面的字段*/
VALUE_TYPE_ENUM valtype;
int valueint; /* The item's number, if type==VALUE_INT */
float valuefloat; /* The item's number, if type==VALUE_FLOAT */
}WarningTypedef;
//联动
typedef struct _LinkAgeTypedef
{
TAB_STA_ENUM dout[LINKAGE_OUT_NUM];
u8 dout_t[LINKAGE_OUT_NUM];
}LinkAgeTypedef;
//系数
typedef struct _VAL_MODULUS
{
VALUE_TYPE_ENUM type;
int valueint;
float valuefloat;
}ValModulusTypedef;
//协议
typedef struct _AmtParamsTypedef
{
/* 协议类型 */
AMT_TYPE_ENUM type;
/* 标识符 */
char tag[AMT_TAG_LEN];
/* 下面只针对modbus协议 */
/* 功能码 */
u8 fun;
/* 寄存器地址 */
uint16_t reg_addr;
/* 寄存器长度 */
uint16_t reg_len;
/* 单位 */
char unit[TAB_UNIT_LEN];
/* 系数 */
ValModulusTypedef modulus;
}AmtParamsTypedef;
//用户记录格式
typedef struct _UserRecordTypedef
{
/* 记录的id 自增长 1++ */
u16 id;
/* 是否启用 */
TAB_STA_ENUM isuse;
/* 接口 */
INTERFACE_ENUM interfac;
/* 通信ID */
u16 commid;
/* 串口参数 */
char uart_params[TAB_UARTPARAMS_NUM];
/* 超时时间ms */
u16 timeout;
/* 传感器型号 和管理员表中的model相同 */
char model[ROOT_TAB_SENIOR_LEN];
/* 备注 和管理员表中的note相同 */
char note[TAB_NOTE_NUM];
/* 告警参数 */
WarningTypedef warning_params;
/* 联动输出 */
LinkAgeTypedef linkage_params;
/* 协议参数 */
AmtParamsTypedef amt_params;
}UserRecordTypedef;
#define Size_UserRecordTypedef sizeof(UserRecordTypedef)
//用户配置表
typedef struct _UserTab{
/* 有效记录的数量 */
u8 num;
UserRecordTypedef array[USERTAB_RECORD_NUM];
}UserTabTypedef;
#define Size_UserTabTypedef sizeof(UserTabTypedef)
extern UserTabTypedef userTab;
//缓存表
typedef struct _CacheRecord{
/* 数据区长度 */
u16 data_len;
/* 数据区 */
u8 data[CACHE_DATA_SIZE];
int valueint;
float valuefloat;
/* 错误计数 */
u8 err_num;
/* 在线状态 */
u8 isonline;
/* 报警状态 */
u8 iswarning;
}CacheRecordTypedef;
#define Size_CacheRecordTypedef sizeof(CacheRecordTypedef)
extern CacheRecordTypedef cacheTab[USERTAB_RECORD_NUM];
void save_user_tab(void);
void user_tab_init(void);
char *userTabToJsonString(u8 fmt);
char *cacheTabToJsonString(u8 fmt);
char *userTabStructToJson();
u8 JsonStringToUserTab(char* p);
cJSON *parseRootJson(cJSON *pJson);
cJSON *parseVarJson(cJSON * pJson);
u8 parse_uartConfig_string(u8* string,u8 stringLen,u32* bps,u8* dataLen,u8* stopLen,u8* parity);
#endif
struct.c
/*
* @Descripttion:
* @version: 1.0.0
* @Author: zhangyasheng
* @Date: 2020-07-05 11:13:14
* @LastEditors: zhangyasheng
* @LastEditTime: 2020-07-08 12:40:12
*/
#include "tab_struct.h"
#include "w25qxx.h"
#include "led.h"
#include "string.h"
#include "malloc.h"
#include "common.h"
#include "some_sensor.h"
/********************************************************************/
//1.json的键名 首字母大写 (c#构造方法中 首字母是大写的)
/********************************************************************/
UserTabTypedef userTab;
CacheRecordTypedef cacheTab[USERTAB_RECORD_NUM];
cJSON *makeUserRecordJson(u16 i);
cJSON *makeCacheRecordJson();
cJSON *makeVarArrayJson();
cJSON *makeVarJson();
cJSON *makeRootJson();
char *userTabToJsonString(u8 fmt);
cJSON *parseVarArrayJson(cJSON * pJson);
cJSON *parseUserRecordJson(cJSON *pJson,u16 i);
void user_tab_init()
{
OS_CPU_SR cpu_sr = 0;
char *p;
OS_ENTER_CRITICAL();
W25QXX_Read((u8*)&userTab,USERCONFIGTAB_ADDR,USERCONFIGTAB_SIZE);
OS_EXIT_CRITICAL();
printf("ram:%d",my_mem_perused(SRAMIN));
// userTab.num = 1;
// userTab.array[0].id = 1;
// userTab.array[0].isuse = ENABLE_STA;
// userTab.array[0].interfac = TYPE_4852;
// userTab.array[0].commid = 10;
// sprintf(userTab.array[0].uart_params,"9600,8,1,0");
// sprintf(userTab.array[0].model,"123");
// sprintf(userTab.array[0].note,"中文");
// userTab.array[0].warning_params.type = WARN_DISABLE;
// userTab.array[0].warning_params.valtype = VALUE_INT;
// userTab.array[0].warning_params.valueint = -12;
// userTab.array[0].linkage_params.dout[1] = 1;
// userTab.array[0].linkage_params.dout_t[1] = 2;
// userTab.array[0].amt_params.type = AMT_MODBUS;
// sprintf(userTab.array[0].amt_params.tag,"1#温度");
// userTab.array[0].amt_params.fun = 0x03;
// userTab.array[0].amt_params.reg_addr = 0x0001;
// userTab.array[0].amt_params.reg_len = 1;
// sprintf(userTab.array[0].amt_params.unit,"℃");
// userTab.array[0].amt_params.modulus.type = VALUE_FLOAT;
// userTab.array[0].amt_params.modulus.valuefloat = 0.1;
// //p = userTabStructToJson();
// p = userTabToJsonString(1);
// if(p != NULL)
// {
// printf("%s",p);
// }
// printf("\r\n ram:%d",my_mem_perused(SRAMIN));
// myfree(SRAMIN,p);
// printf("\r\n ram:%d",my_mem_perused(SRAMIN));
}
/**
* @name: 用户表转换为json字符串 记得释放返回值
* @param 0:不带格式 1:带格式
* @return: 字符串指针
*/
char *userTabToJsonString(u8 fmt)
{
char *p;
cJSON *pJson=NULL;
pJson = makeRootJson();
if(!fmt)p = cJSON_PrintUnformatted(pJson);//打印调试的时候 可以选这个 不带格式
else p = cJSON_Print(pJson);//往文件输出的时候 选择这个 带格式
cJSON_Delete(pJson);
return p;
}
/**
* @name: 缓存表转换为json字符串 记得释放返回值
* @param 0:不带格式 1:带格式
* @return: 字符串指针
*/
char *cacheTabToJsonString(u8 fmt)
{
char *p;
cJSON *pJson=NULL;
pJson = cJSON_CreateObject();
if(NULL == pJson)return NULL;
cJSON_AddItemToObject(pJson,"Records",makeCacheRecordJson());
cJSON_AddNumberToObject(pJson,"Raminuse",my_mem_perused(SRAMIN));
cJSON_AddNumberToObject(pJson,"Ramexuse",my_mem_perused(SRAMEX));
cJSON_AddBoolToObject(pJson,"Linken",glo.linkage_en);
cJSON_AddBoolToObject(pJson,"Out1",OUT1);
cJSON_AddBoolToObject(pJson,"Out2",OUT2);
cJSON_AddBoolToObject(pJson,"Out3",OUT3);
cJSON_AddBoolToObject(pJson,"Out4",OUT4);
cJSON_AddBoolToObject(pJson,"Input1",INPUT1);
cJSON_AddBoolToObject(pJson,"Input2",INPUT2);
cJSON_AddBoolToObject(pJson,"Input3",INPUT3);
cJSON_AddBoolToObject(pJson,"Input4",INPUT4);
cJSON_AddBoolToObject(pJson,"Input5",INPUT5);
cJSON_AddBoolToObject(pJson,"Input6",INPUT6);
cJSON_AddBoolToObject(pJson,"Input7",INPUT7);
cJSON_AddBoolToObject(pJson,"Input8",INPUT8);
if(!fmt)p = cJSON_PrintUnformatted(pJson);//打印调试的时候 可以选这个 不带格式
else p = cJSON_Print(pJson);//往文件输出的时候 选择这个 带格式
cJSON_Delete(pJson);
return p;
}
/**
* @name: json字符串转为用户表
* @param json字符串
* @return: 0:成功 其他:失败
*/
u8 JsonStringToUserTab(char* p)
{
cJSON *pJson=NULL;
cJSON *pSub=NULL;
if(NULL == p)
{
return 1;
}
pJson = cJSON_Parse(p);
if(NULL == pJson)
{
return 1;
}
pSub = parseRootJson(pJson);
cJSON_Delete(pJson);
if(NULL == pSub)
{
return 1;
}
return 0;
}
/**
* @name: 创建Root节点
* @param {type}
* @return: cJSON
*/
cJSON *makeRootJson()
{
cJSON * pJson = NULL;
pJson = cJSON_CreateObject();
if(NULL == pJson)return NULL;
cJSON_AddItemToObject(pJson,"Root",makeVarJson());
return pJson;
}
/**
* @name: 解析Root json 并返回json对象
* @param {type}
* @return: cJSON
*/
cJSON *parseRootJson(cJSON *pJson)
{
cJSON * pSub=NULL;
pSub = cJSON_GetObjectItem(pJson,"Root");
if(NULL == pSub)
{
return NULL;
}
pSub = parseVarJson(pSub);
#if 0
p = cJSON_Print(pJson);
printf("%s",p);
myfree(SRAMIN,p);
#endif
return pSub;
}
/**
* @name: 创建Variable节点
* @param {type}
* @return: cJSON
*/
cJSON *makeVarJson()
{
cJSON * pJson = NULL;
pJson = cJSON_CreateObject();
if(NULL == pJson)return NULL;
cJSON_AddItemToObject(pJson,"Variable",makeVarArrayJson());
return pJson;
}
/**
* @name: 解析Variable节点
* @param {type}
* @return: cJSON
*/
cJSON *parseVarJson(cJSON *pJson)
{
cJSON *pSub=NULL;
char *p=NULL;
pSub = cJSON_GetObjectItem(pJson, "Variable");
if(NULL == pSub)
{
return NULL;
}
#if 0
p = cJSON_Print(pJson);
printf("%s",p);
myfree(SRAMIN,p);
#endif
pSub = parseVarArrayJson(pSub);
if(NULL == pSub)
{
return NULL;
}
return pSub;
}
/**
* @name: 创建VarArray节点
* @param {type}
* @return: cJSON
*/
cJSON *makeVarArrayJson()
{
u16 i;
cJSON * pJson = NULL;
pJson = cJSON_CreateArray();
if(NULL == pJson)return NULL;
for (i = 0; i < userTab.num; i++)
{
cJSON_AddItemToArray(pJson,makeUserRecordJson(i));
}
return pJson;
}
/**
* @name: 解析VarArray节点
* @param {type}
* @return: cJSON
*/
cJSON *parseVarArrayJson(cJSON * pJson)
{
u16 i=0;
u16 iSize=0;
u16 iValue=0;
cJSON *pSub=NULL;
iSize = cJSON_GetArraySize(pJson);
for(i = 0; i < iSize; i++)
{
pSub = cJSON_GetArrayItem(pJson, i);
if(NULL == pSub)
{
continue;
}
pSub = parseUserRecordJson(pSub,i);
if(NULL == pSub)
{
return NULL;
}
}
return pSub;
}
/**
* @name: 创建WarningTypedef节点
* @param {type}
* @return: cJSON
*/
cJSON *makeWarningTypedefJson(u16 i)
{
cJSON * pJson = NULL;
pJson = cJSON_CreateObject();
if(NULL == pJson)return NULL;
/* 告警参数 */
cJSON_AddNumberToObject(pJson,"Type",userTab.array[i].warning_params.type);
cJSON_AddNumberToObject(pJson,"Valtype",userTab.array[i].warning_params.valtype);
if(userTab.array[i].warning_params.valtype == VALUE_BOOL || userTab.array[i].warning_params.valtype == VALUE_INT)
{
cJSON_AddNumberToObject(pJson,"Valueint",userTab.array[i].warning_params.valueint);
}
else if(userTab.array[i].warning_params.valtype == VALUE_FLOAT)
{
cJSON_AddNumberToObject(pJson,"Valuefloat",userTab.array[i].warning_params.valuefloat);
}
return pJson;
}
/**
* @name: 解析WarningTypedef节点 在array循环中调用
* @param Warning_params的json结构 记录的下标
* @return: 返回参数pjson:成功 NULL: 失败
*/
cJSON *parseWarningTypedefJson(cJSON *pJson,u16 i)
{
cJSON * pSub = NULL;
cJSON * item = NULL;
pSub = cJSON_GetObjectItem(pJson, "Warning_params");
if(NULL == pSub)
{
return NULL;
}
item = cJSON_GetObjectItem(pSub,"Type");
if(NULL == item)return NULL;
userTab.array[i].warning_params.type = item->valueint;
item = cJSON_GetObjectItem(pSub,"Valtype");
if(NULL == item)return NULL;
userTab.array[i].warning_params.valtype = item->valueint;
if(userTab.array[i].warning_params.valtype == VALUE_BOOL || userTab.array[i].warning_params.valtype == VALUE_INT)
{
item = cJSON_GetObjectItem(pSub,"Valueint");
if(NULL == item)return NULL;
userTab.array[i].warning_params.valueint = item->valueint;
}
else if(userTab.array[i].warning_params.valtype == VALUE_FLOAT)
{
item = cJSON_GetObjectItem(pSub,"Valuefloat");
if(NULL == item)return NULL;
userTab.array[i].warning_params.valuefloat = item->valuedouble;
}
return pJson;
}
/**
* @name: 创建LinkAgeTypedef节点
* @param {type}
* @return: cJSON
*/
cJSON *makeLinkAgeTypedefJson(u16 i)
{
u8 cnt=0;
char *buff1[] = {"Do0","Do1","Do2","Do3"};
char *buff2[] = {"Dt0","Dt1","Dt2","Dt3"};
cJSON * pJson = NULL;
pJson = cJSON_CreateObject();
if(NULL == pJson)return NULL;
/* 联动输出 */
for(cnt=0;cnt<LINKAGE_OUT_NUM;cnt++)
{
cJSON_AddBoolToObject(pJson,buff1[cnt],userTab.array[i].linkage_params.dout[cnt]);
cJSON_AddNumberToObject(pJson,buff2[cnt],userTab.array[i].linkage_params.dout_t[cnt]);
}
return pJson;
}
/**
* @name: 解析LinkAgeTypedef节点
* @param {type}
* @return: cJSON
*/
cJSON *parseLinkAgeTypedefJson(cJSON *pJson,u16 i)
{
u8 cnt=0;
char *buff1[] = {"Do0","Do1","Do2","Do3"};
char *buff2[] = {"Dt0","Dt1","Dt2","Dt3"};
cJSON * pSub = NULL;
cJSON * item = NULL;
pSub = cJSON_GetObjectItem(pJson, "Linkage_params");
if(NULL == pSub)
{
return NULL;
}
/* 联动输出 */
for(cnt=0;cnt<LINKAGE_OUT_NUM;cnt++)
{
item = cJSON_GetObjectItem(pSub,buff1[cnt]);
if(NULL == item)return NULL;
userTab.array[i].linkage_params.dout[cnt] = item->valueint;
item = cJSON_GetObjectItem(pSub,buff2[cnt]);
if(NULL == item)return NULL;
userTab.array[i].linkage_params.dout_t[cnt] = item->valueint;
}
return pJson;
}
/**
* @name: 创建ValModulusTypedef节点
* @param {type}
* @return: cJSON
*/
cJSON *makeValModulusTypedefJson(u16 i)
{
cJSON * pJson = NULL;
pJson = cJSON_CreateObject();
if(NULL == pJson)return NULL;
/* 系数 */
cJSON_AddNumberToObject(pJson, "Type",userTab.array[i].amt_params.modulus.type);
if(userTab.array[i].amt_params.modulus.type == VALUE_BOOL || userTab.array[i].amt_params.modulus.type == VALUE_INT)
{
cJSON_AddNumberToObject(pJson, "Valueint",userTab.array[i].amt_params.modulus.valueint);
}
else if(userTab.array[i].amt_params.modulus.type == VALUE_FLOAT)
{
cJSON_AddNumberToObject(pJson, "Valuefloat",userTab.array[i].amt_params.modulus.valuefloat);
}
return pJson;
}
/**
* @name: 解析ValModulusTypedef节点
* @param {type}
* @return: 返回pJson:成功 NULL:失败
*/
cJSON *parseValModulusTypedefJson(cJSON *pJson,u16 i)
{
cJSON * pSub = NULL;
cJSON * item = NULL;
pSub = cJSON_GetObjectItem(pJson, "Modulus");
if(NULL == pSub)
{
return NULL;
}
item = cJSON_GetObjectItem(pSub,"Type");
if(NULL == item)return NULL;
userTab.array[i].amt_params.modulus.type = item->valueint;
if(userTab.array[i].amt_params.modulus.type == VALUE_BOOL || userTab.array[i].amt_params.modulus.type == VALUE_INT)
{
item = cJSON_GetObjectItem(pSub,"Valueint");
if(NULL == item)return NULL;
userTab.array[i].amt_params.modulus.valueint = item->valueint;
}
else if(userTab.array[i].amt_params.modulus.type == VALUE_FLOAT)
{
item = cJSON_GetObjectItem(pSub,"Valuefloat");
if(NULL == item)return NULL;
userTab.array[i].amt_params.modulus.valuefloat = item->valuedouble;
}
return pJson;
}
/**
* @name: 创建AmtParamsTypedef节点
* @param {type}
* @return: cJSON
*/
cJSON *makeAmtParamsTypedefJson(u16 i)
{
cJSON * pJson = NULL;
pJson = cJSON_CreateObject();
if(NULL == pJson)return NULL;
/* 协议参数 */
cJSON_AddNumberToObject(pJson,"Type",userTab.array[i].amt_params.type);
userTab.array[i].amt_params.tag[AMT_TAG_LEN-1]=0;
cJSON_AddStringToObject(pJson,"Tag",userTab.array[i].amt_params.tag);
cJSON_AddNumberToObject(pJson,"Fun",userTab.array[i].amt_params.fun);
cJSON_AddNumberToObject(pJson,"Reg_addr",userTab.array[i].amt_params.reg_addr);
cJSON_AddNumberToObject(pJson,"Reg_len",userTab.array[i].amt_params.reg_len);
userTab.array[i].amt_params.unit[TAB_UNIT_LEN-1]=0;
cJSON_AddStringToObject(pJson,"Unit",userTab.array[i].amt_params.unit);
cJSON_AddItemToObject(pJson,"Modulus",makeValModulusTypedefJson(i));
return pJson;
}
/**
* @name: 解析AmtParamsTypedef节点
* @param {type}
* @return: 返回pJson:成功 NULL:失败
*/
cJSON *parseAmtParamsTypedefJson(cJSON *pJson,u16 i)
{
cJSON * pSub = NULL;
cJSON * item = NULL;
u8 len=0;
pSub = cJSON_GetObjectItem(pJson, "Amt_params");
if(NULL == pSub)
{
return NULL;
}
item = cJSON_GetObjectItem(pSub,"Type");
if(NULL == item)return NULL;
userTab.array[i].amt_params.type = item->valueint;
item = cJSON_GetObjectItem(pSub,"Tag");
if(NULL == item)return NULL;
len = strlen(item->valuestring);
if(len>AMT_TAG_LEN) len=AMT_TAG_LEN;
memcpy(userTab.array[i].amt_params.tag,item->valuestring,len);
userTab.array[i].amt_params.tag[AMT_TAG_LEN-1]=0;
item = cJSON_GetObjectItem(pSub,"Fun");
if(NULL == item)return NULL;
userTab.array[i].amt_params.fun = item->valueint;
item = cJSON_GetObjectItem(pSub,"Reg_addr");
if(NULL == item)return NULL;
userTab.array[i].amt_params.reg_addr = item->valueint;
item = cJSON_GetObjectItem(pSub,"Reg_len");
if(NULL == item)return NULL;
userTab.array[i].amt_params.reg_len = item->valueint;
item = cJSON_GetObjectItem(pSub,"Unit");
if(NULL == item)return NULL;
len = strlen(item->valuestring);
if(len>TAB_UNIT_LEN) len=TAB_UNIT_LEN;
memcpy(userTab.array[i].amt_params.unit,item->valuestring,len);
userTab.array[i].amt_params.unit[TAB_UNIT_LEN-1]=0;
item = parseValModulusTypedefJson(pSub,i);
if(NULL == item)return NULL;
return pJson;
}
/**
* @name: 创建UserRecord节点
* @param {type}
* @return: cJSON
*/
cJSON *makeUserRecordJson(u16 i)
{
cJSON * pJson = NULL;
pJson = cJSON_CreateObject();
if(NULL == pJson)return NULL;
/* id */
cJSON_AddNumberToObject(pJson,"Id",userTab.array[i].id);
/* 是否启用 */
cJSON_AddBoolToObject(pJson,"Isuse",userTab.array[i].isuse);
/* 接口 */
cJSON_AddNumberToObject(pJson,"Interfac",userTab.array[i].interfac);
/* 通信ID */
cJSON_AddNumberToObject(pJson,"Commid",userTab.array[i].commid);
/* 串口参数 */
userTab.array[i].uart_params[TAB_UARTPARAMS_NUM-1] = 0;
cJSON_AddStringToObject(pJson,"Uart_params",userTab.array[i].uart_params);
/* 超时时间 */
cJSON_AddNumberToObject(pJson,"Timeout",userTab.array[i].timeout);
/* 传感器型号 和管理员表中的model相同 */
userTab.array[i].model[ROOT_TAB_SENIOR_LEN-1] = 0;
cJSON_AddStringToObject(pJson,"Model",userTab.array[i].model);
/* 备注 和管理员表中的note相同 */
userTab.array[i].note[TAB_NOTE_NUM-1] = 0;
cJSON_AddStringToObject(pJson,"Note",userTab.array[i].note);
/* 告警参数 */
cJSON_AddItemToObject(pJson,"Warning_params",makeWarningTypedefJson(i));
/* 联动输出 */
cJSON_AddItemToObject(pJson,"Linkage_params",makeLinkAgeTypedefJson(i));
/* 协议参数 */
cJSON_AddItemToObject(pJson,"Amt_params",makeAmtParamsTypedefJson(i));
return pJson;
}
/**
* @name: 解析UserRecord节点
* @param {type}
* @return: 返回pJson:成功 NULL:失败
*/
cJSON *parseUserRecordJson(cJSON *pJson,u16 i)
{
cJSON * item = NULL;
u8 len=0;
/* id */
item = cJSON_GetObjectItem(pJson,"Id");
if(NULL == item)return NULL;
userTab.array[i].id = item->valueint;
/* 是否启用 */
item = cJSON_GetObjectItem(pJson,"Isuse");
if(NULL == item)return NULL;
userTab.array[i].isuse = item->valueint;
/* 接口 */
item = cJSON_GetObjectItem(pJson,"Interfac");
if(NULL == item)return NULL;
userTab.array[i].interfac = item->valueint;
/* 通信ID */
item = cJSON_GetObjectItem(pJson,"Commid");
if(NULL == item)return NULL;
userTab.array[i].commid = item->valueint;
/* 串口参数 */
item = cJSON_GetObjectItem(pJson,"Uart_params");
if(NULL == item)return NULL;
len = strlen(item->valuestring);
if(len>(TAB_UARTPARAMS_NUM-1))len=TAB_UARTPARAMS_NUM-1;
memcpy(userTab.array[i].uart_params,item->valuestring,len);
userTab.array[i].uart_params[len] = 0;
/* 超时时间 */
item = cJSON_GetObjectItem(pJson,"Timeout");
if(NULL == item)return NULL;
userTab.array[i].timeout = item->valueint;
/* 传感器型号 和管理员表中的model相同 */
item = cJSON_GetObjectItem(pJson,"Model");
if(NULL == item)return NULL;
len = strlen(item->valuestring);
if(len>(ROOT_TAB_SENIOR_LEN-1))len=ROOT_TAB_SENIOR_LEN-1;
memcpy(userTab.array[i].model,item->valuestring,len);
userTab.array[i].model[len] = 0;
/* 备注 */
item = cJSON_GetObjectItem(pJson,"Note");
if(NULL == item)return NULL;
len = strlen(item->valuestring);
if(len>(TAB_NOTE_NUM-1))len=TAB_NOTE_NUM-1;
memcpy(userTab.array[i].note,item->valuestring,len);
userTab.array[i].note[len] = 0;
/* 告警参数 */
item = parseWarningTypedefJson(pJson,i);
if(NULL == item)return NULL;
/* 联动输出 */
item = parseLinkAgeTypedefJson(pJson,i);
if(NULL == item)return NULL;
/* 协议参数 */
item = parseAmtParamsTypedefJson(pJson,i);
if(NULL == item)return NULL;
return pJson;
}
/**
* @name: 创建CacheRecord节点
* @param {type}
* @return: cJSON
*/
cJSON *makeCacheRecordJson()
{
u16 i;
cJSON * pJson = NULL;
cJSON * item = NULL;
pJson = cJSON_CreateArray();
if(NULL == pJson)return NULL;
for (i = 0; i < userTab.num; i++)
{
item = cJSON_CreateObject();
if(NULL == item)break;
/* 数据区长度 */
cJSON_AddNumberToObject(item,"Data_len",cacheTab[i].data_len);
/* 数据区 */
cacheTab[i].data[CACHE_DATA_SIZE-1] = 0;
cJSON_AddStringToObject(item,"Data",cacheTab[i].data);
if(userTab.array[i].amt_params.modulus.type == VALUE_FLOAT)cJSON_AddNumberToObject(item,"Value",cacheTab[i].valuefloat);
else cJSON_AddNumberToObject(item,"Value",cacheTab[i].valueint);
/* 错误计数 */
cJSON_AddNumberToObject(item,"Err_num",cacheTab[i].err_num);
/* 在线状态 */
cJSON_AddBoolToObject(item,"Isonline",cacheTab[i].isonline);
/* 报警状态 */
cJSON_AddBoolToObject(item,"Iswarning",cacheTab[i].iswarning);
cJSON_AddItemToArray(pJson,item);
}
return pJson;
}
//保存用户表到spiflash
void save_user_tab()
{
OS_CPU_SR cpu_sr = 0;
OS_ENTER_CRITICAL();
W25QXX_Write((u8*)&userTab,USERCONFIGTAB_ADDR,USERCONFIGTAB_SIZE);
OS_EXIT_CRITICAL();
}
//删除全部记录 user表
u8 userTab_delete_all_record(void)
{
memset(&userTab,0,(USERCONFIGTAB_SIZE));
return 0;
}
/**
* @name: 根据id fun reg regLen 获取缓存的下标
* @test: test font
* @msg:
* @param {type}
* @return:
*/
u16 get_cacheTab_index(u16 id,u8 fun,u16 reg,u16 regLen)
{
}
/**
* @name: 串口参数解析
* @msg: "9600,8,1,0" 解析出串口配置参数
* @param 串口字符串,字符串长度。解析的结果
* @return: 0成功 其他失败
*/
u8 parse_uartConfig_string(u8* string,u8 stringLen,u32* bps,u8* dataLen,u8* stopLen,u8* parity)
{
char *p0,*p1;
u8 i;
u8 endChar=string[stringLen-1];
if(string == NULL)return 1;
string[stringLen-1]=',';//最后一位 我手动加一个逗号
p0 = (char*)string;
//取出参数
for(i=0;i<4;i++)
{
p1 = strstr(p0,",");
*p1=0;//结束
if(p0 != NULL)
{
if(i==0)*bps = atoi(p0);
else if(i==1)*dataLen = atoi(p0);
else if(i==2)*stopLen = atoi(p0);
else if(i==3)*parity = atoi(p0);
*p1=',';//用完再恢复
p0=p1+1;
}
else
{
string[stringLen-1]=endChar;
return 1;
}
}
string[stringLen-1]=endChar;
return 0;
}
转换出来的json字符串如下:
{
"Root": {
"Variable": [{
"Id": 1,
"Isuse": true,
"Interfac": 0,
"Commid": 13,
"Uart_params": "4800,8,1,0",
"Timeout": 100,
"Model": "WS-N01-5-LCD",
"Note": "液晶温湿度",
"Warning_params": {
"Type": 0,
"Valtype": 0,
"Valueint": 0
},
"Linkage_params": {
"Do0": false,
"Dt0": 1,
"Do1": false,
"Dt1": 0,
"Do2": false,
"Dt2": 0,
"Do3": false,
"Dt3": 0
},
"Amt_params": {
"Type": 1,
"Tag": "湿度",
"Fun": 3,
"Reg_addr": 0,
"Reg_len": 1,
"Unit": "%",
"Modulus": {
"Type": 2,
"Valuefloat": 0.100000
}
}
}, {
"Id": 2,
"Isuse": true,
"Interfac": 0,
"Commid": 13,
"Uart_params": "4800,8,1,0",
"Timeout": 100,
"Model": "01-5-LCD",
"Note": "液晶温湿度",
"Warning_params": {
"Type": 0,
"Valtype": 0,
"Valueint": 0
},
"Linkage_params": {
"Do0": false,
"Dt0": 0,
"Do1": false,
"Dt1": 0,
"Do2": false,
"Dt2": 0,
"Do3": false,
"Dt3": 0
},
"Amt_params": {
"Type": 1,
"Tag": "温度",
"Fun": 3,
"Reg_addr": 1,
"Reg_len": 1,
"Unit": "℃",
"Modulus": {
"Type": 2,
"Valuefloat": 0.100000
}
}
}]
}
}
5.splitContainer的间隔如何减小?
修改SplitterWidth=1即可
如果lable标签的Dock属性设置为fill,还是无法填满这个panel的话,肯定是autoSize属性没有设置为false
6.设置DataGridView单元格的内容居中显示
DaatGridView.RowsDefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleCenter;
7.列名称根据数据源的顺序
dataGridView1.AutoGenerateColumns = false;
8.datagridview显示绑定数据源的某几个属性的方法
https://blog.csdn.net/weixin_33878457/article/details/93605504
9.datagridview相关设置
禁止编辑单元格 readOnle=true即可
修改行高 e.Row.Cells[i].Height = 20;
选中一行 DataGridViewSelectionMode.FullRowSelect;//设置为整行被选中码
修改行背景颜色 this.dgvCache.Rows[row].DefaultCellStyle.BackColor = color;
修改单元格背景颜色 this.dgvCache.Rows[row].Cells[cell].Style.BackColor = color;
清空数据源,但是保留表头:
//保留表头
try
{
DataTable dt_xx = (DataTable)dgvCache.DataSource;
dt_xx.Rows.Clear();
dgvCache.DataSource = dt_xx;
}
catch (Exception)
{
}
//this.dgvCache.DataSource = null;//不要使用这个