math_tools.c 7.3 KB

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