c#上位机开发总结

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;
  1. 如何获取list ?
    这个集合是从单片机获取的,那么单片机的数据结构里没有集合,只有结构体
    结构体 —> 集合
    集合也没有协议规定啊,怎么转换呢?所以需要一个协议或者格式把结构体转换一下
    结构体 —> json/xml —> 集合
  2. 单片机端何如使用 json/xml
    xml的解析可以使用mxml(开源xml解析器)
    json解析可以使用cjson,我感觉json更简单,所以我选择json
  3. 单片机发送json到上位机
    单片机把结构体数组转换为json字符串(json中也是有数组概念的)进行传输,传输json文件也可以,因为这个是需要保存的,系统上电的时候把这个文件读到ram里面,然后应用程序需要使用里面的数据。话说字符串传输和文件传输也没啥区别。。。
  4. 上位机将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;//不要使用这个
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值