cadence_sensor.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377
  1. #include "cadence_sensor.h"
  2. #include "adc.h"
  3. //局部变量定义
  4. const uint8_t ForwardDir_EncoderData[4] = {2,0,3,1};//判断正转用的编码顺序表,正转时信号为:2,0,1,3
  5. const uint8_t BackwardDir_EncoderData[4] = {1,3,0,2};//判断反转用的编码顺序表,反转时信号为:3,1,0,2
  6. //全局变量定义
  7. MC_CadenceResult_Struct_t MC_CadenceResult = {0, MC_Cadence_Stop, TRUE, 0};
  8. uint16_t MC_Cadence_Array[10] = {0};
  9. /**************************局部函数定义*************************/
  10. uint16_t torqueFilteredThroughCadence(uint16_t torque_temp, uint8_t modeFlag);
  11. /**************************全局函数定义*************************/
  12. uint8_t Cadence_ReadHallState(void)
  13. {
  14. uint8_t CadenceValue;
  15. GPIO_PinState hall_a, hall_b;
  16. hall_a = HAL_GPIO_ReadPin(CADENCE_2_GPIO_Port, CADENCE_2_Pin);
  17. CadenceValue = (uint8_t)hall_a;
  18. hall_b = HAL_GPIO_ReadPin(CADENCE_1_GPIO_Port, CADENCE_1_Pin);
  19. CadenceValue |= (uint8_t)hall_b << 1;
  20. return(CadenceValue & 0x03);
  21. }
  22. //踏频传感器IO初始化
  23. void CadenceSensor_GPIO_Init(void)
  24. {
  25. GPIO_InitTypeDef GPIO_InitStruct;
  26. __HAL_RCC_GPIOA_CLK_ENABLE();
  27. __HAL_RCC_GPIOB_CLK_ENABLE();
  28. GPIO_InitStruct.Pin = CADENCE_1_Pin;
  29. GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
  30. GPIO_InitStruct.Pull = GPIO_PULLUP;
  31. HAL_GPIO_Init(CADENCE_1_GPIO_Port, &GPIO_InitStruct);
  32. GPIO_InitStruct.Pin = CADENCE_2_Pin;
  33. GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
  34. GPIO_InitStruct.Pull = GPIO_PULLUP;
  35. HAL_GPIO_Init(CADENCE_2_GPIO_Port, &GPIO_InitStruct);
  36. }
  37. //踏频传感器检测处理
  38. void CadenceSensor_Process1(MC_CadenceResult_Struct_t* p_MC_CadenceResult, uint16_t StopDelayTime, uint8_t StarCount, TrueOrFalse_Flag_Struct_t UpSlopeFlag)
  39. {
  40. static MC_CadenceSensorStatus_Struct_t MC_CadenceSensorStatus;
  41. static TrueOrFalse_Flag_Struct_t IsFirstEnterFalg = TRUE;
  42. uint8_t CadenceHallStatus1, CadenceHallStatus2, CadenceHallStatus3;
  43. //读取霍尔信号
  44. CadenceHallStatus1 = Cadence_ReadHallState();
  45. CadenceHallStatus2 = Cadence_ReadHallState();
  46. CadenceHallStatus3 = Cadence_ReadHallState();
  47. //连续采集三次霍尔,三次状态都一致才更新霍尔状态,防us级干扰
  48. if( (CadenceHallStatus1==CadenceHallStatus2)&&(CadenceHallStatus2==CadenceHallStatus3) )
  49. {
  50. MC_CadenceSensorStatus.HallGropuStatus = CadenceHallStatus3;
  51. }
  52. if(IsFirstEnterFalg == TRUE)
  53. {
  54. MC_CadenceSensorStatus.HallGropuStatus_Old = MC_CadenceSensorStatus.HallGropuStatus;
  55. IsFirstEnterFalg = FALSE;
  56. }
  57. //判断踏频正反转,踏频信号触发计数
  58. static uint16_t BackwordDelayCnt1 = 0;
  59. static uint16_t BackwordDelayCnt2 = 0;
  60. if(MC_CadenceSensorStatus.HallGropuStatus != MC_CadenceSensorStatus.HallGropuStatus_Old)
  61. {
  62. if(MC_CadenceSensorStatus.HallGropuStatus_Old == ForwardDir_EncoderData[MC_CadenceSensorStatus.HallGropuStatus & 0x03])//上一次的编码,与正转的编码顺序一致,则为正转
  63. {
  64. //正转
  65. p_MC_CadenceResult->Cadence_Dir = MC_Cadence_Forward;
  66. BackwordDelayCnt1 = 0;
  67. BackwordDelayCnt2 = 0;
  68. //踏频信号计数
  69. p_MC_CadenceResult->TrigCount++;
  70. }
  71. else if(MC_CadenceSensorStatus.HallGropuStatus_Old == BackwardDir_EncoderData[MC_CadenceSensorStatus.HallGropuStatus & 0x03])//反转做延时判断
  72. {
  73. //反转
  74. BackwordDelayCnt1++;
  75. if(BackwordDelayCnt1 >= 4)//检测到连续4次反向脉冲则判断为反转,约4/120*360=12度
  76. {
  77. p_MC_CadenceResult->Cadence_Dir = MC_Cadence_Backward;
  78. BackwordDelayCnt1 = 0;
  79. }
  80. }
  81. else//蹋频波形异常情况下,延时判断为反转
  82. {
  83. //反转
  84. BackwordDelayCnt2++;
  85. if(BackwordDelayCnt2 > 10)
  86. {
  87. p_MC_CadenceResult->Cadence_Dir = MC_Cadence_Backward;
  88. BackwordDelayCnt2 = 0;
  89. }
  90. }
  91. }
  92. //踏频计算及启动和停止判断
  93. static uint32_t CadenceCalTimeCnt = 0; //用于计算蹋频值
  94. static int32_t Cadence_ActiveFlt = 0;
  95. static uint16_t CadenceTemp;
  96. static uint8_t CadenceStarFlagCnt = 0; //用于判断启动
  97. static uint32_t CadenceStopJudgeTimeCnt = 0; //用于判断停止
  98. uint8_t CadenceStartThresholdValue = 2; //踏频启动阈值,霍尔信号数,6度/个
  99. if((MC_CadenceSensorStatus.HallGropuStatus & 0x01) != (MC_CadenceSensorStatus.HallGropuStatus_Old & 0x01))
  100. {
  101. //踏频计算及滤波处理
  102. CadenceTemp = 1000 / (HAL_GetTick() - CadenceCalTimeCnt);//转1圈有60个信号,根据两个信号之间的时间计算踏频值rpm
  103. CadenceCalTimeCnt = HAL_GetTick();
  104. // Cadence_ActiveFlt += (((int32_t)CadenceTemp << 8) - Cadence_ActiveFlt) >> 4;
  105. // p_MC_CadenceResult->Cadence_Data = (uint8_t)(Cadence_ActiveFlt >> 8);
  106. /*上坡时,启动阈值为1*/
  107. if(UpSlopeFlag == TRUE)
  108. {
  109. CadenceStartThresholdValue = 1;
  110. }
  111. else
  112. {
  113. CadenceStartThresholdValue = StarCount;
  114. }
  115. //起步判断
  116. if(p_MC_CadenceResult->Cadence_Dir == MC_Cadence_Forward)
  117. {
  118. CadenceStarFlagCnt++;
  119. if(CadenceStarFlagCnt >= CadenceStartThresholdValue)
  120. {
  121. p_MC_CadenceResult->IsStopFlag = FALSE;
  122. }
  123. }
  124. else
  125. {
  126. p_MC_CadenceResult->IsStopFlag = TRUE;
  127. }
  128. /*根据踏频的信号,对力矩进行滤波处理*/
  129. p_MC_CadenceResult->torqueByCadence = torqueFilteredThroughCadence(ADC_SensorData.TorqueSensor,1);
  130. //更新停机计时数值
  131. CadenceStopJudgeTimeCnt = HAL_GetTick();
  132. }
  133. Cadence_ActiveFlt += (((int32_t)CadenceTemp << 10) - Cadence_ActiveFlt) >> 8;
  134. p_MC_CadenceResult->Cadence_Data = (uint8_t)(Cadence_ActiveFlt >> 10);
  135. //停机判断
  136. /*
  137. n < 20rpm, k = 3
  138. n > 40rpm, k = 1
  139. 20rpm <= n <= 40rpm, k = -0.1 * n + 5
  140. */
  141. uint16_t k = 100;
  142. k = (CadenceTemp < 20) ? 300 : ((CadenceTemp > 40) ? 100 : (500 - CadenceTemp * 10));
  143. StopDelayTime = k * StopDelayTime / 100;
  144. if((HAL_GetTick() - CadenceStopJudgeTimeCnt) > StopDelayTime)
  145. {
  146. p_MC_CadenceResult->IsStopFlag = TRUE;
  147. p_MC_CadenceResult->Cadence_Dir = MC_Cadence_Stop;
  148. p_MC_CadenceResult->Cadence_Data = 0;
  149. CadenceTemp = 0;
  150. Cadence_ActiveFlt = 0;
  151. CadenceStarFlagCnt =0;
  152. /*清零相关变量*/
  153. p_MC_CadenceResult->torqueByCadence = torqueFilteredThroughCadence(ADC_SensorData.TorqueSensor,0);
  154. }
  155. MC_CadenceSensorStatus.HallGropuStatus_Old = MC_CadenceSensorStatus.HallGropuStatus;
  156. }
  157. void CadenceSensor_Process2(MC_CadenceResult_Struct_t* p_MC_CadenceResult, uint16_t StopDelayTime, uint8_t StarCount, TrueOrFalse_Flag_Struct_t UpSlopeFlag)
  158. {
  159. static MC_CadenceSensorStatus_Struct_t MC_CadenceSensorStatus;
  160. static TrueOrFalse_Flag_Struct_t IsFirstEnterFalg = TRUE;
  161. uint8_t CadenceHallStatus1, CadenceHallStatus2, CadenceHallStatus3;
  162. //读取霍尔信号
  163. CadenceHallStatus1 = Cadence_ReadHallState();
  164. CadenceHallStatus2 = Cadence_ReadHallState();
  165. CadenceHallStatus3 = Cadence_ReadHallState();
  166. //连续采集三次霍尔,三次状态都一致才更新霍尔状态,防us级干扰
  167. if( (CadenceHallStatus1==CadenceHallStatus2)&&(CadenceHallStatus2==CadenceHallStatus3) )
  168. {
  169. MC_CadenceSensorStatus.HallGropuStatus = CadenceHallStatus3;
  170. }
  171. if(IsFirstEnterFalg == TRUE)
  172. {
  173. MC_CadenceSensorStatus.HallGropuStatus_Old = MC_CadenceSensorStatus.HallGropuStatus;
  174. IsFirstEnterFalg = FALSE;
  175. }
  176. //正反转判断
  177. if(MC_CadenceSensorStatus.HallGropuStatus != MC_CadenceSensorStatus.HallGropuStatus_Old)
  178. {
  179. static uint16_t BackwordDelayCnt1 = 0;
  180. if((MC_CadenceSensorStatus.HallGropuStatus & 0x02) == 0x02) //正转
  181. {
  182. p_MC_CadenceResult->Cadence_Dir = MC_Cadence_Forward;
  183. BackwordDelayCnt1 = 0;
  184. }
  185. else //反转
  186. {
  187. BackwordDelayCnt1++;
  188. if(BackwordDelayCnt1 >= 4)//检测到连续4次反向脉冲则判断为反转,约4/120*360=12度
  189. {
  190. p_MC_CadenceResult->Cadence_Dir = MC_Cadence_Backward;
  191. BackwordDelayCnt1 = 0;
  192. }
  193. }
  194. }
  195. //踏频计算与停止判断
  196. static uint32_t CadenceCalTimeCnt = 0; //用于计算蹋频值
  197. static int32_t Cadence_ActiveFlt = 0;
  198. static uint16_t CadenceTemp;
  199. static uint8_t CadenceStarFlagCnt = 0; //用于判断启动
  200. static uint32_t CadenceStopJudgeTimeCnt = 0; //用于判断停止
  201. uint8_t CadenceStartThresholdValue = 2; //踏频启动阈值,霍尔信号数,6度/个
  202. if((MC_CadenceSensorStatus.HallGropuStatus & 0x01) != (MC_CadenceSensorStatus.HallGropuStatus_Old & 0x01))
  203. {
  204. //踏频计算及滤波处理
  205. CadenceTemp = 500 / (HAL_GetTick() - CadenceCalTimeCnt);//转1圈有120个信号,根据两个信号之间的时间计算踏频值rpm
  206. CadenceCalTimeCnt = HAL_GetTick();
  207. /*上坡时,启动阈值为1*/
  208. if(UpSlopeFlag == TRUE)
  209. {
  210. CadenceStartThresholdValue = 1;
  211. }
  212. else
  213. {
  214. CadenceStartThresholdValue = StarCount;
  215. }
  216. //起步判断
  217. if(p_MC_CadenceResult->Cadence_Dir == MC_Cadence_Forward)
  218. {
  219. CadenceStarFlagCnt++;
  220. if(CadenceStarFlagCnt >= CadenceStartThresholdValue)
  221. {
  222. p_MC_CadenceResult->IsStopFlag = FALSE;
  223. }
  224. }
  225. else
  226. {
  227. p_MC_CadenceResult->IsStopFlag = TRUE;
  228. }
  229. /*根据踏频的信号,对力矩进行滤波处理*/
  230. p_MC_CadenceResult->torqueByCadence = torqueFilteredThroughCadence(ADC_SensorData.TorqueSensor,1);
  231. //更新停机计时数值
  232. CadenceStopJudgeTimeCnt = HAL_GetTick();
  233. p_MC_CadenceResult->TrigCount++;
  234. }
  235. Cadence_ActiveFlt += (((int32_t)CadenceTemp << 10) - Cadence_ActiveFlt) >> 8;
  236. p_MC_CadenceResult->Cadence_Data = (uint8_t)(Cadence_ActiveFlt >> 10);
  237. //停机判断
  238. /*
  239. n < 20rpm, k = 3
  240. n > 40rpm, k = 1
  241. 20rpm <= n <= 40rpm, k = -0.1 * n + 5
  242. */
  243. uint16_t k = 100;
  244. k = (CadenceTemp < 20) ? 300 : ((CadenceTemp > 40) ? 100 : (500 - CadenceTemp * 10));
  245. StopDelayTime = k * StopDelayTime / 100;
  246. if((HAL_GetTick() - CadenceStopJudgeTimeCnt) > StopDelayTime)
  247. {
  248. p_MC_CadenceResult->IsStopFlag = TRUE;
  249. p_MC_CadenceResult->Cadence_Dir = MC_Cadence_Stop;
  250. p_MC_CadenceResult->Cadence_Data = 0;
  251. CadenceTemp = 0;
  252. Cadence_ActiveFlt = 0;
  253. CadenceStarFlagCnt =0;
  254. /*清零相关变量*/
  255. p_MC_CadenceResult->torqueByCadence = torqueFilteredThroughCadence(ADC_SensorData.TorqueSensor,0);
  256. }
  257. MC_CadenceSensorStatus.HallGropuStatus_Old = MC_CadenceSensorStatus.HallGropuStatus;
  258. }
  259. uint16_t torqueFilteredThroughCadence(uint16_t torque_temp, uint8_t modeFlag)
  260. {
  261. #define T_FIFO_LENGTH 30 //每个信号6度,30为180度
  262. static uint16_t T_FIFO[T_FIFO_LENGTH]={0};
  263. static uint8_t T_Index=0;
  264. static uint32_t T_sum=0;
  265. static uint8_t filter_status_falg=0;
  266. uint16_t result_filtered=0;
  267. if( modeFlag != 0 )
  268. {
  269. /*根据踏频信号,采样最近180度内力矩平均值*/
  270. if(filter_status_falg != 0)
  271. {
  272. T_sum -= T_FIFO[T_Index];
  273. T_sum += torque_temp;
  274. T_FIFO[T_Index] = torque_temp;
  275. }
  276. T_Index++;
  277. if(T_Index >= T_FIFO_LENGTH)
  278. {
  279. T_Index = 0;
  280. if(filter_status_falg == 0)
  281. {
  282. filter_status_falg = 1;
  283. }
  284. else if(filter_status_falg == 1)
  285. {
  286. filter_status_falg = 2;
  287. }
  288. }
  289. if(filter_status_falg == 2)
  290. {
  291. result_filtered = T_sum / T_FIFO_LENGTH;
  292. }
  293. else if(filter_status_falg == 1)
  294. {
  295. /*启动后的前180度-360度,根据实际数据个数求平均值*/
  296. if(T_Index == 0)
  297. {
  298. result_filtered = torque_temp;
  299. }
  300. else
  301. {
  302. result_filtered = T_sum / T_Index;
  303. }
  304. }
  305. else
  306. {
  307. /*启动后的前180度,使用实时值*/
  308. result_filtered = torque_temp;
  309. }
  310. /*力矩实时值低于滤波值的五分之一,使用实时值*/
  311. if(torque_temp < (result_filtered/5) )
  312. {
  313. result_filtered = torque_temp;
  314. }
  315. /*踏频信号采样*/
  316. }
  317. else
  318. {
  319. /*清零变量*/
  320. for(uint8_t i=0;i<T_FIFO_LENGTH;i++)
  321. {
  322. T_FIFO[i] = 0;
  323. }
  324. T_Index = 0;
  325. T_sum = 0;
  326. filter_status_falg=0;
  327. }
  328. return result_filtered;
  329. }