mathtool.c 15 KB

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