#include "lora.h"


LoRaParameter LoRaSetData = {            //模块工作参数
  0x00,                                //模块地址高字节
  0x00,                                //模块地址低字节
  0x01,                                //模块网络地址
  LoRa_9600,                           //模块串口 波特率 9600
  LoRa_8N1,                            //串口工作模式 8数据位 无校验 1停止位
  LoRa_38_4,                           //模块空中速率 38.4K
  LoRa_Data240,                        //数据分包大小 240字节
  LoRa_RssiDIS,                        //关闭RSSI功能
  LoRa_FEC_22DBM,                      //发射功率22dbm
  LoRa_CH23,                           //模块信道
  LoRa_RssiByteDIS,                    //禁用RSSI字节功能
  LoRa_ModePOINT,                      //定点模式
  LoRa_RelayDIS,                       //禁用中继模式
  LoRa_LBTEN,                          //使能LBT
  LoRa_WorTX,                          //Wor模式发送        只在模式1才有效
  LoRa_Wor2000ms,                      //Wor周期2000毫秒    只在模式1才有效
  0x22,                                //模块加密秘钥高字节
  0x33,                                //模块加密秘钥低字节
};


//LoRA模块引脚初始化
void loraGpioInit(void) {
  GPIO_InitTypeDef GPIO_InitStruct = {0};
	
	GPIOA_RCC_ENABLE;
  GPIOB_RCC_ENABLE;
	GPIOC_RCC_ENABLE;

  GPIO_InitStruct.Pin  = LORA_AUX_Pin;          //忙检测引脚
  GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
  GPIO_InitStruct.Pull = GPIO_PULLUP;
  HAL_GPIO_Init(LORA_AUX_Port, &GPIO_InitStruct);

  GPIO_InitStruct.Pin  = LORA_POW_Pin ;         //电源控制引脚
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
  HAL_GPIO_Init(LORA_POW_Port, &GPIO_InitStruct);

  GPIO_InitStruct.Pin  = LORA_M0_Pin ;          //M0引脚
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
  HAL_GPIO_Init(LORA_M0_Port, &GPIO_InitStruct);

  GPIO_InitStruct.Pin  = LORA_M1_Pin ;          //M1引脚
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
  HAL_GPIO_Init(LORA_M1_Port, &GPIO_InitStruct);

  LoRa_MODE2;                                   //模块模式2
  HAL_Delay(200);                               //适当延时
}
/*-------------------------------------------------*/
/*函数名：LoRa上电复位                             */
/*参  数：timeout：超时时间                        */
/*返回值：0：正确   其他：错误                     */
/*-------------------------------------------------*/
uint8_t loraReset(int16_t timeout) {
  LoRa_PowerOFF;                  //先关闭电源
  HAL_Delay(200);                 //延时
  LoRa_PowerON;                   //再打开电源

  while(timeout--) {              //等待复位成功
    HAL_Delay(100);             //延时100ms
    if(LoRa_AUX==1)             //需要等到高电平1，才能跳出while，表示复位完毕
      break;       			//主动跳出while循环
    u1_printf("%d ",timeout);   //串口输出现在的超时时间
  }
  u1_printf("\r\n");              //串口输出信息
  if(timeout<=0)return 1;         //如果timeout<=0，说明超时时间到了，也没能等到LoRa_AUX高电平，返回1
  return 0;                       //正确，返回0
}
/*-------------------------------------------------*/
/*函数名：初始化模块                               */
/*参  数：无                                       */
/*返回值：无                                       */
/*-------------------------------------------------*/
void loraInit(void) {
  loraGpioInit();                                 //Lora模块引脚初始化
  u1_printf("准备复位Lora模块\r\n");   	          //串口输出信息
  if(loraReset(100)) {                             //复位Lora模块，返回值如果非零，表示错误
    u1_printf("复位Lora模块失败，重启\r\n");   	  //串口输出信息
    NVIC_SystemReset();                           //重启
  } else u1_printf("Lora模块复位成功\r\n");   	      //串口输出信息
  u1_printf("准备设置Lora模块\r\n");   	          //串口输出信息
  loraSet();                                       //设置Lora模块
  HAL_Delay(200);                                   //延时
}

