math_tools.c 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451
  1. #include "math_tools.h"
  2. /*
  3. 滑动均值滤波
  4. InputData:最新采集值
  5. Array:缓存队列
  6. Length:缓存大小
  7. 运行一次后,缓存队列最后一个数据为最新采集值,前面数据依次前移,返回值为缓存队列平均值
  8. */
  9. uint16_t MovingAverageFilter(uint16_t InputData, uint16_t* Array, uint16_t Length)
  10. {
  11. uint16_t Result, i;
  12. Result = GetAverageData(Array, Length);
  13. for(i=0; i<(Length - 1); i++)
  14. {
  15. Array[i] = Array[i+1];
  16. }
  17. Array[Length - 1] = InputData;
  18. return Result;
  19. }
  20. /*
  21. 取平均值
  22. Input:输入数组
  23. Length:有效数据长度
  24. 返回值为输入数组平均值
  25. */
  26. uint16_t GetAverageData(uint16_t* Input, uint16_t Length)
  27. {
  28. uint16_t i,Result;
  29. uint32_t Sum = 0;
  30. for(i=0; i<Length; i++)
  31. {
  32. Sum += Input[i];
  33. }
  34. Result = Sum / Length;
  35. return Result;
  36. }
  37. /*
  38. 三段曲线计算
  39. 0< InputData < Th1 : y = 1 - (Th1 - InputData) * K1
  40. Th1 < InputData < Th2 : y = 1
  41. InputData> Th2 : y = 1 - (InputData - Th2) * K2
  42. K1, K2, Result均放大1024倍
  43. */
  44. uint16_t Function_Linear_3Stage(uint16_t Th1, int16_t K1, uint16_t Th2, int16_t K2, uint16_t InputData)
  45. {
  46. int32_t Result;
  47. if(InputData < Th1)
  48. {
  49. if(K1 == 0xFF)
  50. Result = 0;
  51. else
  52. Result = 1024 - (Th1 - InputData) * K1;
  53. }
  54. else if(InputData < Th2)
  55. {
  56. Result = 1024;
  57. }
  58. else
  59. {
  60. Result = 1024 - (InputData - Th2) * K2;
  61. }
  62. Result = (Result <= 0) ? 0 : Result;
  63. return (uint16_t)Result;
  64. }
  65. /*
  66. 系数增益计算
  67. InputData <= Th: y = Min + (Max - Min) / Th * InputData
  68. InputData > Th: y = Max;
  69. Min, Max均放大1024倍
  70. */
  71. uint16_t Coefficient_GainCal(uint16_t Min, uint16_t Max, uint16_t Th, uint16_t InputData)
  72. {
  73. uint16_t Result;
  74. uint16_t K;
  75. //计算K
  76. if(Th == 0)
  77. {
  78. return Max;
  79. }
  80. else
  81. {
  82. K = (Max - Min) * 1024 / Th;
  83. if(InputData > Th)
  84. {
  85. Result = Max;
  86. return Result;
  87. }
  88. else
  89. {
  90. Result = Min + (K * InputData >> 10);
  91. return Result;
  92. }
  93. }
  94. }
  95. /*
  96. 三角波发生函数
  97. Time_Zero:起始时刻,单位ms
  98. Time1:上升结束点时刻,单位ms
  99. Time2:下降结束点时刻,单位ms
  100. PeakValue:Time1时刻输出值
  101. Time_Zero和Time2时刻输出为0
  102. */
  103. uint16_t TriangleWaveGenerate(uint32_t Time_Zero, uint16_t Time1, uint16_t Time2, uint16_t PeakValue)
  104. {
  105. uint32_t K1 , K2;
  106. uint32_t DiffTime;
  107. uint16_t Result = 0;
  108. K1 = PeakValue * 1000 / Time1;
  109. K2 = PeakValue * 1000 / (Time2 - Time1);
  110. DiffTime = HAL_GetTick() - Time_Zero;
  111. DiffTime %= Time2;
  112. if(DiffTime < Time1)
  113. {
  114. Result = DiffTime * K1 / 1000;
  115. }
  116. else if(DiffTime < Time2)
  117. {
  118. Result = (Time2 - DiffTime) * K2 / 1000;
  119. }
  120. return Result;
  121. }
  122. /*
  123. 方波发生函数
  124. Time_Zero:起始时刻,单位ms
  125. Time1:输出结束点时刻,单位ms
  126. Time2:输出PeakValue结束点时刻,单位ms
  127. PeakValue:Time1-Time2时刻输出值
  128. Time_Zero和Time2时刻输出为0
  129. */
  130. uint16_t SquareWaveGenerate(uint32_t Time_Zero, uint16_t Time1, uint16_t Time2, uint16_t PeakValue)
  131. {
  132. uint32_t DiffTime;
  133. uint16_t Result = 0;
  134. DiffTime = HAL_GetTick() - Time_Zero;
  135. DiffTime %= Time2;
  136. if(DiffTime < Time1)
  137. {
  138. Result = 0;
  139. }
  140. else if(DiffTime < Time2)
  141. {
  142. Result = PeakValue;
  143. }
  144. return Result;
  145. }
  146. /*
  147. 斜坡发生函数
  148. Time_Zero:起始时刻,单位ms
  149. Time1:输出结束点时刻,单位ms
  150. PeakValue:最终输出值
  151. */
  152. uint16_t RampWaveGenerate(uint32_t Time_Zero, uint16_t Time1, uint16_t PeakValue)
  153. {
  154. uint32_t DiffTime;
  155. uint32_t K;
  156. uint16_t Result = 0;
  157. K = PeakValue * 1000 / Time1;
  158. DiffTime = HAL_GetTick() - Time_Zero;
  159. if(DiffTime < Time1)
  160. {
  161. Result = DiffTime * K / 1000;
  162. }
  163. else
  164. {
  165. Result = PeakValue;
  166. }
  167. return Result;
  168. }
  169. /*
  170. 获取最大值
  171. */
  172. uint16_t GetMaxData(uint16_t* Array, uint16_t Length)
  173. {
  174. uint16_t TempData = 0, i;
  175. for(i=0; i<Length; i++)
  176. {
  177. if(TempData < Array[i])
  178. {
  179. TempData = Array[i];
  180. }
  181. }
  182. return TempData;
  183. }
  184. /*
  185. 获取最小值
  186. */
  187. uint16_t GetMinData(uint16_t* Array, uint16_t Length)
  188. {
  189. uint16_t TempData = 0xFFFF, i;
  190. for(i=0; i<Length; i++)
  191. {
  192. if(TempData > Array[i])
  193. {
  194. TempData = Array[i];
  195. }
  196. }
  197. return TempData;
  198. }
  199. /*
  200. 获取最大值、最小值、平均值
  201. */
  202. void GetMaxMinAvgData(uint16_t* Array, uint16_t Length, uint16_t* Max, uint16_t* Min, uint16_t* Avg)
  203. {
  204. uint16_t TempData1 = 0x00, TempData2 = 0xFFFF, i;
  205. uint32_t Sum;
  206. for(i=0; i<Length; i++)
  207. {
  208. //取大值
  209. if(TempData1 < Array[i])
  210. {
  211. TempData1 = Array[i];
  212. }
  213. //取小值
  214. if(TempData2 > Array[i])
  215. {
  216. TempData2 = Array[i];
  217. }
  218. //求和
  219. Sum += Array[i];
  220. }
  221. *Max = TempData1;
  222. *Min = TempData2;
  223. *Avg = Sum / Length;
  224. }
  225. /*
  226. 计算标准差
  227. */
  228. uint32_t GetStandardDeviation(uint16_t* Input, uint16_t Length)
  229. {
  230. uint16_t AvgData, i;
  231. int32_t Deviation = 0;
  232. int32_t DiffData = 0;
  233. AvgData = GetAverageData(Input, Length);
  234. for(i=0; i<Length; i++)
  235. {
  236. DiffData = (AvgData - Input[i]);
  237. Deviation += DiffData * DiffData;
  238. }
  239. DiffData = _sqrt(Deviation);
  240. return((uint32_t)DiffData);
  241. }
  242. /*
  243. 计算标准差,返回平均值
  244. */
  245. uint16_t Standard_deviation_aver(uint16_t *data,uint8_t len, uint16_t *pAver)
  246. {
  247. uint8_t i=0,j=0;
  248. float aver=0;
  249. double sum=0,deviation=0;
  250. for(i=0;i<len;i++)
  251. {
  252. sum+=data[i];
  253. }
  254. aver=sum/len;
  255. *pAver = aver;
  256. for(j=0;j<len;j++)
  257. {
  258. deviation+=(data[j]-aver)*(data[j]-aver);
  259. }
  260. //deviation = deviation / len;
  261. deviation=(uint16_t)sqrt(deviation);
  262. return deviation;
  263. }
  264. /*
  265. 检测数组中是否有重复数值
  266. */
  267. TrueOrFalse_Flag_Struct_t CheckIsHasDouble(uint8_t* Array, uint16_t Length)
  268. {
  269. uint16_t i = 0, j = 0;
  270. for (i = 0; i < Length; ++i)
  271. {
  272. for (j = i + 1; j < Length; ++j)
  273. {
  274. if (Array[i] == Array[j])
  275. {
  276. return TRUE;
  277. }
  278. }
  279. }
  280. return FALSE;
  281. }
  282. /******************************************************************************
  283. * @Function: uint32_t StepCalc(int16_t V_max, \
  284. int16_t V_Tc, \
  285. int16_t V_AccDecT)
  286. * @Discrible: 步进计算
  287. * @Param: V_max设定值最大值;V_Tc计算周期;V_AccDecT步进到最大值的总时间;
  288. * @Return: 步进值
  289. * @Others:
  290. ******************************************************************************
  291. * @Recode date version author modify
  292. * ------------------------------------------------------------------
  293. * 20180824 V1.1 Damon modify
  294. *
  295. *******************************************************************************/
  296. uint32_t StepCalc(int16_t V_max, \
  297. int16_t V_Tc, \
  298. int16_t V_AccDecT)
  299. {
  300. return ((uint32_t)V_max << 16) * V_Tc / V_AccDecT;
  301. }
  302. /******************************************************************************
  303. * @Function: int16_t accDecProcess(int16_t V_Set, \
  304. uint32_t V_AccStep, \
  305. uint32_t V_DecStep)
  306. * @Discrible: 任意量的加减速处理
  307. * @Param: 目标设定值;加速步进;减速步进;
  308. * @Return: 当前设定值
  309. * @Others:
  310. ******************************************************************************
  311. * @Recode date version author modify
  312. * ------------------------------------------------------------------
  313. * 20190815 V1.2 Damon modify
  314. *
  315. *******************************************************************************/
  316. int16_t accDecProcess(int16_t V_Set, \
  317. uint32_t V_AccStep, \
  318. uint32_t V_DecStep, \
  319. int32_t* V_SetMiddle)
  320. {
  321. int16_t Tmp16;
  322. int32_t Tmp32;
  323. int16_t V_Ret;
  324. Tmp32 = *V_SetMiddle;
  325. Tmp16 = (int16_t)( (*V_SetMiddle) >> 16);
  326. if(Tmp16 < V_Set) // 加速 是否需要加状态标志后面考虑
  327. {
  328. Tmp32 += V_AccStep;
  329. V_Ret = (int16_t)(Tmp32 >> 16);
  330. if(V_Ret > V_Set)
  331. {
  332. V_Ret = V_Set;
  333. Tmp32 = (int32_t) V_Ret << 16;
  334. }
  335. }
  336. else if(Tmp16 > V_Set) // 减速 是否需要加状态标志后面考虑
  337. {
  338. Tmp16 = ((int32_t) V_Set << 16) + V_DecStep;
  339. if(Tmp32 < Tmp16)
  340. {
  341. V_Ret = V_Set;
  342. Tmp32 = (int32_t) V_Ret << 16;
  343. }
  344. else
  345. {
  346. Tmp32 -= V_DecStep;
  347. V_Ret = (int16_t)(Tmp32 >> 16);
  348. if(V_Ret == 0)
  349. {
  350. Tmp32 = 0;
  351. }
  352. }
  353. }
  354. else // 稳速 是否需要加状态标志后面考虑
  355. {
  356. V_Ret = V_Set;
  357. }
  358. *V_SetMiddle = Tmp32;
  359. return V_Ret;
  360. }
  361. /*检查数组是否全部为0*/
  362. uint8_t CheckArrayIs0(uint8_t* Data, uint16_t Len)
  363. {
  364. uint16_t i;
  365. for(i=0; i<Len; i++)
  366. {
  367. if(Data[i] != 0)
  368. {
  369. return 1;
  370. }
  371. }
  372. return 0;
  373. }
  374. /*数组填充0*/
  375. void ArrayFillZero(uint16_t* Array, uint16_t Length)
  376. {
  377. uint16_t i;
  378. for(i=0; i<Length; i++)
  379. {
  380. Array[i] = 0;
  381. }
  382. }
  383. /*
  384. 滑动最大值滤波
  385. InputData:最新采集值
  386. Array:缓存队列
  387. Length:缓存大小
  388. 运行一次后,缓存队列最后一个数据为最新采集值,前面数据依次前移,返回值为缓存队列最大值
  389. */
  390. uint16_t MovingMaxFilter(uint16_t InputData, uint16_t* Array, uint16_t Length)
  391. {
  392. uint16_t Result, i;
  393. Result = GetMaxData(Array, Length);
  394. for(i = 0; i < (Length - 1); i++)
  395. {
  396. Array[i] = Array[i+1];
  397. }
  398. Array[Length - 1] = InputData;
  399. return Result;
  400. }