rs485.c 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005
  1. /*
  2. * Copyright (c) 2006-2021, RT-Thread Development Team
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Change Logs:
  7. * Date Author Notes
  8. * 2024-09-10 RuoFeng the first version
  9. */
  10. /*********************↓ define ↓************************/
  11. #define DBG_ENABLE
  12. #define DBG_COLOR
  13. #define DBG_TAG "rs"
  14. #define DBG_LEVEL DBG_LOG
  15. #include <rtdbg.h>
  16. #define LOG_INR 10 // 默认的log打印间隔(作用域在本文件)
  17. /*********************↑ define ↑************************/
  18. /**
  19. *
  20. *
  21. *
  22. *
  23. * */
  24. /*********************↓ include ↓************************/
  25. #include "rs485.h"
  26. #include "string.h"
  27. #include "control.h"
  28. #include "Work_XCT.h"
  29. #include <easyflash.h>
  30. /*********************↑ include ↑************************/
  31. /**
  32. *
  33. *
  34. *
  35. *
  36. * */
  37. /*********************↓ extern ↓************************/
  38. extern void HMI_WRITE(char *fmt, ...);
  39. extern uint8_t ef_cfged;
  40. extern Limit limit;
  41. extern Device_Status_typedef device_status;
  42. extern Sunwork swork;
  43. extern SYSCFG syscfg;
  44. extern void Get_SunTime(void);
  45. extern void CollFanSetPWM(uint8_t percent);
  46. /*********************↑ extern ↑************************/
  47. /**
  48. *
  49. *
  50. *
  51. *
  52. * */
  53. /********************↓ declaration ↓***********************/
  54. /********************↑ declaration ↑***********************/
  55. /**
  56. *
  57. *
  58. *
  59. *
  60. * */
  61. /*********************↓ global variables ↓************************/
  62. UART_HandleTypeDef huart5;
  63. uint8_t aRxBuffer[6] = {0};
  64. uint8_t rs_buf_cnt = 0;
  65. uint8_t rs_buf_fis = 0;
  66. uint8_t rs_buf[rs_buf_max] = {0};
  67. Sensor sensor[MAX_SENSOR_NUM] = {0};
  68. uint16_t Read_data[MAX_SENSOR_NUM * 2] = {0};
  69. volatile uint8_t sex_enread = 0;
  70. uint8_t up_time = 0;
  71. uint8_t up_limit = 0;
  72. /*********************↑ global variables ↑************************/
  73. /**
  74. *
  75. *
  76. *
  77. *
  78. * */
  79. /**
  80. * @brief 清缓存
  81. *
  82. */
  83. void clear_rsbuf(void)
  84. {
  85. rs_buf_fis = 0;
  86. rs_buf_cnt = 0;
  87. memset(rs_buf, 0, sizeof(rs_buf));
  88. }
  89. /**
  90. * @brief 纯手工crc16算法 冰冰凉 嘎嘎好使
  91. *
  92. * @param data 数据位
  93. * @param len 长度
  94. * @return unsigned int CRC
  95. */
  96. unsigned int ModBusCRC16(unsigned char *data, unsigned int len)
  97. {
  98. unsigned int i, j, tmp, CRC16;
  99. CRC16 = 0xFFFF; // CRC寄存器初始值
  100. for (i = 0; i < len; i++)
  101. {
  102. CRC16 ^= data[i];
  103. for (j = 0; j < 8; j++)
  104. {
  105. tmp = (unsigned int)(CRC16 & 0x0001);
  106. CRC16 >>= 1;
  107. if (tmp == 1)
  108. {
  109. CRC16 ^= 0xA001; // 异或多项式
  110. }
  111. }
  112. }
  113. i = (CRC16 & 0x00FF) << 8; // 反向
  114. CRC16 = (CRC16 & 0xFF00) >> 8;
  115. CRC16 |= i;
  116. return CRC16;
  117. }
  118. /*
  119. *********************************************************************************************************
  120. * 函 数 名: BEBufToUint16
  121. * 功能说明: 将2字节数组(大端Big Endian次序,高字节在前)转换为16位整数
  122. * 形 参: _pBuf : 数组
  123. * 返 回 值: 16位整数值
  124. *
  125. * 大端(Big Endian)与小端(Little Endian)
  126. *********************************************************************************************************
  127. */
  128. uint16_t BEBufToUint16(uint8_t *_pBuf)
  129. {
  130. return (((uint16_t)_pBuf[0] << 8) | _pBuf[1]);
  131. }
  132. /**
  133. * @brief 读03寄存器
  134. *
  135. * @param slaveAddr 地址
  136. * @param _reg 起始
  137. * @param _num 长度
  138. * @param sort 页码
  139. * @return Res_def 结果
  140. */
  141. Res_def MODH_ReadParam_03H(uint8_t slaveAddr, uint16_t _reg, uint16_t _num, uint8_t sort)
  142. {
  143. uint8_t buf[8] = {0};
  144. if (slaveAddr == 0 || slaveAddr > 255)
  145. {
  146. return res_Error;
  147. }
  148. buf[0] = slaveAddr;
  149. buf[1] = 0x03;
  150. buf[2] = (uint8_t)(_reg >> 8);
  151. buf[3] = (uint8_t)(_reg & 0xFF);
  152. buf[4] = (uint8_t)(_num >> 8);
  153. buf[5] = (uint8_t)(_num & 0xFF);
  154. buf[6] = (uint8_t)(ModBusCRC16(buf, 6) >> 8);
  155. buf[7] = (uint8_t)(ModBusCRC16(buf, 6) & 0xFF);
  156. RS485_SEND(buf, 8);
  157. rt_thread_mdelay(390);
  158. if (rs_buf_fis != 1 || rs_buf_cnt < 6)
  159. {
  160. clear_rsbuf();
  161. return res_Timeout;
  162. }
  163. uint16_t CRC16 = ModBusCRC16(rs_buf, rs_buf_cnt - 2);
  164. if (CRC16 != (uint16_t)(rs_buf[rs_buf_cnt - 2] << 8 | rs_buf[rs_buf_cnt - 1]))
  165. {
  166. clear_rsbuf();
  167. rt_kprintf("CRC Check faild > %04X %02X%02X", CRC16, rs_buf[rs_buf_cnt - 2], rs_buf[rs_buf_cnt - 1]);
  168. return res_Verifi;
  169. }
  170. if (rs_buf[0] != sensor[sort].sensor_addr)
  171. {
  172. clear_rsbuf();
  173. rt_kprintf("SAddr check failed > %d - %d\n", rs_buf[0], sensor[sort].sensor_addr);
  174. return res_Verifi;
  175. }
  176. uint8_t *p;
  177. p = &rs_buf[3];
  178. if (rs_buf[2] == sensor[sort].count * 2)
  179. {
  180. for (uint8_t a = 1; a <= rs_buf[2]; a++)
  181. {
  182. if (a % 2 == 0)
  183. {
  184. Read_data[(a / 2) - 1] = BEBufToUint16(p);
  185. p += 2;
  186. }
  187. }
  188. }
  189. else
  190. {
  191. rt_kprintf("Return cnt check fail > %d \n", rs_buf[2]);
  192. return res_Verifi;
  193. }
  194. clear_rsbuf();
  195. return res_OK;
  196. }
  197. /**
  198. * @brief 获取数值的位数
  199. *
  200. * @param val 数值
  201. * @return uint8_t 返回位数
  202. */
  203. uint8_t GetValueLen(int32_t val)
  204. {
  205. uint8_t cnt = 1;
  206. int32_t m = val;
  207. while (m > 9)
  208. {
  209. m /= 10;
  210. cnt++;
  211. }
  212. // rt_kprintf("%d is %d len\n",val , cnt);
  213. return cnt;
  214. }
  215. /**
  216. * @brief 给定val和factor 生成eval
  217. *
  218. * @param val 原始数据
  219. * @param factor 因数
  220. * @param eval eval的指针
  221. */
  222. void GenerateValue(int16_t val, int factor, char *eval)
  223. {
  224. // rt_kprintf("val %d \n", val);
  225. if (val == 0x7FFF)
  226. {
  227. rt_sprintf(eval, "-99.99");
  228. return;
  229. }
  230. if (factor > 0)
  231. {
  232. rt_sprintf((char *)eval, "%d", val * factor);
  233. }
  234. else if (factor < 0)
  235. {
  236. switch (GetValueLen(abs(factor)))
  237. {
  238. // 当负的单位数 不做处理
  239. case 1:
  240. {
  241. }
  242. break;
  243. // 当负的两位数 例如-10
  244. case 2:
  245. {
  246. if (val >= 0)
  247. {
  248. rt_sprintf((char *)eval, "%d.%01d", val / abs(factor), val % abs(factor));
  249. }
  250. else
  251. {
  252. rt_sprintf((char *)eval, "-%d.%01d", abs(val) / abs(factor), abs(val) % abs(factor));
  253. }
  254. }
  255. break;
  256. // 当负的三位数 例如-100
  257. case 3:
  258. {
  259. if (val >= 0)
  260. {
  261. rt_sprintf((char *)eval, "%d.%02d", val / abs(factor), val % abs(factor));
  262. }
  263. else
  264. {
  265. rt_sprintf((char *)eval, "-%d.%02d", abs(val) / abs(factor), abs(val) % abs(factor));
  266. }
  267. }
  268. break;
  269. // 当负的四位数 例如-1000 //flash不够了 4位小数先不考虑
  270. case 4:
  271. {
  272. if (val >= 0)
  273. {
  274. rt_sprintf((char *)eval, "%d.%03d", val / abs(factor), val % abs(factor));
  275. }
  276. else
  277. {
  278. rt_sprintf((char *)eval, "-%d.%03d", abs(val) / abs(factor), abs(val) % abs(factor));
  279. }
  280. }
  281. break;
  282. default:
  283. break;
  284. }
  285. }
  286. // 不对factor == 0的情况做处理
  287. // rt_kprintf("Gen %s\n",eval);
  288. }
  289. /**
  290. * @brief 给定val和factor 生成eval
  291. *
  292. * @param val 原始数据
  293. * @param factor 因数
  294. * @param eval eval的指针
  295. */
  296. void GenerateValue_32(int32_t val, int factor, char *eval)
  297. {
  298. // rt_kprintf("val %d \n", val);
  299. if (val == 0x7FFF)
  300. {
  301. rt_sprintf(eval, "-99.99");
  302. return;
  303. }
  304. if (factor > 0)
  305. {
  306. rt_sprintf((char *)eval, "%d", val * factor);
  307. }
  308. else if (factor < 0)
  309. {
  310. switch (GetValueLen(abs(factor)))
  311. {
  312. // 当负的单位数 不做处理
  313. case 1:
  314. {
  315. }
  316. break;
  317. // 当负的两位数 例如-10
  318. case 2:
  319. {
  320. if (val >= 0)
  321. {
  322. rt_sprintf((char *)eval, "%d.%01d", val / abs(factor), val % abs(factor));
  323. }
  324. else
  325. {
  326. rt_sprintf((char *)eval, "-%d.%01d", abs(val) / abs(factor), abs(val) % abs(factor));
  327. }
  328. }
  329. break;
  330. // 当负的三位数 例如-100
  331. case 3:
  332. {
  333. if (val >= 0)
  334. {
  335. rt_sprintf((char *)eval, "%d.%02d", val / abs(factor), val % abs(factor));
  336. }
  337. else
  338. {
  339. rt_sprintf((char *)eval, "-%d.%02d", abs(val) / abs(factor), abs(val) % abs(factor));
  340. }
  341. }
  342. break;
  343. // 当负的四位数 例如-1000 //flash不够了 4位小数先不考虑
  344. case 4:
  345. {
  346. if (val >= 0)
  347. {
  348. rt_sprintf((char *)eval, "%d.%03d", val / abs(factor), val % abs(factor));
  349. }
  350. else
  351. {
  352. rt_sprintf((char *)eval, "-%d.%03d", abs(val) / abs(factor), abs(val) % abs(factor));
  353. }
  354. }
  355. break;
  356. default:
  357. break;
  358. }
  359. }
  360. // 不对factor == 0的情况做处理
  361. // rt_kprintf("Gen %s\n",eval);
  362. }
  363. /**
  364. *
  365. *
  366. * READ_MODBUS_DATA_1()
  367. * 该函数可根据sensor中存放的传感器参数 自动进行解析和运算
  368. * 并将结果组包为字符串 存于sensor[a].eValue
  369. * 若读取失败 evalue使用 -99.99填充 平台显示N/A
  370. *
  371. *
  372. */
  373. int8_t READ_MODBUS_DATA_1(Sensor_Read_Type srt)
  374. {
  375. uint16_t log_en_inr = LOG_INR; // 打印log的速度 数值越小 打印越频繁
  376. static int16_t log_en_cnt = -1;
  377. if (srt >= s_TypeMAX)
  378. {
  379. return -1;
  380. }
  381. int8_t res = 0;
  382. uint8_t en_log = 0;
  383. if (chk_log_time)
  384. {
  385. en_log = 1;
  386. }
  387. if (srt == s_ALL)
  388. {
  389. for (uint8_t a = 0; a < MAX_SENSOR_NUM; a++)
  390. {
  391. if (sensor[a].cfged == 1)
  392. {
  393. sensor[a].value = 0;
  394. // rt_kprintf("start Read %s\n" , sensor[a].eName);
  395. if (sensor[a].online == 0)
  396. {
  397. rt_sprintf(sensor[a].eValue, "-99.99");
  398. }
  399. if (MODH_ReadParam_03H(sensor[a].sensor_addr, sensor[a].start_reg, sensor[a].count, a) == res_OK)
  400. {
  401. // rt_kprintf("res %X \n", Read_data[0]);
  402. for (uint8_t b = 0; b < sensor[a].d_length; b++)
  403. {
  404. sensor[a].value += Read_data[sensor[a].d_pos + b] << ((sensor[a].d_length - 1 - b) * 16);
  405. }
  406. memset(sensor[a].eValue, 0, sizeof(sensor[a].eValue));
  407. // 使用新算法对eval进行生成
  408. if (sensor[a].d_length == 1)
  409. {
  410. GenerateValue(sensor[a].value, sensor[a].factor, (char *)sensor[a].eValue); // 16位整型
  411. }
  412. else
  413. {
  414. GenerateValue_32(sensor[a].value, sensor[a].factor, (char *)sensor[a].eValue); // 32位整型
  415. }
  416. if (en_log || 1)
  417. rt_kprintf("%s %s / ", sensor[a].eName, sensor[a].eValue);
  418. sensor[a].online = 2;
  419. res++;
  420. }
  421. else
  422. {
  423. if (en_log || 1)
  424. rt_kprintf("s%d %s × ", a, sensor[a].eName);
  425. if (sensor[a].online > 0)
  426. {
  427. sensor[a].online--;
  428. rt_kprintf("%s -- \n", sensor[a].eName);
  429. }
  430. }
  431. }
  432. // rt_thread_mdelay(500); // 每个要素结束的间隔
  433. memset(Read_data, 0, sizeof(Read_data));
  434. rt_thread_mdelay(1000);
  435. }
  436. }
  437. else
  438. {
  439. if (sensor[srt].cfged == 1)
  440. {
  441. sensor[srt].value = 0;
  442. rt_sprintf(sensor[srt].eValue, "-99.99");
  443. if (MODH_ReadParam_03H(sensor[srt].sensor_addr, sensor[srt].start_reg, sensor[srt].count, srt) == res_OK)
  444. {
  445. for (uint8_t b = 0; b < sensor[srt].d_length; b++)
  446. {
  447. sensor[srt].value += Read_data[sensor[srt].d_pos + b] << ((sensor[srt].d_length - 1 - b) * 16);
  448. }
  449. memset(sensor[srt].eValue, 0, sizeof(sensor[srt].eValue));
  450. // 使用新算法对eval进行生成
  451. if (sensor[srt].d_length == 1)
  452. {
  453. GenerateValue(sensor[srt].value, sensor[srt].factor, (char *)sensor[srt].eValue); // 16位整型
  454. }
  455. else
  456. {
  457. GenerateValue_32(sensor[srt].value, sensor[srt].factor, (char *)sensor[srt].eValue); // 32位整型
  458. }
  459. rt_kprintf("s%d %s %s ", srt, sensor[srt].eName, sensor[srt].eValue);
  460. sensor[srt].online = 1;
  461. }
  462. else
  463. {
  464. rt_kprintf("s%d %s × ", srt, sensor[srt].eName);
  465. sensor[srt].online = 0;
  466. res = 0;
  467. }
  468. }
  469. rt_thread_mdelay(1000); // 每个要素结束的间隔
  470. memset(Read_data, 0, sizeof(Read_data));
  471. }
  472. rt_kprintf("\n");
  473. return res;
  474. }
  475. void RS485_SEND(uint8_t *buf, uint16_t size)
  476. {
  477. HAL_UART_Transmit(&huart5, buf, size, 1000);
  478. }
  479. /* UART5 init function */
  480. void MX_UART5_Init(void)
  481. {
  482. /**UART5 GPIO Configuration
  483. PC12 ------> UART5_TX
  484. PD2 ------> UART5_RX
  485. */
  486. /* USER CODE BEGIN UART5_Init 0 */
  487. __HAL_RCC_GPIOC_CLK_ENABLE();
  488. __HAL_RCC_GPIOD_CLK_ENABLE();
  489. /* USER CODE END UART5_Init 0 */
  490. /* USER CODE BEGIN UART5_Init 1 */
  491. /* USER CODE END UART5_Init 1 */
  492. huart5.Instance = UART5;
  493. huart5.Init.BaudRate = 9600;
  494. huart5.Init.WordLength = UART_WORDLENGTH_8B;
  495. huart5.Init.StopBits = UART_STOPBITS_1;
  496. huart5.Init.Parity = UART_PARITY_NONE;
  497. huart5.Init.Mode = UART_MODE_TX_RX;
  498. huart5.Init.HwFlowCtl = UART_HWCONTROL_NONE;
  499. huart5.Init.OverSampling = UART_OVERSAMPLING_16;
  500. if (HAL_UART_Init(&huart5) != HAL_OK)
  501. {
  502. rt_kprintf("HAL_UART_Init(&huart5) failed\n");
  503. Error_Handler();
  504. }
  505. /* USER CODE BEGIN UART5_Init 2 */
  506. //rt_kprintf("MX_UART5_Init\n");
  507. /* USER CODE END UART5_Init 2 */
  508. }
  509. void HAL_UART_MspInit(UART_HandleTypeDef *uartHandle)
  510. {
  511. GPIO_InitTypeDef GPIO_InitStruct = {0};
  512. if (uartHandle->Instance == UART5)
  513. {
  514. /* USER CODE BEGIN UART5_MspInit 0 */
  515. /* USER CODE END UART5_MspInit 0 */
  516. /* UART5 clock enable */
  517. __HAL_RCC_UART5_CLK_ENABLE();
  518. __HAL_RCC_GPIOC_CLK_ENABLE();
  519. __HAL_RCC_GPIOD_CLK_ENABLE();
  520. /**UART5 GPIO Configuration
  521. PC12 ------> UART5_TX
  522. PD2 ------> UART5_RX
  523. */
  524. GPIO_InitStruct.Pin = GPIO_PIN_12;
  525. GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
  526. GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
  527. HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
  528. GPIO_InitStruct.Pin = GPIO_PIN_2;
  529. GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
  530. GPIO_InitStruct.Pull = GPIO_NOPULL;
  531. HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);
  532. /* UART5 interrupt Init */
  533. HAL_NVIC_SetPriority(UART5_IRQn, 0, 0);
  534. HAL_NVIC_EnableIRQ(UART5_IRQn);
  535. __HAL_UART_ENABLE_IT(&huart5, UART_IT_IDLE);
  536. __HAL_UART_ENABLE(&huart5);
  537. HAL_UART_Receive_IT(&huart5, &aRxBuffer[3], 1);
  538. /* USER CODE END UART5_MspInit 1 */
  539. //rt_kprintf("HAL_UART_MspInit\n");
  540. }
  541. }
  542. void HAL_UART_MspDeInit(UART_HandleTypeDef *uartHandle)
  543. {
  544. if (uartHandle->Instance == UART5)
  545. {
  546. /* USER CODE BEGIN UART5_MspDeInit 0 */
  547. /* USER CODE END UART5_MspDeInit 0 */
  548. /* Peripheral clock disable */
  549. __HAL_RCC_UART5_CLK_DISABLE();
  550. /**UART5 GPIO Configuration
  551. PC12 ------> UART5_TX
  552. PD2 ------> UART5_RX
  553. */
  554. HAL_GPIO_DeInit(GPIOC, GPIO_PIN_12);
  555. HAL_GPIO_DeInit(GPIOD, GPIO_PIN_2);
  556. /* UART5 interrupt Deinit */
  557. HAL_NVIC_DisableIRQ(UART5_IRQn);
  558. /* USER CODE BEGIN UART5_MspDeInit 1 */
  559. /* USER CODE END UART5_MspDeInit 1 */
  560. }
  561. }
  562. /**
  563. * @brief This function handles UART5 global interrupt.
  564. */
  565. void UART5_IRQHandler(void)
  566. {
  567. if ((__HAL_UART_GET_FLAG(&huart5, UART_FLAG_ORE) != RESET))
  568. {
  569. __HAL_UART_CLEAR_OREFLAG(&huart5); // 清除标志位
  570. HAL_UART_Receive_IT(&huart5, &aRxBuffer[3], 1);
  571. }
  572. __HAL_UART_DISABLE_IT(&huart5, UART_IT_IDLE);
  573. if ((__HAL_UART_GET_FLAG(&huart5, UART_FLAG_IDLE) != RESET)) // idle标志被置位
  574. {
  575. rs_buf_fis = 1; // 接收1帧
  576. __HAL_UART_CLEAR_IDLEFLAG(&huart5); // 清除标志位
  577. }
  578. __HAL_UART_ENABLE_IT(&huart5, UART_IT_IDLE);
  579. HAL_UART_IRQHandler(&huart5);
  580. }
  581. /**
  582. * @brief Get the sensor num object
  583. *
  584. * @param cmd
  585. * @return Sensor_Read_Type
  586. */
  587. Sensor_Read_Type get_sensor_num(char *cmd)
  588. {
  589. if (strstr(cmd, stemp) != NULL)
  590. {
  591. return s_Temp;
  592. }
  593. if (strstr(cmd, humi) != NULL)
  594. {
  595. return s_Humi;
  596. }
  597. if (strstr(cmd, airpre) != NULL)
  598. {
  599. return s_Airpre;
  600. }
  601. if (strstr(cmd, lux) != NULL)
  602. {
  603. return s_Lux;
  604. }
  605. if (strstr(cmd, rain) != NULL)
  606. {
  607. return s_Rain;
  608. }
  609. return s_ALL;
  610. }
  611. /**
  612. * @brief 读取传感器参数
  613. *
  614. */
  615. void sensor_setdef(void)
  616. {
  617. uint8_t mark_up = 0;
  618. while (ef_cfged != 1)
  619. {
  620. rt_thread_mdelay(1000);
  621. }
  622. ef_get_env_blob("sensor", &sensor, sizeof(sensor), NULL);
  623. if (sensor[s_Temp].cfged != 1)
  624. {
  625. sensor[s_Temp].cfged = 1;
  626. sensor[s_Temp].sensor_addr = 1;
  627. sensor[s_Temp].start_reg = 2;
  628. sensor[s_Temp].count = 1;
  629. sensor[s_Temp].d_length = 1;
  630. sensor[s_Temp].d_pos = 0;
  631. sprintf(sensor[s_Temp].eName, stemp);
  632. sensor[s_Temp].factor = -10;
  633. mark_up = 1;
  634. LOG_W("s_Temp set def");
  635. }
  636. if (sensor[s_Humi].cfged != 1)
  637. {
  638. sensor[s_Humi].cfged = 1;
  639. sensor[s_Humi].sensor_addr = 1;
  640. sensor[s_Humi].start_reg = 3;
  641. sensor[s_Humi].count = 1;
  642. sensor[s_Humi].d_length = 1;
  643. sensor[s_Humi].d_pos = 0;
  644. sprintf(sensor[s_Humi].eName, humi);
  645. sensor[s_Humi].factor = -10;
  646. mark_up = 1;
  647. LOG_W("s_Humi set def");
  648. }
  649. if (sensor[s_Airpre].cfged != 1)
  650. {
  651. sensor[s_Airpre].cfged = 1;
  652. sensor[s_Airpre].sensor_addr = 1;
  653. sensor[s_Airpre].start_reg = 4;
  654. sensor[s_Airpre].count = 1;
  655. sensor[s_Airpre].d_length = 1;
  656. sensor[s_Airpre].d_pos = 0;
  657. sprintf(sensor[s_Airpre].eName, airpre);
  658. sensor[s_Airpre].factor = -10;
  659. mark_up = 1;
  660. LOG_W("s_Airpre set def");
  661. }
  662. if (sensor[s_Lux].cfged != 1)
  663. {
  664. sensor[s_Lux].cfged = 1;
  665. sensor[s_Lux].sensor_addr = 1;
  666. sensor[s_Lux].start_reg = 5;
  667. sensor[s_Lux].count = 1;
  668. sensor[s_Lux].d_length = 1;
  669. sensor[s_Lux].d_pos = 0;
  670. sprintf(sensor[s_Lux].eName, lux);
  671. sensor[s_Lux].factor = 10;
  672. mark_up = 1;
  673. LOG_W("s_Lux set def");
  674. }
  675. // if (sensor[s_Rain].cfged != 1)
  676. // {
  677. // sensor[s_Rain].cfged = 1;
  678. // sensor[s_Rain].sensor_addr = 1;
  679. // sensor[s_Rain].start_reg = 6;
  680. // sensor[s_Rain].count = 1;
  681. // sensor[s_Rain].d_length = 1;
  682. // sensor[s_Rain].d_pos = 0;
  683. // sprintf(sensor[s_Rain].eName, rain);
  684. // sensor[s_Rain].factor = -10;
  685. // mark_up = 1;
  686. // LOG_W("s_Rain set def");
  687. // }
  688. if (mark_up == 1)
  689. {
  690. LOG_W("sensor SET %d", ef_set_env_blob("sensor", &sensor, sizeof(sensor)));
  691. }
  692. ef_get_env_blob("collecting_sh1", &device_status.collecting_sh1, sizeof(device_status.collecting_sh1), NULL);
  693. ef_get_env_blob("collecting_eh1", &device_status.collecting_eh1, sizeof(device_status.collecting_eh1), NULL);
  694. if (ef_get_env_blob("limit", &limit, sizeof(Limit), NULL) == 0)
  695. {
  696. limit.temp_up = tempup_def;
  697. limit.temp_dw = tempdw_def;
  698. limit.LuxEN = OFF; // 250616 修改为默认时控
  699. limit.LuxTime = gktime_def;
  700. limit.temhumEN == ON; // 250616 修改默认温控为开
  701. LOG_W("limit SET %d", ef_set_env_blob("limit", &limit, sizeof(Limit)));
  702. }
  703. else
  704. {
  705. if (limit.temhumEN == ON)
  706. {
  707. LOG_W("温控已开启:%d ~ %d \n", limit.temp_dw, limit.temp_up);
  708. }
  709. if (limit.RainEN == ON)
  710. {
  711. LOG_W("雨控已开启\n");
  712. }
  713. if (limit.LuxEN == ON)
  714. {
  715. if (limit.LuxTime == 0)
  716. {
  717. limit.LuxTime = gktime_def;
  718. LOG_W("limit SET %d", ef_set_env_blob("limit", &limit, sizeof(Limit)));
  719. }
  720. }
  721. }
  722. /**
  723. * @brief 准备工作
  724. *
  725. */
  726. if (swork.Read != 1) // swork默认
  727. {
  728. if (ef_get_env_blob((const char *)"swork", (void *)&swork, sizeof(swork), NULL) == 0)
  729. {
  730. swork.Read = 1;
  731. swork.EN = OFF;
  732. swork.slux_set = Luxlimit_def;
  733. ef_set_env_blob((const char *)"swork", (void *)&swork, sizeof(swork));
  734. rt_kprintf("swork SET Def\n");
  735. }
  736. }
  737. if (swork.slux_set == 0)
  738. {
  739. swork.slux_set = Luxlimit_def;
  740. ef_set_env_blob((const char *)"swork", (void *)&swork, sizeof(swork));
  741. }
  742. if (swork.lseek == 0)
  743. {
  744. swork.lseek = 20;
  745. ef_set_env_blob((const char *)"swork", (void *)&swork, sizeof(swork));
  746. }
  747. if (swork.sunup_time.Hours == 0 || swork.sundown_time.Hours == 0)
  748. {
  749. swork.sunup_time.Hours = 7;
  750. swork.sunup_time.Minutes = 30;
  751. swork.sundown_time.Hours = 17;
  752. swork.sundown_time.Minutes = 20;
  753. ef_set_env_blob((const char *)"swork", (void *)&swork, sizeof(swork));
  754. }
  755. // 测试用 用来测试时间
  756. // swork.sunup_time.Hours = 7;
  757. // swork.sunup_time.Minutes = 30;
  758. // swork.sundown_time.Hours = 11;
  759. // swork.sundown_time.Minutes = 20;
  760. // 计算工作开始时间
  761. swork.start_time.Hours = (swork.sundown_time.Hours * 60 + swork.sundown_time.Minutes - swork.lseek) / 60;
  762. swork.start_time.Minutes = (swork.sundown_time.Hours * 60 + swork.sundown_time.Minutes - swork.lseek) % 60;
  763. swork.start_time.Seconds = swork.sundown_time.Seconds;
  764. // 计算工作结束时间
  765. swork.end_time.Hours = (swork.sunup_time.Hours * 60 + swork.sunup_time.Minutes + swork.lseek) / 60;
  766. swork.end_time.Minutes = (swork.sunup_time.Hours * 60 + swork.sunup_time.Minutes + swork.lseek) % 60;
  767. swork.end_time.Seconds = swork.sunup_time.Seconds;
  768. uint8_t save_syscfg = 0;
  769. if(ef_get_env_blob("syscfg", &syscfg, sizeof(syscfg), NULL) == 0)
  770. {
  771. syscfg.fan_speed = 50;
  772. save_syscfg = 1;
  773. }
  774. else
  775. {
  776. if(syscfg.fan_speed < 10 || syscfg.fan_speed > 100)
  777. {
  778. syscfg.fan_speed = 50; // 默认值
  779. save_syscfg = 1;
  780. }
  781. CollFanSetPWM(syscfg.fan_speed);
  782. }
  783. if(syscfg.Demo_mode != 0 && syscfg.Demo_mode != 1)
  784. {
  785. syscfg.Demo_mode = 0;
  786. save_syscfg = 1;
  787. }
  788. if(save_syscfg)
  789. {
  790. ef_set_env_blob("syscfg", &syscfg, sizeof(syscfg));
  791. }
  792. }
  793. // void delswork(void)
  794. //{
  795. //
  796. // ef_del_env("swork");
  797. //
  798. // }
  799. // MSH_CMD_EXPORT(delswork , delswork);
  800. /**
  801. * @brief 线程
  802. *
  803. * @param param
  804. */
  805. static void rs485_thread_entry(void *param)
  806. {
  807. uint16_t timeout = 10 * 60, cnt = 0, update_wait = 0;
  808. rt_thread_mdelay(6000);
  809. MX_UART5_Init();
  810. rt_thread_mdelay(6000);
  811. while (ef_cfged == 0)
  812. {
  813. rt_thread_mdelay(1000);
  814. if (update_wait++ > 180)
  815. {
  816. break;
  817. }
  818. }
  819. rt_kprintf("rs485_thread_entry\n");
  820. sensor_setdef();
  821. HMI_WRITE("result.txt=\"要素采集已开始\"");
  822. static uint8_t luxreadcnt = 0;
  823. while (1)
  824. {
  825. while (sex_enread)
  826. {
  827. // rt_kprintf("sex_enread \n");
  828. rt_thread_mdelay(1000);
  829. if (cnt++ >= timeout)
  830. {
  831. cnt = 0;
  832. sex_enread = 0;
  833. rt_kprintf("sex_enread timeout\n");
  834. HMI_WRITE("ReadSenor.result.txt=\"测试时长超时 已退出\"");
  835. break;
  836. }
  837. }
  838. READ_MODBUS_DATA_1(s_ALL);
  839. if (++luxreadcnt >= 5 && swork.EN == ON)
  840. {
  841. luxreadcnt = 0;
  842. Get_SunTime();
  843. }
  844. rt_thread_mdelay(6000);
  845. }
  846. }
  847. int rs485_thread(void)
  848. {
  849. rt_thread_t tid1 = RT_NULL;
  850. tid1 = rt_thread_create("rs485_thread",
  851. rs485_thread_entry, RT_NULL,
  852. 1024 + 256,
  853. 10, 5);
  854. /* 如果获得线程控制块,启动这个线程 */
  855. if (tid1 != RT_NULL)
  856. {
  857. rt_thread_startup(tid1);
  858. }
  859. else
  860. LOG_E("rs485_thread start fail\n");
  861. return 0;
  862. }
  863. INIT_APP_EXPORT(rs485_thread); // 监听命令及响应
  864. void dis_elem(void)
  865. {
  866. for (uint8_t a = 0; a < MAX_SENSOR_NUM; a++)
  867. {
  868. if (sensor[a].cfged == 1)
  869. {
  870. rt_kprintf("s%6s s-%d reg-%d val-%d/%s on-%d\n",
  871. sensor[a].eName,
  872. sensor[a].sensor_addr,
  873. sensor[a].start_reg,
  874. sensor[a].value,
  875. sensor[a].eValue,
  876. sensor[a].online);
  877. }
  878. }
  879. rt_kprintf("\n\n");
  880. }
  881. MSH_CMD_EXPORT(dis_elem, dis_elem);
  882. void dislimlt(void)
  883. {
  884. rt_kprintf("tup %d tdw %d hup %d hdw %d temp%d lux%d rain%d \n\n",
  885. limit.temp_up,
  886. limit.temp_dw,
  887. limit.humi_up,
  888. limit.humi_dw,
  889. limit.temhumEN,
  890. limit.LuxEN,
  891. limit.RainEN);
  892. }
  893. MSH_CMD_EXPORT(dislimlt, dislimlt);