/*-------------------------------------------------*/
/*函数名：LoRa设置工作参数                         */
/*参  数：无                                       */
/*返回值：无                                       */
/*-------------------------------------------------*/
void loraSet(void) {
  uint8_t cmd[12];                                         //保存设置参数的数组缓冲区，命令共计12字节

  cmd[0] = 0xC0;                                           //设置参数指令的起始字节，固定值0xC0
  cmd[1] = 0x00;                                           //设置参数的起始寄存器地址，从寄存器0开始设置，一共9个
  cmd[2] = 0x09;                                           //一共设置9个寄存器
  cmd[3] = LoRaSetData.LoRa_AddrH;                         //设置模块地址高字节
  cmd[4] = LoRaSetData.LoRa_AddrL;                         //设置模块地址低字节
  cmd[5] = LoRaSetData.LoRa_NetID;                         //设置模块网络地址
  cmd[6] = LoRaSetData.LoRa_Baudrate | LoRaSetData.LoRa_UartMode | LoRaSetData.LoRa_airvelocity;    //设置模块 波特率 串口模式 空中速率
  cmd[7] = LoRaSetData.LoRa_DataLen | LoRaSetData.LoRa_Rssi | LoRaSetData.LoRa_TxPower;             //设置模块 数据分包长度 RSSI噪声是否使能 发射功率
  cmd[8] = LoRaSetData.LoRa_CH;                            //设置模块信道
  cmd[9] = LoRaSetData.LoRa_RssiByte | LoRaSetData.LoRa_DateMode | LoRaSetData.LoRa_Relay | LoRaSetData.LoRa_LBT | LoRaSetData.LoRa_WORmode | LoRaSetData.LoRa_WORcycle; //设置模块 是否使用RSSI字节功能 传输方式 是否中继 是否使用LBT WOR模式收发控制 WOR周期
  cmd[10] = LoRaSetData.LoRa_KeyH;                         //设置模块加密秘钥高字节
  cmd[11] = LoRaSetData.LoRa_KeyL;                         //设置模块加密秘钥低字节
  u3_TxDataBuf(cmd,12);                                    //发送缓冲区加入数据
}
/*-------------------------------------------------*/
/*函数名：LoRa查询工作参数                         */
/*参  数：data：工作参数数据                       */
/*返回值：无                                       */
/*-------------------------------------------------*/
void loraGet(uint8_t *data) {
  uint8_t ch;                                                          //保存信道的变量

  u1_printf("模块地址:0x%02X%02X\r\n",data[3],data[4]);                //串口输出信息
  u1_printf("模块网络ID:0x%02X\r\n",data[5]);                          //串口输出信息

  switch(data[6]&0xE0) {                                               //判断串口波特率
  case LoRa_1200 :
    u1_printf("波特率 1200\r\n");                   //串口输出信息
    break;                                          //跳出
  case LoRa_2400 :
    u1_printf("波特率 2400\r\n");                   //串口输出信息
    break;                                          //跳出
  case LoRa_4800 :
    u1_printf("波特率 4800\r\n");                   //串口输出信息
    break;                                          //跳出
  case LoRa_9600 :
    u1_printf("波特率 9600\r\n");                   //串口输出信息
    break;                                          //跳出
  case LoRa_19200 :
    u1_printf("波特率 19200\r\n");                 //串口输出信息
    break;                                          //跳出
  case LoRa_38400 :
    u1_printf("波特率 38400\r\n");                 //串口输出信息
    break;                                          //跳出
  case LoRa_57600 :
    u1_printf("波特率 57600\r\n");                 //串口输出信息
    break;                                          //跳出
  case LoRa_115200:
    u1_printf("波特率 115200\r\n");                //串口输出信息
    break;                                          //跳出
  }
  switch(data[6]&0x18) {                                               //判断串口参数
  case LoRa_8N1 :
    u1_printf("8数据位 无校验 1停止位\r\n");        //串口输出信息
    break;                                          //跳出
  case LoRa_8O1 :
    u1_printf("8数据位 奇校验 1停止位\r\n");        //串口输出信息
    break;                                          //跳出
  case LoRa_8E1 :
    u1_printf("8数据位 偶校验 1停止位\r\n");        //串口输出信息
    break;                                          //跳出
  }
  switch(data[6]&0x07) {                                               //判断空中速率
  case LoRa_0_3 :
    u1_printf("空中速率 0.3K\r\n");                 //串口输出信息
    break;                                          //跳出
  case LoRa_1_2 :
    u1_printf("空中速率 1.2K\r\n");                 //串口输出信息
    break;                                          //跳出
  case LoRa_2_4 :
    u1_printf("空中速率 2.4K\r\n");                 //串口输出信息
    break;                                          //跳出
  case LoRa_4_8 :
    u1_printf("空中速率 4.8K\r\n");                 //串口输出信息
    break;                                          //跳出
  case LoRa_9_6 :
    u1_printf("空中速率 9.6K\r\n");                 //串口输出信息
    break;                                          //跳出
  case LoRa_19_2 :
    u1_printf("空中速率 19.2K\r\n");                //串口输出信息
    break;                                          //跳出
  case LoRa_38_4 :
    u1_printf("空中速率 38.4K\r\n");                //串口输出信息
    break;  		                                 //跳出
  case LoRa_62_5 :
    u1_printf("空中速率 62.5K\r\n");                //串口输出信息
    break;  		                                 //跳出
  }
  switch(data[7]&0xC0) {                                               //判断数据分包大小
  case LoRa_Data240 :
    u1_printf("数据分包大小：240字节\r\n");      //串口输出信息
    break;                                       //跳出
  case LoRa_Data128 :
    u1_printf("数据分包大小：128字节\r\n");      //串口输出信息
    break;                                       //跳出
  case LoRa_Data64  :
    u1_printf("数据分包大小：64字节\r\n");       //串口输出信息
    break;                                       //跳出
  case LoRa_Data32  :
    u1_printf("数据分包大小：32字节\r\n");       //串口输出信息
    break;                                       //跳出
  }
  switch(data[7]&0x20) {                                               //判断是否启用RSSI功能
  case LoRa_RssiEN  :
    u1_printf("启用RSSI功能\r\n");               //串口输出信息
    break;                                       //跳出
  case LoRa_RssiDIS :
    u1_printf("禁用RSSI功能\r\n");               //串口输出信息
    break;                                       //跳出
  }
  switch(data[7]&0x03) {                                               //判断发射功率
  case LoRa_FEC_22DBM :
    u1_printf("发射功率 22dbm\r\n");          //串口输出信息
    break;                                    //跳出
  case LoRa_FEC_17DBM :
    u1_printf("发射功率 17dbm\r\n");          //串口输出信息
    break;                                    //跳出
  case LoRa_FEC_13DBM :
    u1_printf("发射功率 13dbm\r\n");          //串口输出信息
    break;                                    //跳出
  case LoRa_FEC_10DBM :
    u1_printf("发射功率 10dbm\r\n");          //串口输出信息
    break;                                    //跳出
  }

  ch = data[8] & 0x7F;                                                 //保存信道
  u1_printf("信道:0x%02X  对应频率%dMHz\r\n",ch,410+ch);               //串口输出信息

  switch(data[9]&0x80) {                                               //判断RSSI字节功能
  case LoRa_RssiByteEN  :
    u1_printf("启用RSSI字节功能\r\n");       //串口输出信息
    break;                                   //跳出
  case LoRa_RssiByteDIS :
    u1_printf("禁用RSSI字节功能\r\n");       //串口输出信息
    break;                                   //跳出
  }
  switch(data[9]&0x40) {                                               //判断传输模式
  case LoRa_ModeTRANS :
    u1_printf("透明传输\r\n");                //串口输出信息
    break;                                    //跳出
  case LoRa_ModePOINT :
    u1_printf("定点传输\r\n");                //串口输出信息
    break;                                    //跳出
  }
  switch(data[9]&0x20) {                                              //判断中继功能
  case LoRa_RelayEN  :
    u1_printf("启用中继\r\n");                //串口输出信息
    break;                                    //跳出
  case LoRa_RelayDIS :
    u1_printf("禁用中继\r\n");                //串口输出信息
    break;                                    //跳出
  }
  switch(data[9]&0x10) {                                              //判断LBT功能
  case LoRa_LBTEN  :
    u1_printf("启用LBT\r\n");                   //串口输出信息
    break;                                    //跳出
  case LoRa_LBTDIS :
    u1_printf("禁用LBT\r\n");                   //串口输出信息
    break;                                    //跳出
  }
//	switch(data[9]&0x08){                                               //判断WOR模式
//		case LoRa_WorTX  :  u1_printf("Wor模式发送\r\n");               //串口输出信息
//							  break;                                    //跳出
//		case LoRa_WorRX :  u1_printf("Wor模式接收\r\n");                //串口输出信息
//							  break;                                    //跳出
//	}
//	switch(data[9]&0x07){                                               //判断WOR周期
//		case LoRa_Wor500ms  : u1_printf("WOR周期时间 500毫秒\r\n");     //串口输出信息
//							  break;                                    //跳出
//		case LoRa_Wor1000ms : u1_printf("WOR周期时间 1000毫秒\r\n");    //串口输出信息
//							  break;                                    //跳出
//		case LoRa_Wor1500ms : u1_printf("WOR周期时间 1500毫秒\r\n");    //串口输出信息
//							  break;                                    //跳出
//		case LoRa_Wor2000ms : u1_printf("WOR周期时间 2000毫秒\r\n");    //串口输出信息
//							  break;                                    //跳出
//		case LoRa_Wor2500ms : u1_printf("WOR周期时间 2500毫秒\r\n");    //串口输出信息
//							  break;                                    //跳出
//		case LoRa_Wor3000ms : u1_printf("WOR周期时间 3000毫秒\r\n");    //串口输出信息
//							  break;                                    //跳出
//		case LoRa_Wor3500ms : u1_printf("WOR周期时间 3500毫秒\r\n");    //串口输出信息
//							  break;                                    //跳出
//		case LoRa_Wor4000ms : u1_printf("WOR周期时间 4000毫秒\r\n");    //串口输出信息
//							  break;                                    //跳出
//	}
}


