mathtool.c 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621
  1. /************************************************************************
  2. Project: Welling Motor Control Paltform
  3. Filename: mathtool.c
  4. Partner Filename: mathtool.h
  5. Description: The math function
  6. Complier: IAR Embedded Workbench for ARM 7.80, IAR Systems.
  7. CPU TYPE : GD32F3x0
  8. *************************************************************************
  9. Copyright (c) 2018 Welling Motor Technology(Shanghai) Co. Ltd.
  10. All rights reserved.
  11. *************************************************************************
  12. *************************************************************************
  13. Revising History (ECL of this file):
  14. ************************************************************************/
  15. /************************************************************************
  16. Beginning of File, do not put anything above here except notes
  17. Compiler Directives:
  18. *************************************************************************/
  19. #ifndef _MATHTOOL_C_
  20. #define _MATHTOOL_C_
  21. #endif
  22. /************************************************************************
  23. Included File:
  24. *************************************************************************/
  25. #include "user.h"
  26. /************************************************************************
  27. Constant Table:
  28. *************************************************************************/
  29. static const SWORD mth_swSinTab[SINTABSIZE] = {
  30. 0, // 0
  31. 804, // 1
  32. 1608, // 2
  33. 2411, // 3
  34. 3212, // 4
  35. 4011, // 5
  36. 4808, // 6
  37. 5602, // 7
  38. 6393, // 8
  39. 7180, // 9
  40. 7962, // 10
  41. 8740, // 11
  42. 9512, // 12
  43. 10279, // 13
  44. 11039, // 14
  45. 11793, // 15
  46. 12540, // 16
  47. 13279, // 17
  48. 14010, // 18
  49. 14733, // 19
  50. 15447, // 20
  51. 16151, // 21
  52. 16846, // 22
  53. 17531, // 23
  54. 18205, // 24
  55. 18868, // 25
  56. 19520, // 26
  57. 20160, // 27
  58. 20788, // 28
  59. 21403, // 29
  60. 22006, // 30
  61. 22595, // 31
  62. 23170, // 32
  63. 23732, // 33
  64. 24279, // 34
  65. 24812, // 35
  66. 25330, // 36
  67. 25833, // 37
  68. 26320, // 38
  69. 26791, // 39
  70. 27246, // 40
  71. 27684, // 41
  72. 28106, // 42
  73. 28511, // 43
  74. 28899, // 44
  75. 29269, // 45
  76. 29622, // 46
  77. 29957, // 47
  78. 30274, // 48
  79. 30572, // 49
  80. 30853, // 50
  81. 31114, // 51
  82. 31357, // 52
  83. 31581, // 53
  84. 31786, // 54
  85. 31972, // 55
  86. 32138, // 56
  87. 32286, // 57
  88. 32413, // 58
  89. 32522, // 59
  90. 32610, // 60
  91. 32679, // 61
  92. 32729, // 62
  93. 32758, // 63
  94. 32767, // 64
  95. 32758, // 65
  96. 32729, // 66
  97. 32679, // 67
  98. 32610, // 68
  99. 32522, // 69
  100. 32413, // 70
  101. 32286, // 71
  102. 32138, // 72
  103. 31972, // 73
  104. 31786, // 74
  105. 31581, // 75
  106. 31357, // 76
  107. 31114, // 77
  108. 30853, // 78
  109. 30572, // 79
  110. 30274, // 80
  111. 29957, // 81
  112. 29622, // 82
  113. 29269, // 83
  114. 28899, // 84
  115. 28511, // 85
  116. 28106, // 86
  117. 27684, // 87
  118. 27246, // 88
  119. 26791, // 89
  120. 26320, // 90
  121. 25833, // 91
  122. 25330, // 92
  123. 24812, // 93
  124. 24279, // 94
  125. 23732, // 95
  126. 23170, // 96
  127. 22595, // 97
  128. 22006, // 98
  129. 21403, // 99
  130. 20788, // 100
  131. 20160, // 101
  132. 19520, // 102
  133. 18868, // 103
  134. 18205, // 104
  135. 17531, // 105
  136. 16846, // 106
  137. 16151, // 107
  138. 15447, // 108
  139. 14733, // 109
  140. 14010, // 110
  141. 13279, // 111
  142. 12540, // 112
  143. 11793, // 113
  144. 11039, // 114
  145. 10279, // 115
  146. 9512, // 116
  147. 8740, // 117
  148. 7962, // 118
  149. 7180, // 119
  150. 6393, // 120
  151. 5602, // 121
  152. 4808, // 122
  153. 4011, // 123
  154. 3212, // 124
  155. 2411, // 125
  156. 1608, // 126
  157. 804, // 127
  158. 0, // 128
  159. -804, // 129
  160. -1608, // 130
  161. -2411, // 131
  162. -3212, // 132
  163. -4011, // 133
  164. -4808, // 134
  165. -5602, // 135
  166. -6393, // 136
  167. -7180, // 137
  168. -7962, // 138
  169. -8740, // 139
  170. -9512, // 140
  171. -10279, // 141
  172. -11039, // 142
  173. -11793, // 143
  174. -12540, // 144
  175. -13279, // 145
  176. -14010, // 146
  177. -14733, // 147
  178. -15447, // 148
  179. -16151, // 149
  180. -16846, // 150
  181. -17531, // 151
  182. -18205, // 152
  183. -18868, // 153
  184. -19520, // 154
  185. -20160, // 155
  186. -20788, // 156
  187. -21403, // 157
  188. -22006, // 158
  189. -22595, // 159
  190. -23170, // 160
  191. -23732, // 161
  192. -24279, // 162
  193. -24812, // 163
  194. -25330, // 164
  195. -25833, // 165
  196. -26320, // 166
  197. -26791, // 167
  198. -27246, // 168
  199. -27684, // 169
  200. -28106, // 170
  201. -28511, // 171
  202. -28899, // 172
  203. -29269, // 173
  204. -29622, // 174
  205. -29957, // 175
  206. -30274, // 176
  207. -30572, // 177
  208. -30853, // 178
  209. -31114, // 179
  210. -31357, // 180
  211. -31581, // 181
  212. -31786, // 182
  213. -31972, // 183
  214. -32138, // 184
  215. -32286, // 185
  216. -32413, // 186
  217. -32522, // 187
  218. -32610, // 188
  219. -32679, // 189
  220. -32729, // 190
  221. -32758, // 191
  222. -32768, // 192
  223. -32758, // 193
  224. -32729, // 194
  225. -32679, // 195
  226. -32610, // 196
  227. -32522, // 197
  228. -32413, // 198
  229. -32286, // 199
  230. -32138, // 200
  231. -31972, // 201
  232. -31786, // 202
  233. -31581, // 203
  234. -31357, // 204
  235. -31114, // 205
  236. -30853, // 206
  237. -30572, // 207
  238. -30274, // 208
  239. -29957, // 209
  240. -29622, // 210
  241. -29269, // 211
  242. -28899, // 212
  243. -28511, // 213
  244. -28106, // 214
  245. -27684, // 215
  246. -27246, // 216
  247. -26791, // 217
  248. -26320, // 218
  249. -25833, // 219
  250. -25330, // 220
  251. -24812, // 221
  252. -24279, // 222
  253. -23732, // 223
  254. -23170, // 224
  255. -22595, // 225
  256. -22006, // 226
  257. -21403, // 227
  258. -20788, // 228
  259. -20160, // 229
  260. -19520, // 230
  261. -18868, // 231
  262. -18205, // 232
  263. -17531, // 233
  264. -16846, // 234
  265. -16151, // 235
  266. -15447, // 236
  267. -14733, // 237
  268. -14010, // 238
  269. -13279, // 239
  270. -12540, // 240
  271. -11793, // 241
  272. -11039, // 242
  273. -10279, // 243
  274. -9512, // 244
  275. -8740, // 245
  276. -7962, // 246
  277. -7180, // 247
  278. -6393, // 248
  279. -5602, // 249
  280. -4808, // 250
  281. -4011, // 251
  282. -3212, // 252
  283. -2411, // 253
  284. -1608, // 254
  285. -804, // 255
  286. 0 // 256
  287. };
  288. static const UWORD mth_uwArctanTab[ARCTANTABSIZE] = {
  289. 8192, // 0
  290. 4836, // 1
  291. 2555, // 2
  292. 1297, // 3
  293. 651, // 4
  294. 326, // 5
  295. 163, // 6
  296. 81, // 7
  297. 41, // 8
  298. 20, // 9
  299. 10, // 10
  300. 5, // 11
  301. 3, // 12
  302. 1, // 13
  303. 1, // 14
  304. 0 // 15
  305. };
  306. /************************************************************************
  307. Exported Functions:
  308. *************************************************************************/
  309. /***************************************************************
  310. Function: math_voSinCos;
  311. Description: SIN & COS table.
  312. Call by: ...;
  313. Input Variables: Angle
  314. Output/Return Variables: SIN, COS
  315. Subroutine Call: N/A;
  316. Reference: N/A
  317. ****************************************************************/
  318. void mth_voSinCos(UWORD angle, SINCOS *v)
  319. {
  320. SWORD mth_swThsEntPu, mth_swNxtEntPu, mth_swDltAngPu;
  321. UWORD mth_uwIpValPu;
  322. //=======================================================================
  323. // Calculate Cos(theta_p)
  324. //=======================================================================
  325. mth_swThsEntPu = mth_swSinTab[((angle + 8192) & 0x7fff) >> 7]; // High 8 bit, 32767 to 255 Q15-Q7=Q8
  326. mth_swNxtEntPu = mth_swSinTab[(((angle + 8192) & 0x7fff) >> 7) + 1];
  327. mth_swDltAngPu = mth_swNxtEntPu - mth_swThsEntPu;
  328. mth_uwIpValPu = (angle & 0x007f) * 256; // Low 7 bit, 127 to 32512
  329. v->swCosPu = (SWORD)(((SLONG)mth_swDltAngPu * (SLONG)mth_uwIpValPu >> 15) + mth_swThsEntPu);
  330. //=======================================================================
  331. // Calculate Sin(theta_p)
  332. //=======================================================================
  333. mth_swThsEntPu = mth_swSinTab[(angle & 0x7fff) >> 7]; // High 8 bit, 32767 to 255 Q15-Q7=Q8
  334. mth_swNxtEntPu = mth_swSinTab[((angle & 0x7fff) >> 7) + 1];
  335. mth_swDltAngPu = mth_swNxtEntPu - mth_swThsEntPu;
  336. mth_uwIpValPu = (angle & 0x007f) * 256; // Low 7 bit, 127 to 32512
  337. v->swSinPu = (SWORD)(((SLONG)mth_swDltAngPu * (SLONG)mth_uwIpValPu >> 15) + mth_swThsEntPu);
  338. }
  339. /***************************************************************
  340. Function: Lpf;
  341. Description: LowPass filter cof calculation;
  342. Call by: repeated functions;
  343. Input Variables: ulLpfTime_us, uwExeFreq(Hz),uwLPFCof
  344. Output/Return Variables: SLONG *slpLpfOut
  345. Subroutine Call: N/A;
  346. Reference: N/A
  347. ****************************************************************/
  348. void mth_voLPFilterCoef(ULONG ulLpfTime_us, ULONG ulExeFreq, UWORD *uwLPFCof)
  349. {
  350. // y(n) = y(n-1) + T/(T+tao)*[x(n) - y(n-1)] = T/(T+tao)*x(n) + tao/(T+tao)*y(n-1)
  351. // uwLPFCof = T/(T+tao) //Q15
  352. // ulExeFreq range(50Hz,50KHz)
  353. ULONG ulTCtrl_us; // control time: us
  354. if (ulExeFreq < 1)
  355. {
  356. ulExeFreq = 1;
  357. }
  358. ulTCtrl_us = 1000000 / ulExeFreq; // Unit:1us
  359. if ((ulTCtrl_us < 1) && (ulLpfTime_us < 1))
  360. {
  361. ulLpfTime_us = 1;
  362. }
  363. *uwLPFCof = (UWORD)((ulTCtrl_us << 15) / (ulTCtrl_us + ulLpfTime_us)); // Q15
  364. }
  365. /***************************************************************
  366. Function: Lpf;
  367. Description: LowPass filter;
  368. Call by: repeated functions;
  369. Input Variables: swLpfIn,uwLPFCof
  370. Output/Return Variables: SLONG *slpLpfOut
  371. Subroutine Call: N/A;
  372. Reference: N/A
  373. ****************************************************************/
  374. void mth_voLPFilter(SWORD swLpfIn, LPF_OUT *out)
  375. {
  376. // swLpfIn(Q15);
  377. // ulLpfTime_us:Unit:1us (Range0.000ms~20000.000ms)
  378. // uwExeFreq:Unit:Hz the frequence of call
  379. // slLpfOut
  380. UWORD uwKx;
  381. SLONG_UNION sluTmp;
  382. SLONG slTmp1;
  383. uwKx = out->uwKx; // Q15
  384. sluTmp.sl = out->slY.sl;
  385. slTmp1 = sluTmp.sl + (uwKx * swLpfIn << 1) - (uwKx * sluTmp.sw.hi << 1) - (uwKx * sluTmp.sw.low >> 15);
  386. out->slY.sl = slTmp1; // Q31
  387. }
  388. /***************************************************************
  389. Function: mth_slSqrt;
  390. Description: sqrt;
  391. Call by: repeated functions;
  392. Input Variables:
  393. Output/Return Variables:
  394. Subroutine Call: N/A;
  395. Reference: N/A
  396. ****************************************************************/
  397. SLONG mth_slSqrt(SLONG slInput)
  398. {
  399. SLONG slRemainder;
  400. SLONG slRoot;
  401. SWORD swN;
  402. slRoot = 0;
  403. if (slInput < 0)
  404. {
  405. slInput = 0;
  406. }
  407. if ((slInput - 2147352578) > 0) // slInput>(32767*32767*2)
  408. {
  409. slRoot = 46339;
  410. return slRoot;
  411. }
  412. if (slInput > 0)
  413. {
  414. for (swN = 15; swN >= 0; swN--)
  415. {
  416. slRemainder = slInput - (SLONG)slRoot * slRoot;
  417. if (slRemainder > 0)
  418. {
  419. slRoot = slRoot + (1 << swN);
  420. }
  421. else
  422. {
  423. slRoot = slRoot - (1 << swN);
  424. if (slRoot <= 0)
  425. {
  426. slRoot = 0;
  427. }
  428. }
  429. }
  430. }
  431. else
  432. {
  433. slRoot = 0;
  434. }
  435. return slRoot;
  436. }
  437. /***************************************************************
  438. Function: mth_slRamp;
  439. Description: ramp;
  440. Call by: repeated functions;
  441. Input Variables:
  442. Output/Return Variables:
  443. Subroutine Call: N/A;
  444. Reference: N/A
  445. ****************************************************************/
  446. SLONG mth_slRamp(SLONG slInput, SLONG slDelta, SLONG slOutputLimit)
  447. {
  448. SLONG slOutput;
  449. slOutput = slInput + slDelta;
  450. if (slOutput > slOutputLimit)
  451. {
  452. slOutput = slOutputLimit;
  453. }
  454. return slOutput;
  455. }
  456. /***************************************************************
  457. Function: mth_voArctan;
  458. Description: arctan;
  459. Call by: repeated functions;
  460. Input Variables:
  461. Output/Return Variables:
  462. Subroutine Call: N/A;
  463. Reference: N/A
  464. ****************************************************************/
  465. UWORD mth_voArctan(const ARCTAN_IN *in) /* parasoft-suppress METRICS-28 "本项目圈复杂度无法更改,后续避免" */
  466. {
  467. UWORD uwQuadrant, uwStep;
  468. SLONG slX, slY, slCurAngle, slNewX;
  469. UWORD uwEstThetaPu;
  470. slCurAngle = 0;
  471. slX = in->swAlphaPu;
  472. slY = in->swBetaPu;
  473. if ((slX == 0) || (slY == 0))
  474. {
  475. if (slX == 0)
  476. {
  477. if (slY > 0)
  478. {
  479. uwEstThetaPu = 8192; // Q15
  480. }
  481. else if (slY < 0)
  482. {
  483. uwEstThetaPu = 24576; // Q15
  484. }
  485. else
  486. {
  487. uwEstThetaPu = 0;
  488. }
  489. }
  490. if (slY == 0)
  491. {
  492. if (slX > 0)
  493. {
  494. uwEstThetaPu = 0; // Q15
  495. }
  496. else if (slX < 0)
  497. {
  498. uwEstThetaPu = 16384; // Q15
  499. }
  500. else
  501. {
  502. //do noting
  503. }
  504. }
  505. }
  506. else
  507. {
  508. if ((slX > 0) && (slY > 0)) // Quadrant 0, 0 < angle < 90
  509. {
  510. uwQuadrant = 0;
  511. }
  512. else if ((slX < 0) && (slY > 0)) // Quadrant 1, 90 < angle < 180
  513. {
  514. uwQuadrant = 1;
  515. slX = -slX;
  516. }
  517. else if ((slX < 0) && (slY < 0)) // Quadrant 2, 180 < angle < 270
  518. {
  519. uwQuadrant = 2;
  520. slX = -slX;
  521. slY = -slY;
  522. }
  523. else //if ((slX > 0) && (slY < 0)) // Quadrant 3, 270 < angle < 360
  524. {
  525. uwQuadrant = 3;
  526. slY = -slY;
  527. }
  528. for (uwStep = 0; uwStep < (ARCTANTABSIZE - 1); uwStep++)
  529. {
  530. if (slY > 0)
  531. {
  532. slNewX = slX + (slY >> uwStep);
  533. slY = slY - (slX >> uwStep);
  534. slX = slNewX;
  535. slCurAngle += mth_uwArctanTab[uwStep];
  536. }
  537. else if (slY < 0)
  538. {
  539. slNewX = slX - (slY >> uwStep);
  540. slY = slY + (slX >> uwStep);
  541. slX = slNewX;
  542. slCurAngle -= mth_uwArctanTab[uwStep];
  543. }
  544. else
  545. {
  546. slCurAngle = slCurAngle;
  547. }
  548. }
  549. switch (uwQuadrant)
  550. {
  551. case 0:
  552. slCurAngle = slCurAngle;
  553. break;
  554. case 1:
  555. slCurAngle = 32767 - slCurAngle;
  556. break;
  557. case 2:
  558. slCurAngle = 32767 + slCurAngle;
  559. break;
  560. case 3:
  561. slCurAngle = 65534 - slCurAngle;
  562. break;
  563. default:
  564. break;
  565. }
  566. slCurAngle = slCurAngle >> 1;
  567. if (slCurAngle > 32767)
  568. {
  569. slCurAngle = 32767;
  570. }
  571. else if (slCurAngle < 0)
  572. {
  573. slCurAngle = slCurAngle + 32768;
  574. }
  575. else
  576. {
  577. //do noting
  578. }
  579. uwEstThetaPu = (UWORD)slCurAngle;
  580. }
  581. return uwEstThetaPu;
  582. }
  583. /************************************************************************
  584. Local Functions: N/A
  585. *************************************************************************/
  586. /*************************************************************************
  587. Copyright (c) 2018 Welling Motor Technology(Shanghai) Co., Ltd.
  588. All rights reserved.
  589. *************************************************************************/
  590. #ifdef _MATHTOOL_C_
  591. #undef _MATHTOOL_C_ /* parasoft-suppress MISRA2004-19_6 "本项目中无法更改,后续避免使用" */
  592. #endif
  593. /*************************************************************************
  594. End of this File (EOF):
  595. Do not put anything after this part!
  596. *************************************************************************/