prj_com.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575
  1. #include "string.h"
  2. #include "prj_com.h"
  3. void HexToStr(uint32_t Hex, char *Str, int16_t Len)
  4. {
  5. unsigned char Ch;
  6. while((Len--)>0){
  7. Ch = Hex & 0xFU;
  8. Ch += (Ch<=0x9U) ? 0x30 : 0x37;
  9. *(Str+Len) = Ch;
  10. Hex = Hex>>4;
  11. }
  12. }
  13. // judge and convert a string to integer
  14. // return 0: either HEX or DEC found
  15. // return 10: DEC convertion completed
  16. // return 16: HEX convertion completed
  17. int str2int(char *str, uint32_t *n) {
  18. char ch;
  19. *n = 0;
  20. ch = *str++; // get 1st char of string
  21. if (ch<0x30 || ch>0x39) { // not ASCII 0~9
  22. return(0);
  23. }
  24. if (ch==0x30) { // 1st char is '0'
  25. ch = *str++;
  26. if (ch=='\0') { // 2nd char is 'end'
  27. return(10); // DEC 0 found
  28. }
  29. if (ch!='x' && ch!='X') { // not HEX
  30. return(0);
  31. }
  32. ch = *str++;
  33. if (ch=='\0') { // 3rd char is 'end'
  34. return(0);
  35. }
  36. while (ch!='\0' && ch!=0x20) { // HEX convertion
  37. while (ch=='_') { // skip '_' between numbers
  38. ch = *str++;
  39. }
  40. if (ch>=0x30 && ch<=0x39) { // ASCII 0~9
  41. ch -= 0x30;
  42. } else if (ch>=0x41 && ch<=0x46) { // ASCII A~F
  43. ch -= 0x41 - 10;
  44. } else if (ch>=0x61 && ch<=0x66) { // ASCII a~f
  45. ch -= 0x61 - 10;
  46. } else {
  47. return(0);
  48. }
  49. *n = (*n<<4) + ch;
  50. ch = *str++;
  51. }
  52. return(16); // HEX return
  53. }
  54. while (ch!='\0' && ch!=0x20) { // DEC convertion
  55. while (ch=='_') { // skip '_' between numbers
  56. ch = *str++;
  57. }
  58. if (ch>=0x30 && ch<=0x39) {
  59. ch -= 0x30;
  60. } else {
  61. return(0);
  62. }
  63. *n = (*n*10) + ch;
  64. ch = *str++;
  65. }
  66. return(10); // DEC return
  67. }
  68. // judge and convert a string to float
  69. // return 0: error, not float found
  70. // return 1: float convertion completed
  71. int str2float(char *str, float *f)
  72. {
  73. char ch;
  74. char fraction = 0;
  75. float precision = 1.0f;
  76. *f = 0.0f;
  77. ch = *str++; // get 1st char of string
  78. if (ch=='-'){
  79. precision = -1.0f;
  80. ch = *str++; // skip '-'
  81. }
  82. while(ch!='\0' && ch!=0x20){
  83. if (ch>=0x30 && ch<=0x39) {
  84. ch -= 0x30;
  85. *f = (*f)*10.0f + ch;
  86. if (fraction){
  87. precision *= 0.1f;
  88. }
  89. } else if (ch=='.') {
  90. fraction = 1;
  91. } else { // unknow char
  92. return(0);
  93. }
  94. ch = *str++;
  95. }
  96. *f *= precision;
  97. return(1);
  98. }
  99. void int2str(int n, char *str) {
  100. int i = 0, j, sign;
  101. char temp;
  102. if ((sign = n) < 0) n = -n;
  103. do {
  104. str[i++] = n % 10 + '0';
  105. } while ((n /= 10) > 0);
  106. if (sign < 0) str[i++] = '-';
  107. str[i] = '\0';
  108. for (j = 0; j < i / 2; j++) {
  109. temp = str[j];
  110. str[j] = str[i - j - 1];
  111. str[i - j - 1] = temp;
  112. }
  113. }
  114. void HexBufToStr(char *dest, unsigned char *src, int len) {
  115. char ddl, ddh;
  116. int i;
  117. for (i = 0; i < len; i++) {
  118. ddh = 48 + src[i] / 16;
  119. ddl = 48 + src[i] % 16;
  120. if (ddh > 57) {
  121. ddh = ddh + 7;
  122. }
  123. if (ddl > 57) {
  124. ddl = ddl + 7;
  125. }
  126. dest[i * 2] = ddh;
  127. dest[i * 2 + 1] = ddl;
  128. }
  129. dest[len * 2] = '\0';
  130. }
  131. uint8_t ToUpper(uint8_t c) {
  132. return (c >= 'a' && c <= 'z') ? c & 0x5f : c;
  133. }
  134. void StrToHexBuf(char *dest, char *src, int len) {
  135. char h1, h2;
  136. char s1, s2;
  137. int i;
  138. for (i = 0; i < len; i++) {
  139. h1 = src[2 * i];
  140. h2 = src[2 * i + 1];
  141. s1 = ToUpper(h1) - 0x30;
  142. if (s1 > 9) {
  143. s1 -= 7;
  144. }
  145. s2 = ToUpper(h2) - 0x30;
  146. if (s2 > 9) {
  147. s2 -= 7;
  148. }
  149. dest[i] = s1 * 16 + s2;
  150. }
  151. }
  152. // width 2:uint16_t; 4:uint32_t; others:reserved
  153. // num number of uint16_t or uint32_t, not byte number
  154. void ToggleEndian(uint8_t *src, uint8_t *dst, uint16_t width, uint16_t num)
  155. {
  156. uint16_t b;
  157. src--;
  158. src += width;
  159. while(1){
  160. b = width;
  161. while(b--){
  162. *dst++ = *src--;
  163. }
  164. if (--num==0) {
  165. break;
  166. }
  167. src += (width<<1);
  168. }
  169. }
  170. // 1) pattern = 0xEDB88320
  171. // G(x)=x32+x26+x23+x22+x16+x12+x11+x10+x8+x7+x5+x4+x2+x+1
  172. // when initial=0xFFFFFFFF, GoodFCS = 0xDEBB20E3
  173. uint32_t com_crc32L_next(uint32_t crc_cur, uint8_t *data, uint32_t len, uint32_t pattern)
  174. {
  175. uint8_t u8;
  176. uint8_t i;
  177. uint8_t fb;
  178. while(len-->0){
  179. u8 = *data++;
  180. for(i=0;i<8;i++){
  181. fb = (u8 ^ (uint8_t)crc_cur) & 0x01u;
  182. u8 = u8>>1; // LSB first
  183. crc_cur = crc_cur>>1;
  184. if (fb){
  185. crc_cur = crc_cur ^ pattern;
  186. }
  187. }
  188. }
  189. return(crc_cur);
  190. }
  191. // 1) pattern = 0x8408
  192. // G(x)=x16+x12+x5+1
  193. // when initial=0xFFFF, GoodFCS = 0xF0B8
  194. // 2) pattern = 0xA001
  195. // G(x)=x16+x15+x2+1
  196. // when initial=0xFFFF, GoodFCS = 0xF0B8
  197. uint16_t com_crc16L_next(uint16_t crc_cur, uint8_t *data, uint32_t len, uint16_t pattern)
  198. {
  199. uint8_t u8;
  200. uint8_t i;
  201. uint8_t fb;
  202. while(len-->0){
  203. u8 = *data++;
  204. for(i=0;i<8;i++){
  205. fb = (u8 ^ (uint8_t)crc_cur) & 0x01u;
  206. u8 = u8>>1; // LSB first
  207. crc_cur = crc_cur>>1;
  208. if (fb){
  209. crc_cur = crc_cur ^ pattern;
  210. }
  211. }
  212. }
  213. return(crc_cur);
  214. }
  215. // 1) pattern = 0x04C11DB7
  216. // G(x)=x32+x26+x23+x22+x16+x12+x11+x10+x8+x7+x5+x4+x2+x+1
  217. // when initial=0xFFFFFFFF, GoodFCS = 0xC704DD7B
  218. uint32_t com_crc32H_next(uint32_t crc_cur, uint8_t *data, uint32_t len, uint32_t pattern)
  219. {
  220. uint8_t u8;
  221. uint8_t i;
  222. uint8_t fb;
  223. while(len-->0){
  224. u8 = *data++;
  225. for(i=0;i<8;i++){
  226. fb = (u8 ^ (uint8_t)(crc_cur>>24)) & 0x80u;
  227. u8 = u8<<1; // MSB first
  228. crc_cur = crc_cur<<1;
  229. if (fb){
  230. crc_cur = crc_cur ^ pattern;
  231. }
  232. }
  233. }
  234. return(crc_cur);
  235. }
  236. // 1) pattern = 0x1021
  237. // G(x)=x16+x12+x5+1
  238. // when initial=0xFFFF, GoodFCS = 0x
  239. // 2) pattern = 0x8005
  240. // G(x)=x16+x15+x2+1
  241. // when initial=0xFFFF, GoodFCS = 0x
  242. uint16_t com_crc16H_next(uint16_t crc_cur, uint8_t *data, uint32_t len, uint16_t pattern)
  243. {
  244. uint8_t u8;
  245. uint8_t i;
  246. uint8_t fb;
  247. while(len-->0){
  248. u8 = *data++;
  249. for(i=0;i<8;i++){
  250. fb = (u8 ^ (uint8_t)(crc_cur>>8)) & 0x80u;
  251. u8 = u8<<1; // MSB first
  252. crc_cur = crc_cur<<1;
  253. if (fb){
  254. crc_cur = crc_cur ^ pattern;
  255. }
  256. }
  257. }
  258. return(crc_cur);
  259. }
  260. uint32_t strnchar(const char *src, char ch, int index)
  261. {
  262. int num = 0;
  263. const char *p = src;
  264. while (*p) {
  265. if(*p == ch) {
  266. if(num++ == index) {
  267. break;
  268. } else {
  269. p++;
  270. }
  271. } else {
  272. p++;
  273. }
  274. }
  275. return (uint32_t)(strlen(src) - strlen(p));
  276. }
  277. uint32_t strcntchar(const char *src, char ch)
  278. {
  279. uint32_t num = 0;
  280. const char *p = src;
  281. while (*p) {
  282. if(*p == ch) {
  283. num++;
  284. }
  285. p++;
  286. }
  287. return num;
  288. }
  289. static uint8_t month_days[13][2] = {{0, 0}, {31, 31}, {28, 29}, {31, 31}, {30, 30}, {31, 31},
  290. {30, 30}, {31, 31}, {31, 31}, {30, 30}, {31, 31}, {30, 30}, {31, 31}};
  291. uint8_t is_leap(uint16_t year) {
  292. return ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0) ? 1 : 0;
  293. }
  294. uint8_t last_day_of_month(uint8_t year, uint8_t month)
  295. {
  296. return month_days[month][is_leap(2000 + year)];
  297. }
  298. uint32_t days_from_leap_year_begin(uint8_t month, uint8_t day) {
  299. uint8_t i;
  300. uint32_t days = 0;
  301. for (i = 1; i < month; i++) {
  302. days += month_days[i][1];
  303. }
  304. return (days + day);
  305. }
  306. uint32_t next_day(uint32_t date) {
  307. uint16_t year = (uint16_t)(date >> 16);
  308. uint8_t month = (uint8_t)(date >> 8);
  309. uint8_t day = (uint8_t)date;
  310. day++;
  311. if (day > month_days[month][is_leap(year)]) {
  312. day -= month_days[month][is_leap(year)];
  313. month++;
  314. }
  315. if (month >= 13) {
  316. month = 1;
  317. year++;
  318. }
  319. return (year << 16) | (month << 8) | day;
  320. }
  321. uint32_t prev_day(uint32_t date) {
  322. uint16_t year = (uint16_t)(date >> 16);
  323. uint8_t month = (uint8_t)(date >> 8);
  324. uint8_t day = (uint8_t)date;
  325. uint16_t y;
  326. uint8_t m;
  327. uint8_t d = day - 1;
  328. if (d != 0) {
  329. y = year;
  330. m = month;
  331. } else {
  332. m = month - 1;
  333. y = year;
  334. if (m != 0) {
  335. d = month_days[m][is_leap(y)];
  336. } else {
  337. y = year - 1;
  338. m = 12;
  339. d = month_days[m][is_leap(y)];
  340. }
  341. }
  342. return (y << 16) | (m << 8) | d;
  343. }
  344. uint32_t next_month(uint32_t date) {
  345. uint16_t year = (uint16_t)(date >> 16);
  346. uint8_t month = (uint8_t)(date >> 8);
  347. month++;
  348. if (month >= 13) {
  349. month = 1;
  350. year++;
  351. }
  352. return (year << 16) | (month << 8);
  353. }
  354. uint32_t prev_month(uint32_t date) {
  355. uint16_t year = (uint16_t)(date >> 16);
  356. uint8_t month = (uint8_t)(date >> 8);
  357. month--;
  358. if (month == 0) {
  359. year = year - 1;
  360. month = 12;
  361. }
  362. return (year << 16) | (month << 8);
  363. }
  364. void time_add_secs(tm_t *dest, tm_t *src, uint32_t secs) {
  365. uint16_t days;
  366. uint32_t date;
  367. uint16_t i;
  368. memcpy(dest, src, sizeof(tm_t));
  369. dest->sec += secs;
  370. if (dest->sec >= 60) {
  371. dest->min += (dest->sec / 60);
  372. dest->sec %= 60;
  373. if (dest->min >= 60) {
  374. dest->hour += (dest->min / 60);
  375. dest->min %= 60;
  376. if (dest->hour >= 24) {
  377. days = dest->hour / 24;
  378. dest->hour %= 24;
  379. date = (dest->year << 16) | (dest->month << 8) | dest->day;
  380. for (i = 0; i < days; i++) {
  381. date = next_day(date);
  382. }
  383. dest->year = (uint8_t)(date >> 16);
  384. dest->month = (uint8_t)(date >> 8);
  385. dest->day = (uint8_t)date;
  386. }
  387. }
  388. }
  389. }
  390. void time_sub_secs(tm_t *dest, tm_t *src, uint32_t secs) {
  391. uint16_t days;
  392. uint32_t date;
  393. uint16_t i;
  394. memcpy(dest, src, sizeof(tm_t));
  395. // 处理减去秒数发生借位的情况
  396. if (dest->sec < secs) {
  397. uint32_t borrow_secs = secs - dest->sec;
  398. dest->sec = 60 - (borrow_secs % 60);
  399. uint32_t borrow_mins = borrow_secs / 60;
  400. if (borrow_secs % 60 != 0) {
  401. borrow_mins++;
  402. }
  403. if (dest->min < borrow_mins) {
  404. uint32_t borrow_mins_actual = borrow_mins - dest->min;
  405. dest->min = 60 - (borrow_mins_actual % 60);
  406. uint32_t borrow_hours = borrow_mins_actual / 60;
  407. if (borrow_mins_actual % 60 != 0) {
  408. borrow_hours++;
  409. }
  410. if (dest->hour < borrow_hours) {
  411. uint32_t borrow_hours_actual = borrow_hours - dest->hour;
  412. dest->hour = 24 - (borrow_hours_actual % 24);
  413. days = borrow_hours_actual / 24;
  414. if (borrow_hours_actual % 24 != 0) {
  415. days++;
  416. }
  417. date = (dest->year << 16) | (dest->month << 8) | dest->day;
  418. for (i = 0; i < days; i++) {
  419. date = prev_day(date);
  420. }
  421. dest->year = (uint8_t)(date >> 16);
  422. dest->month = (uint8_t)(date >> 8);
  423. dest->day = (uint8_t)date;
  424. } else {
  425. dest->hour -= borrow_hours;
  426. }
  427. } else {
  428. dest->min -= borrow_mins;
  429. }
  430. } else {
  431. dest->sec -= secs;
  432. }
  433. }
  434. uint8_t check_sum(volatile uint8_t *data, uint16_t len) {
  435. uint8_t sum = 0;
  436. uint16_t i;
  437. for (i = 0; i < len; i++) {
  438. sum += data[i];
  439. }
  440. return sum;
  441. }
  442. //add by yuewei 20260304
  443. uint16_t check_sum_2_byte(volatile uint8_t *data, uint16_t len) {
  444. uint16_t sum = 0;
  445. uint16_t i;
  446. for (i = 0; i < len; i++) {
  447. sum += data[i];
  448. }
  449. return sum;
  450. }
  451. //add by yuewei 20260317
  452. /**
  453. * @brief 计算CRC16/MODBUS校验值(逐位计算法)
  454. * @param data: 待校验的数据首地址
  455. * @param length: 数据长度
  456. * @return 16位校验结果(高字节在前,低字节在后)
  457. */
  458. uint16_t crc16_modbus(volatile uint8_t *data, uint16_t length)
  459. {
  460. uint16_t crc = 0xFFFF;
  461. uint8_t i;
  462. while (length--)
  463. {
  464. crc ^= *data++;
  465. for (i = 0; i < 8; i++)
  466. {
  467. if (crc & 0x0001)
  468. {
  469. crc >>= 1;
  470. crc ^= 0xA001;
  471. }
  472. else
  473. {
  474. crc >>= 1;
  475. }
  476. }
  477. }
  478. return crc;
  479. }