/*-------------------------------------------------*/
/*函数名：串口3被动事件                            */
/*参  数：data ：数据                              */
/*参  数：datalen ：数据长度                       */
/*返回值：无                                       */
/*-------------------------------------------------*/
uint8_t tempdata[512];
void u3PassiveEvent(uint8_t *data, uint16_t datalen) {
  /*----------------------------------------------*/
  /*           接收设置LoRa模块返回数据           */
  /*----------------------------------------------*/
  if((data[0]==0xC1)&&(datalen==12)) {
    u1_printf("接收设置LoRa模块返回数据\r\n");        //串口输出信息
    loraGet(data);                                   //分析设置的参数
    LoRa_MODE0;                                       //切换到模式0
    HAL_Delay(200);                                   //延时
    catReset();                                    //4G模块重启
  }


  /*----------------------------------------------*/
  /*         接收到子设备x上发的证书信息          */
  /*----------------------------------------------*/
  if(datalen==(SUBMQTTINFO_STRUCT_LEN+1)) { //收到符合长度的数据
    switch (data[0]) {
    case CERT1_DATA:
      subDeviceReportingCertificate(0,data);
      break;
    case CERT2_DATA:
      subDeviceReportingCertificate(1,data);
      break;
    case CERT3_DATA:
      subDeviceReportingCertificate(2,data);
      break;
    case CERT4_DATA:
      subDeviceReportingCertificate(3,data);
      break;
    case CERT5_DATA:
      subDeviceReportingCertificate(4,data);
      break;
    case CERT6_DATA:
      subDeviceReportingCertificate(5,data);
      break;
    case CERT7_DATA:
      subDeviceReportingCertificate(6,data);
      break;
    case CERT8_DATA:
      subDeviceReportingCertificate(7,data);
      break;
    case CERT9_DATA:
      subDeviceReportingCertificate(8,data);
      break;
    case CERT10_DATA:
      subDeviceReportingCertificate(9,data);
      break;
    default :
      break;
    }
    u1_printf("***收到子设备数据，线程结束...\r\n");
    taskRunning = 0;	//则退出
  }
	
  /*----------------------------------------------*/
  /*      接收到子设备x上发的数据         */
  /*----------------------------------------------*/
  if(datalen==(ATTRIBUTE_STRUCT_LEN+1)) { //收到符合长度的数据
    switch (data[0]) {
    case SUB1_DATA:
      subDeviceReportingSwitchStatus(0,data);
      break;
    case SUB2_DATA:
      subDeviceReportingSwitchStatus(1,data);
      break;
    case SUB3_DATA:
      subDeviceReportingSwitchStatus(2,data);
      break;
    case SUB4_DATA:
      subDeviceReportingSwitchStatus(3,data);
      break;
    case SUB5_DATA:
      subDeviceReportingSwitchStatus(4,data);
      break;
    default :
      break;
    }
    u1_printf("***收到子设备数据，线程结束...\r\n");
    taskRunning = 0;	//则退出
  }	
	
}


