math_tools.c 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367
  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. Result = 1024 - (Th1 - InputData) * K1;
  50. }
  51. else if(InputData < Th2)
  52. {
  53. Result = 1024;
  54. }
  55. else
  56. {
  57. Result = 1024 - (InputData - Th2) * K2;
  58. }
  59. Result = (Result <= 0) ? 0 : Result;
  60. return (uint16_t)Result;
  61. }
  62. /*
  63. 系数增益计算
  64. InputData <= Th: y = Min + (Max - Min) / Th * InputData
  65. InputData > Th: y = Max;
  66. Min, Max均放大1024倍
  67. */
  68. uint16_t Coefficient_GainCal(uint16_t Min, uint16_t Max, uint16_t Th, uint16_t InputData)
  69. {
  70. uint16_t Result;
  71. uint16_t K;
  72. //计算K
  73. K = (Max - Min) * 1024 / Th;
  74. if(InputData > Th)
  75. {
  76. Result = Max;
  77. return Result;
  78. }
  79. else
  80. {
  81. Result = Min + (K * InputData >> 10);
  82. return Result;
  83. }
  84. }
  85. /*
  86. 三角波发生函数
  87. Time_Zero:起始时刻,单位ms
  88. Time1:上升结束点时刻,单位ms
  89. Time2:下降结束点时刻,单位ms
  90. PeakValue:Time1时刻输出值
  91. Time_Zero和Time2时刻输出为0
  92. */
  93. uint16_t TriangleWaveGenerate(uint32_t Time_Zero, uint16_t Time1, uint16_t Time2, uint16_t PeakValue)
  94. {
  95. uint32_t K1 , K2;
  96. uint32_t DiffTime;
  97. uint16_t Result = 0;
  98. K1 = PeakValue * 1000 / Time1;
  99. K2 = PeakValue * 1000 / (Time2 - Time1);
  100. DiffTime = HAL_GetTick() - Time_Zero;
  101. DiffTime %= Time2;
  102. if(DiffTime < Time1)
  103. {
  104. Result = DiffTime * K1 / 1000;
  105. }
  106. else if(DiffTime < Time2)
  107. {
  108. Result = (Time2 - DiffTime) * K2 / 1000;
  109. }
  110. return Result;
  111. }
  112. /*
  113. 方波发生函数
  114. Time_Zero:起始时刻,单位ms
  115. Time1:输出结束点时刻,单位ms
  116. Time2:输出PeakValue结束点时刻,单位ms
  117. PeakValue:Time1-Time2时刻输出值
  118. Time_Zero和Time2时刻输出为0
  119. */
  120. uint16_t SquareWaveGenerate(uint32_t Time_Zero, uint16_t Time1, uint16_t Time2, uint16_t PeakValue)
  121. {
  122. uint32_t DiffTime;
  123. uint16_t Result = 0;
  124. DiffTime = HAL_GetTick() - Time_Zero;
  125. DiffTime %= Time2;
  126. if(DiffTime < Time1)
  127. {
  128. Result = 0;
  129. }
  130. else if(DiffTime < Time2)
  131. {
  132. Result = PeakValue;
  133. }
  134. return Result;
  135. }
  136. /*
  137. 斜坡发生函数
  138. Time_Zero:起始时刻,单位ms
  139. Time1:输出结束点时刻,单位ms
  140. PeakValue:最终输出值
  141. */
  142. uint16_t RampWaveGenerate(uint32_t Time_Zero, uint16_t Time1, uint16_t PeakValue)
  143. {
  144. uint32_t DiffTime;
  145. uint32_t K;
  146. uint16_t Result = 0;
  147. K = PeakValue * 1000 / Time1;
  148. DiffTime = HAL_GetTick() - Time_Zero;
  149. if(DiffTime < Time1)
  150. {
  151. Result = DiffTime * K / 1000;
  152. }
  153. else
  154. {
  155. Result = PeakValue;
  156. }
  157. return Result;
  158. }
  159. /*
  160. 获取最大值
  161. */
  162. uint16_t GetMaxData(uint16_t* Array, uint16_t Length)
  163. {
  164. uint16_t TempData = 0, i;
  165. for(i=0; i<Length; i++)
  166. {
  167. if(TempData < Array[i])
  168. {
  169. TempData = Array[i];
  170. }
  171. }
  172. return TempData;
  173. }
  174. /*
  175. 获取最小值
  176. */
  177. uint16_t GetMinData(uint16_t* Array, uint16_t Length)
  178. {
  179. uint16_t TempData = 0xFFFF, i;
  180. for(i=0; i<Length; i++)
  181. {
  182. if(TempData > Array[i])
  183. {
  184. TempData = Array[i];
  185. }
  186. }
  187. return TempData;
  188. }
  189. /*
  190. 计算标准差
  191. */
  192. uint32_t GetStandardDeviation(uint16_t* Input, uint16_t Length)
  193. {
  194. uint16_t AvgData, i;
  195. int32_t Deviation = 0;
  196. int32_t DiffData = 0;
  197. AvgData = GetAverageData(Input, Length);
  198. for(i=0; i<Length; i++)
  199. {
  200. DiffData = (AvgData - Input[i]);
  201. Deviation += DiffData * DiffData;
  202. }
  203. DiffData = _sqrt(Deviation);
  204. return((uint32_t)DiffData);
  205. }
  206. /*
  207. 计算标准差,返回平均值
  208. */
  209. uint16_t Standard_deviation_aver(uint16_t *data,uint8_t len, uint16_t *pAver)
  210. {
  211. uint8_t i=0,j=0;
  212. float aver=0;
  213. double sum=0,deviation=0;
  214. for(i=0;i<len;i++)
  215. {
  216. sum+=data[i];
  217. }
  218. aver=sum/len;
  219. *pAver = aver;
  220. for(j=0;j<len;j++)
  221. {
  222. deviation+=(data[j]-aver)*(data[j]-aver);
  223. }
  224. //deviation = deviation / len;
  225. deviation=(uint16_t)sqrt(deviation);
  226. return deviation;
  227. }
  228. /*
  229. 检测数组中是否有重复数值
  230. */
  231. TrueOrFalse_Flag_Struct_t CheckIsHasDouble(uint8_t* Array, uint16_t Length)
  232. {
  233. uint16_t i = 0, j = 0;
  234. for (i = 0; i < Length; ++i)
  235. {
  236. for (j = i + 1; j < Length; ++j)
  237. {
  238. if (Array[i] == Array[j])
  239. {
  240. return TRUE;
  241. }
  242. }
  243. }
  244. return FALSE;
  245. }
  246. /******************************************************************************
  247. * @Function: uint32_t StepCalc(int16_t V_max, \
  248. int16_t V_Tc, \
  249. int16_t V_AccDecT)
  250. * @Discrible: 步进计算
  251. * @Param: V_max设定值最大值;V_Tc计算周期;V_AccDecT步进到最大值的总时间;
  252. * @Return: 步进值
  253. * @Others:
  254. ******************************************************************************
  255. * @Recode date version author modify
  256. * ------------------------------------------------------------------
  257. * 20180824 V1.1 Damon modify
  258. *
  259. *******************************************************************************/
  260. uint32_t StepCalc(int16_t V_max, \
  261. int16_t V_Tc, \
  262. int16_t V_AccDecT)
  263. {
  264. return ((uint32_t)V_max << 16) * V_Tc / V_AccDecT;
  265. }
  266. /******************************************************************************
  267. * @Function: int16_t accDecProcess(int16_t V_Set, \
  268. uint32_t V_AccStep, \
  269. uint32_t V_DecStep)
  270. * @Discrible: 任意量的加减速处理
  271. * @Param: 目标设定值;加速步进;减速步进;
  272. * @Return: 当前设定值
  273. * @Others:
  274. ******************************************************************************
  275. * @Recode date version author modify
  276. * ------------------------------------------------------------------
  277. * 20190815 V1.2 Damon modify
  278. *
  279. *******************************************************************************/
  280. int16_t accDecProcess(int16_t V_Set, \
  281. uint32_t V_AccStep, \
  282. uint32_t V_DecStep, \
  283. int32_t* V_SetMiddle)
  284. {
  285. int16_t Tmp16;
  286. int32_t Tmp32;
  287. int16_t V_Ret;
  288. Tmp32 = *V_SetMiddle;
  289. Tmp16 = (int16_t)( (*V_SetMiddle) >> 16);
  290. if(Tmp16 < V_Set) // 加速 是否需要加状态标志后面考虑
  291. {
  292. Tmp32 += V_AccStep;
  293. V_Ret = (int16_t)(Tmp32 >> 16);
  294. if(V_Ret > V_Set)
  295. {
  296. V_Ret = V_Set;
  297. Tmp32 = (int32_t) V_Ret << 16;
  298. }
  299. }
  300. else if(Tmp16 > V_Set) // 减速 是否需要加状态标志后面考虑
  301. {
  302. Tmp16 = ((int32_t) V_Set << 16) + V_DecStep;
  303. if(Tmp32 < Tmp16)
  304. {
  305. V_Ret = V_Set;
  306. Tmp32 = (int32_t) V_Ret << 16;
  307. }
  308. else
  309. {
  310. Tmp32 -= V_DecStep;
  311. V_Ret = (int16_t)(Tmp32 >> 16);
  312. if(V_Ret == 0)
  313. {
  314. Tmp32 = 0;
  315. }
  316. }
  317. }
  318. else // 稳速 是否需要加状态标志后面考虑
  319. {
  320. V_Ret = V_Set;
  321. }
  322. *V_SetMiddle = Tmp32;
  323. return V_Ret;
  324. }