mylib.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610
  1. /**
  2. ******************************************************************************
  3. * @file mylib.c
  4. * @author eming
  5. * @version V1.0.0
  6. * @date 2022-03-21
  7. * @brief 定义一些公用函数
  8. ******************************************************************************
  9. */
  10. #include "stdint.h"
  11. // #include "ustdio.h"
  12. #include "stdlib.h"
  13. #include "string.h"
  14. #include "time.h"
  15. #include "bs_type.h"
  16. /**
  17. * @brief 和校验
  18. * @details 字节数组的和校验函数
  19. *
  20. * @param *p 数组指针
  21. * @param size 数组长度
  22. * @return 求和结果
  23. * @retval 无
  24. */
  25. uint32_t mylib_sum(const uint8_t *p, uint16_t size)
  26. {
  27. uint32_t sum = 0;
  28. while(size--)
  29. {
  30. sum += *(p++);
  31. }
  32. return(sum);
  33. }
  34. /**
  35. * @brief 数据比较
  36. * @details 字节数组的数据比较
  37. *
  38. * @param *p1 数组1指针
  39. * @param *p2 数组2指针
  40. * @param size 比较的数据块大小
  41. * @return 比较结果
  42. * @retval TRUE 相等
  43. * @retval FALSE 不相等
  44. */
  45. int mylib_memcmp(const void *p1, const void *p2, int size)
  46. {
  47. uint8_t *bp1, *bp2;
  48. bp1 = (uint8_t*)p1;
  49. bp2 = (uint8_t*)p2;
  50. while(size--)
  51. {
  52. if(*(bp1++) != *(bp2++))return(FALSE);
  53. }
  54. return(TRUE);
  55. }
  56. /**
  57. * @brief 数据比较
  58. * @details 字节数组与指定数据比较
  59. *
  60. * @param *p1 数组指针
  61. * @param value 被比较的数值
  62. * @param size 比较的数据块大小
  63. * @return 比较结果
  64. * @retval TRUE 相等
  65. * @retval FALSE 不相等
  66. */
  67. int mylib_memcmp_b(uint8_t *p1, uint8_t value, int size)
  68. {
  69. while(size--)
  70. {
  71. if(*(p1++) != value)return(FALSE);
  72. }
  73. return(TRUE);
  74. }
  75. /**
  76. * @brief 延时函数
  77. * @details 大概为1uS的延时函数
  78. *
  79. * @param us 需要延时的微秒数
  80. * @return 无
  81. * @retval 无
  82. */
  83. void mylib_uDelay(uint32_t us)
  84. {
  85. int i;
  86. for(; us > 0; us--)
  87. {
  88. for(i = 0; i < 40; i++);
  89. }
  90. }
  91. /**
  92. * @brief CRC16函数
  93. * @details 计算字节数组的CRC16
  94. *
  95. * @param *p 数组指针
  96. * @param size 数组长度
  97. * @return 计算结果
  98. * @retval uint16_t CRC16值
  99. */
  100. uint16_t mylib_crc16(uint8_t *p, uint16_t size)
  101. {
  102. uint16_t crc; //校验码
  103. uint16_t i;
  104. uint16_t j;
  105. crc = 0xFFFF;
  106. for (i = 0; i < size; i++)
  107. {
  108. crc ^= *p;
  109. for (j = 0; j < 8; j++)
  110. {
  111. if ((crc & 1) == 1)
  112. {
  113. crc >>= 1;
  114. crc ^= 0xA001;
  115. }
  116. else
  117. {
  118. crc >>= 1;
  119. }
  120. }
  121. p++;
  122. }
  123. return(crc);
  124. }
  125. /**
  126. * @brief 16位大小端转换
  127. * @details 数据大端小段互相转换函数
  128. *
  129. * @param *frm 源数组指针
  130. * @param *to 目标数组指针
  131. * @param size 转换的数据个数(半字)
  132. * @return 无
  133. * @retval 无
  134. */
  135. void mylib_BigtoLittle16(const void *frm, void *to, uint16_t size)
  136. {
  137. uint8_t buff[2];
  138. uint8_t *fp, *tp;
  139. fp = (uint8_t *)frm;
  140. tp = (uint8_t *)to;
  141. while(size--)
  142. {
  143. buff[0] = fp[0];
  144. buff[1] = fp[1];
  145. tp[0] = buff[1];
  146. tp[1] = buff[0];
  147. tp += 2;
  148. fp += 2;
  149. }
  150. }
  151. /**
  152. * @brief 32位大小端转换
  153. * @details 数据大端小段互相转换函数
  154. *
  155. * @param *frm 源数组指针
  156. * @param *to 目标数组指针
  157. * @param size 转换的数据个数(字)
  158. * @return 无
  159. * @retval 无
  160. */
  161. void mylib_BigtoLittle32(const void *frm, void *to, uint16_t size)
  162. {
  163. uint8_t buff[4];
  164. uint8_t *fp, *tp;
  165. fp = (uint8_t *)frm;
  166. tp = (uint8_t *)to;
  167. while(size--)
  168. {
  169. buff[0] = fp[0];
  170. buff[1] = fp[1];
  171. buff[2] = fp[2];
  172. buff[3] = fp[3];
  173. tp[0] = buff[3];
  174. tp[1] = buff[2];
  175. tp[2] = buff[1];
  176. tp[3] = buff[0];
  177. tp += 4;
  178. fp += 4;
  179. }
  180. }
  181. /**
  182. * @brief 64位浮点数大小端转换
  183. * @details 数据大端小段互相转换函数
  184. *
  185. * @param dat 浮点数
  186. * @return 转换结果
  187. * @retval 转换后的浮点数
  188. */
  189. double mylib_BigtoLittle_fp64(double dat)
  190. {
  191. F64_U8 tmp1, tmp2;
  192. tmp1.f64 = dat;
  193. tmp2.d8[0] = tmp1.d8[7];
  194. tmp2.d8[1] = tmp1.d8[6];
  195. tmp2.d8[2] = tmp1.d8[5];
  196. tmp2.d8[3] = tmp1.d8[4];
  197. tmp2.d8[4] = tmp1.d8[3];
  198. tmp2.d8[5] = tmp1.d8[2];
  199. tmp2.d8[6] = tmp1.d8[1];
  200. tmp2.d8[7] = tmp1.d8[0];
  201. return(tmp2.f64);
  202. }
  203. /**
  204. * @brief BCD编码函数
  205. * @details 二进制数据转BCD码
  206. *
  207. * @param hex 二进制数据
  208. * @return 转换结果
  209. * @retval BCD码
  210. */
  211. uint8_t mylib_HEXtoBCD(uint8_t hex)
  212. {
  213. uint8_t bcd = 0;
  214. bcd = hex / 10;
  215. bcd <<= 4;
  216. bcd += hex % 10;
  217. return(bcd);
  218. }
  219. /**
  220. * @brief BCD解码函数
  221. * @details BCD码转二进制数据
  222. *
  223. * @param bcd BCD码数据
  224. * @return 转换结果
  225. * @retval 二进制数据
  226. */
  227. uint8_t mylib_BCDtoHEX(uint8_t bcd)
  228. {
  229. uint8_t hex = 0;
  230. hex = ((bcd >> 4) & 0x0F) * 10 + (bcd & 0x0F);
  231. return(hex);
  232. }
  233. /**
  234. * @brief 数值转字符串
  235. * @details 整形数值转字符串
  236. *
  237. * @param value 整形数值
  238. * @param *str 转换结果字符串指针
  239. * @param radix 进制
  240. * @return 换结果字符串指针
  241. */
  242. char *my_itoa(int value, char *str, uint8_t radix)
  243. {
  244. static char szMap[] =
  245. {
  246. '0', '1', '2', '3', '4', '5',
  247. '6', '7', '8', '9', 'a', 'b',
  248. 'c', 'd', 'e', 'f', 'g', 'h',
  249. 'i', 'j', 'k', 'l', 'm', 'n',
  250. 'o', 'p', 'q', 'r', 's', 't',
  251. 'u', 'v', 'w', 'x', 'y', 'z'
  252. }; // 字符映射表
  253. int nCount = -1, nIndex;
  254. char *pStr = str, nTemp;
  255. unsigned int nValue = *(unsigned *)&value;
  256. if(radix >= 2 && radix <= 36 ) //限制radix必须在2到36之间
  257. {
  258. if(value < 0 && radix == 10) //如果是负数就在首位添加负号,并将字符串前移
  259. {
  260. *pStr++ = '-';
  261. value = -value; //转为正数,
  262. }
  263. do //循环转换每一个数字,直到结束
  264. {
  265. pStr[++nCount] = szMap[nValue % radix];
  266. nValue /= radix;
  267. }
  268. while(nValue > 0); //转换结束后字符串是翻的
  269. nIndex = (nCount + 1) / 2; //计算出一半的长度
  270. while(nIndex-- > 0) //将字符串的字符序翻转
  271. {
  272. nTemp = pStr[nIndex];
  273. pStr[nIndex] = pStr[nCount - nIndex];
  274. pStr[nCount - nIndex] = nTemp;
  275. }
  276. }
  277. pStr[nCount + 1] = '\0'; // 置结束符
  278. return str;
  279. }
  280. /**
  281. * @brief 数组转字符串
  282. * @details 字节数组转字符串
  283. *
  284. * @param *str 转换后的字符串
  285. * @param bytes 被转换的字节数组
  286. * @param size 被转换的字节数组长度
  287. * @return 转换出的字符串长度
  288. */
  289. int mylib_bytes_to_string(char *str, const uint8_t *bytes, int size)
  290. {
  291. int i;
  292. char hexArray[] = "0123456789ABCDEF";
  293. for (i = 0; i < size; i++)
  294. {
  295. int v = bytes[i] & 0xFF;
  296. str[i * 2] = hexArray[v >> 4];
  297. str[i * 2 + 1] = hexArray[v & 0x0F];
  298. }
  299. str[size * 2] = '\0';
  300. return (size * 2);
  301. }
  302. /**
  303. * @brief 字符串转数组
  304. * @details 字符串转字节数组
  305. *
  306. * @param *str 被转换的字符串
  307. * @param bytes 转换出的字节数组
  308. * @return 转换出的字节数组长度
  309. */
  310. int mylib_string_to_bytes(char *str, uint8_t *bytes)
  311. {
  312. uint8_t tmp, tmp1;
  313. uint16_t len;
  314. uint16_t dat_len;
  315. len = strlen(str);
  316. if(len % 2) //检查是否为偶数
  317. {
  318. str[len] = '0'; //补0
  319. len++;
  320. str[len] = '\0';
  321. }
  322. dat_len = len / 2;
  323. while(len)
  324. {
  325. if((*str > 47) && (*str < 58)) //0~9
  326. {
  327. tmp = *str - 48;
  328. }
  329. else if((*str > 64) && (*str < 71)) //A~F
  330. {
  331. tmp = *str - 55;
  332. }
  333. else if((*str > 96) && (*str < 103)) //a~f
  334. {
  335. tmp = *str - 87;
  336. }
  337. else
  338. {
  339. tmp = 32;
  340. }
  341. tmp <<= 4;
  342. str++;
  343. if((*str > 47) && (*str < 58)) //0~9
  344. {
  345. tmp1 = *str - 48;
  346. }
  347. else if((*str > 64) && (*str < 71)) //A~F
  348. {
  349. tmp1 = *str - 55;
  350. }
  351. else if((*str > 96) && (*str < 103)) //a~f
  352. {
  353. tmp1 = *str - 87;
  354. }
  355. else
  356. {
  357. tmp1 = 32;
  358. }
  359. tmp += tmp1;
  360. *(bytes++) = tmp;
  361. str++;
  362. len -= 2;
  363. }
  364. return(dat_len);
  365. }
  366. /**
  367. * @brief 大小写转换
  368. * @details 将字符串中的大写字符变为小写字符
  369. *
  370. * @param *str 被转换的字符串
  371. * @return 转换出的字符串
  372. */
  373. char *strlwr(char *str)
  374. {
  375. uint16_t len;
  376. char *p;
  377. len = strlen(str);
  378. p = str;
  379. while(len--)
  380. {
  381. if((*p > 64) && (*p < 91))
  382. {
  383. *p += 32;
  384. }
  385. p++;
  386. }
  387. return(str);
  388. }
  389. /**
  390. * @brief 字符串提取数字
  391. * @details 字符串提取数字字符,去除其他符号
  392. *
  393. * @param *str 被处理的字符串
  394. * @param *num 结果字符串
  395. * @return 提取出的字符串长度
  396. */
  397. int strval(char *str, char *num)
  398. {
  399. int len = 0;
  400. while(*str != '\0')
  401. {
  402. if((*str > 47) && (*str < 58))
  403. {
  404. *num = *str;
  405. num++;
  406. len++;
  407. }
  408. str++;
  409. }
  410. *num = '\0';
  411. return(len);
  412. }
  413. /**
  414. * @brief 打印16进制数据
  415. * @details 由于调试时输出二进制数据
  416. *
  417. * @param *p 二进制数据指针
  418. * @param size 数据长度
  419. * @return 无
  420. */
  421. void printk_hex(const uint8_t *p, int size)
  422. {
  423. // int i;
  424. // for(i = 0; i < size; i++)
  425. // {
  426. // printk(" %02X", *(p++));
  427. // }
  428. }
  429. /**
  430. * @brief utc秒转时间
  431. * @details 包含时区参数
  432. *
  433. * @param utc_s utc秒
  434. * @param *t 转换结果
  435. * @param tz 时区
  436. * @return 无
  437. */
  438. void utc_to_time(uint32_t utc_s, struct tm *t, int tz)
  439. {
  440. #define SECOND_OF_DAY 86400 //1天的秒数
  441. uint16_t i, j, iDay;
  442. uint32_t lDay;
  443. const uint8_t DayOfMon[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
  444. utc_s += 3600 * tz; //时区
  445. lDay = utc_s / SECOND_OF_DAY;
  446. utc_s = utc_s % SECOND_OF_DAY;
  447. i = 1970; //星期取值为0-6
  448. t->tm_wday = (lDay + 3) % 7; //1970年1月1号是星期4
  449. while(lDay > 365)
  450. {
  451. if(((i % 4 == 0) && (i % 100 != 0)) || (i % 400 == 0)) // 闰年
  452. lDay -= 366;
  453. else
  454. lDay -= 365;
  455. i++;
  456. }
  457. if((lDay == 365) && !(((i % 4 == 0) && (i % 100 != 0)) || (i % 400 == 0))) //平年
  458. {
  459. lDay -= 365;
  460. i++;
  461. }
  462. t->tm_year = i - 1900; //得到年份
  463. for(j = 0; j < 12; j++) //计算月份
  464. {
  465. if((j == 1) && (((i % 4 == 0) && (i % 100 != 0)) || (i % 400 == 0)))
  466. iDay = 29;
  467. else
  468. iDay = DayOfMon[j];
  469. if(lDay >= iDay) lDay -= iDay;
  470. else break;
  471. }
  472. t->tm_mon = j;
  473. t->tm_mday = lDay + 1;
  474. t->tm_hour = utc_s / 3600;
  475. t->tm_min = (utc_s % 3600) / 60;
  476. t->tm_sec = (utc_s % 3600) % 60;
  477. }
  478. /**
  479. * @brief 计算日期是一年中的那一天
  480. * @details 计算日期的年索引,2月当做29天算
  481. *
  482. * @param utc_s utc秒
  483. * @param *t 转换结果
  484. * @param tz 时区
  485. * @return 无
  486. */
  487. int mylib_day_index(uint8_t mon, uint8_t day)
  488. {
  489. const uint8_t Line_Mon_Len[12] = {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
  490. int index = 0;
  491. int i;
  492. if((mon < 1) || (mon > 12))return(0); //参数判断
  493. if((day < 1) || (day > 31))return(0);
  494. for(i = 1; i < mon; i++)
  495. {
  496. index += Line_Mon_Len[i - 1];
  497. }
  498. index += day - 1;
  499. return(index);
  500. }
  501. /**
  502. * @brief 16进制字符串转数据
  503. * @details 16进制字符串转数据,可以包含"0x"头
  504. *
  505. * @param *s 字符串
  506. * @return 提取的数值
  507. */
  508. int tolower(int c)
  509. {
  510. if (c >= 'A' && c <= 'Z')
  511. {
  512. return c + 'a' - 'A';
  513. }
  514. else
  515. {
  516. return c;
  517. }
  518. }
  519. uint32_t htoi(const char *s)
  520. {
  521. int i;
  522. uint32_t n = 0;
  523. if (s[0] == '0' && (s[1]=='x' || s[1]=='X'))
  524. {
  525. i = 2;
  526. }
  527. else
  528. {
  529. i = 0;
  530. }
  531. for (; (s[i] >= '0' && s[i] <= '9') || (s[i] >= 'a' && s[i] <= 'z') || (s[i] >='A' && s[i] <= 'Z');++i)
  532. {
  533. if (tolower(s[i]) > '9')
  534. {
  535. n = 16 * n + (10 + tolower(s[i]) - 'a');
  536. }
  537. else
  538. {
  539. n = 16 * n + (tolower(s[i]) - '0');
  540. }
  541. }
  542. return n;
  543. }
  544. /**
  545. * @brief 返回堆内存的大小
  546. * @details 返回堆内存的大小
  547. *
  548. * @param *mp 堆内存指针
  549. * @return 堆内存的大小
  550. */
  551. uint32_t _msize(const void *mp)
  552. {
  553. return(*((int*)((uint32_t)mp - 4)));
  554. }
  555. /*******************************************************************************************************
  556. ** End Of File
  557. ********************************************************************************************************/