//子设备上报证书信息至云平台  推送   参数说明： sub_num 子设备序号 0表示设备1...
void subDeviceReportingCertificate(uint8_t sub_num,uint8_t *data) {
  u1_printf("接收到子设备%d证书信息。\r\n",sub_num + 1);
  memcpy(&SubMqttInfo_Struct[sub_num],&data[1],SUBMQTTINFO_STRUCT_LEN);              //临时缓冲区全部清零
  CAT1_printf("AT+MPUB=\"/iot/sub/live/post/%s\",0,0,\"{\\22header\\22:\\22iot.sub.live.post\\22,\\22version\\22:\\221.0\\22,\\22body\\22:{\\22online\\22:[{\\22uid\\22:\\22%s\\22,\\22secret\\22:\\22%s\\22}]}}\"\r\n",
              GwMqttInfo_Struct.ClientID,
              SubMqttInfo_Struct[sub_num].ClientID,
              SubMqttInfo_Struct[sub_num].Passward);

  u1_printf("子设备%d的uid：%s,secret：%s\r\n",
            sub_num + 1,
            SubMqttInfo_Struct[sub_num].ClientID,
            SubMqttInfo_Struct[sub_num].Passward);
  SUB_DEVICE_ON[sub_num] = 1;//子设备上线标志位置一
}


//子设备上报开关状态至云平台  推送   参数说明： sub_num 子设备序号 0表示设备1...

void subDeviceReportingSwitchStatus(uint8_t sub_num,uint8_t *data) {
  u1_printf("接收到子设备%d的数据。\r\n",sub_num + 1);

  memcpy(&SubAttribute_Struct[sub_num],&data[1],ATTRIBUTE_STRUCT_LEN);                   //拷贝数据
	
				u1_printf("* * * * *准备上传设备电量，温度，大气压强，环境温湿度* * * * *\r\n");

/*
BAT_VAL  电池电量
DEV_TP   设备温度
DEV_RES  设备重启次数
BS_RH    大气湿度
BS_T     大气温度
BS_DO    大气压强

SOIL_RH   土壤湿度
SOIL_TP   土壤温度
YSMD_RH   叶面湿度
YSMD_TP   叶面温度
BY_HV     百叶箱光照
BY_CO2    百叶箱二氧化碳

SOIL_NV   土壤氮
SOIL_PV   土壤磷
SOIL_KV   土壤钾
SOIL_PH   土壤PH  
SOIL_RV   土壤电导率 
SIGNAL    信号强度 
*/


				CAT1_printf("AT+MPUB=\"/iot/sub/prop/post/%s\",0,0,\"{\\22header\\22:\\22iot.sub.prop.post\\22,\\22version\\22:\\221.0\\22,\\22body\\22:{\\22subs\\22:[{\\22uid\\22:\\22%s\\22,\\22props\\22:{\\22BAT_VAL\\22:%d,\\22DEV_TP\\22:%.1f,\\22DEV_RES\\22:%d,\\22BS_RH\\22:%.1f,\\22BS_T\\22:%.1f,\\22BS_DO\\22:%.1f}}]}}\"\r\n",
								GwMqttInfo_Struct.ClientID,
								SubMqttInfo_Struct[sub_num].ClientID,
								SubAttribute_Struct[sub_num].Sub_BAT,
								SubAttribute_Struct[sub_num].Device_Temp,
								SubAttribute_Struct[sub_num].Res_Count,
								SubAttribute_Struct[sub_num].Envir_PressHumi,
								SubAttribute_Struct[sub_num].Envir_PressTemp,
								SubAttribute_Struct[sub_num].Envir_Press);//回复数据	
HAL_Delay(1000);			
				u1_printf("* * * * *准备上传叶面温湿度，土壤温湿度,环境光照强度，二氧化碳含量 * * * * *\r\n");
				CAT1_printf("AT+MPUB=\"/iot/sub/prop/post/%s\",0,0,\"{\\22header\\22:\\22iot.sub.prop.post\\22,\\22version\\22:\\221.0\\22,\\22body\\22:{\\22subs\\22:[{\\22uid\\22:\\22%s\\22,\\22props\\22:{\\22SOIL_RH\\22:%.1f,\\22SOIL_TP\\22:%.1f,\\22YSMD_RH\\22:%.1f,\\22YSMD_TP\\22:%.1f,\\22BY_HV\\22:%d,\\22BY_CO2\\22:%d}}]}}\"\r\n",
								GwMqttInfo_Struct.ClientID,
								SubMqttInfo_Struct[sub_num].ClientID,
								SubAttribute_Struct[sub_num].Soil_Humi,
								SubAttribute_Struct[sub_num].Soil_Temp,
								SubAttribute_Struct[sub_num].Leaf_Humi,
								SubAttribute_Struct[sub_num].Leaf_Temp,
								SubAttribute_Struct[sub_num].Envir_Light,
								SubAttribute_Struct[sub_num].Envir_Co2);//回复数据	
HAL_Delay(1000);
			 u1_printf("* * * * *准备上传土壤氮磷钾含量，土壤PH，土壤电导率，子设备信号强度* * * * *\r\n");
			CAT1_printf("AT+MPUB=\"/iot/sub/prop/post/%s\",0,0,\"{\\22header\\22:\\22iot.sub.prop.post\\22,\\22version\\22:\\221.0\\22,\\22body\\22:{\\22subs\\22:[{\\22uid\\22:\\22%s\\22,\\22props\\22:{\\22SOIL_NV\\22:%d,\\22SOIL_PV\\22:%d,\\22SOIL_KV\\22:%d,\\22SOIL_PH\\22:%.1f,\\22SOIL_RV\\22:%d,\\22SIGNAL\\22:%d}}]}}\"\r\n",
								GwMqttInfo_Struct.ClientID,
								SubMqttInfo_Struct[sub_num].ClientID,
								SubAttribute_Struct[sub_num].Soil_NV,
								SubAttribute_Struct[sub_num].Soil_PV,
								SubAttribute_Struct[sub_num].Soil_KV,
								SubAttribute_Struct[sub_num].Soil_PH,
								SubAttribute_Struct[sub_num].Soil_EC,
								SubAttribute_Struct[sub_num].SIGNAL_STRENGTH);//回复数据
		
		u1_printf("子设备重启次数:%d\r\n",SubAttribute_Struct[sub_num].Res_Count); 
		u1_printf("设备温度： %.1f'C\r\n",SubAttribute_Struct[sub_num].Device_Temp);
		u1_printf("电池电量为:%d %%\r\n",SubAttribute_Struct[sub_num].Sub_BAT);  //串口输出
		u1_printf("环境湿度：%.2f%%RH，温度：%.2f'C,大气压强：%.2fKpa\r\n",SubAttribute_Struct[sub_num].Envir_PressHumi,SubAttribute_Struct[sub_num].Envir_PressTemp,SubAttribute_Struct[sub_num].Envir_Press);
		u1_printf("叶面湿度：%.2f%%RH，温度：%.2f'C\r\n",SubAttribute_Struct[sub_num].Leaf_Humi,SubAttribute_Struct[sub_num].Leaf_Temp);
		u1_printf("土壤湿度：%.2f%%RH，温度：%.2f'C\r\n",SubAttribute_Struct[sub_num].Soil_Humi,SubAttribute_Struct[sub_num].Soil_Temp);
		u1_printf("土壤氮含量：%dmg/kg，磷含量：%dmg/kg，钾含量：%dmg/kg\r\n",SubAttribute_Struct[sub_num].Soil_NV,SubAttribute_Struct[sub_num].Soil_PV,SubAttribute_Struct[sub_num].Soil_KV);
		u1_printf("土壤酸碱度：%.2f\r\n",SubAttribute_Struct[sub_num].Soil_PH);
		u1_printf("土壤电导率：%duS/cm\r\n",SubAttribute_Struct[sub_num].Soil_EC);

}

