hall_sensor.c 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125
  1. /**********************************
  2. * 文件名称: hall_sensor.c
  3. * 功能描述: 霍尔传感器模块
  4. * 功能: 读取霍尔传感器信号,计算电机角度和速度
  5. **********************************/
  6. #include "main.h"
  7. #include "hall_sensor.h"
  8. #include "motor_define.h"
  9. #define SPEED_FILTER_DEPTH 8
  10. Hall_TypeDef Hall = {0}; // 全局实例
  11. Hall_TypeDef* Hall_Get(void)
  12. {
  13. return &Hall;
  14. }
  15. static float speed_history[SPEED_FILTER_DEPTH] = {0};
  16. static uint8_t speed_idx = 0;
  17. float Get_Filtered_Speed(void)
  18. {
  19. speed_history[speed_idx++] =(Hall.speed[0]+Hall.speed[1]+Hall.speed[2]+Hall.speed[3]+Hall.speed[4]+Hall.speed[5])/6.0f;
  20. if(speed_idx >= SPEED_FILTER_DEPTH) speed_idx = 0;
  21. float sum = 0;
  22. for(int i=0; i<SPEED_FILTER_DEPTH; i++)
  23. sum += speed_history[i];
  24. return sum / SPEED_FILTER_DEPTH;
  25. }
  26. /**
  27. * @brief TIM5中断处理函数
  28. * @note 处理霍尔传感器信号中断,计算电机角度和速度
  29. */
  30. void TIM5_IRQHandler(void)
  31. {
  32. if(TIM_GetFlagStatus(TIM5, TIM_FLAG_CC1) == SET)
  33. {
  34. Hall.ccr = (float)TIM_GetCapture1(TIM5);
  35. TIM_ClearFlag(TIM5, TIM_FLAG_CC1);
  36. Hall.state_last = Hall.state; // 记录上次状态
  37. uint8_t W = GPIO_ReadInputDataBit(HALL_CH3_GPIO_PORT, HALL_CH3_PIN); // 需要根据实际进行修改
  38. uint8_t V = GPIO_ReadInputDataBit(HALL_CH2_GPIO_PORT, HALL_CH2_PIN);
  39. uint8_t U = GPIO_ReadInputDataBit(HALL_CH1_GPIO_PORT, HALL_CH1_PIN);
  40. Hall.state = U; //计算扇区
  41. Hall.state |= V << 1;
  42. Hall.state |= W << 2;
  43. switch(Hall.state)
  44. {
  45. // CW 645132 CCW 623154
  46. case 0x06:
  47. Hall.theta[0] = 0.4506f;
  48. Hall.angle = Hall.theta[0];
  49. Hall.count[0] = Hall.ccr;
  50. Hall.speed[0] = (Hall.speed[0]+( 2.0f * PI + Hall.theta[0]-Hall.theta[5]) / (Hall.count[0] / HALL_SPEED_FACTOR))/2.0f; // 电弧度
  51. Hall.angle_add = Hall.speed[0] / HALL_SAMPLE_FREQ; // 速度乘电流环单次时间 速度*0.0001s 单次电流环插值间隔
  52. break;
  53. case 0x04:
  54. Hall.theta[1] = 0.4506f + PI / 3;
  55. Hall.angle = Hall.theta[1] ;
  56. Hall.count[1] = Hall.ccr;
  57. Hall.speed[1] = (Hall.speed[1]+(Hall.theta[1]-Hall.theta[0]) / (Hall.count[1] / HALL_SPEED_FACTOR))/2.0f;
  58. Hall.angle_add = Hall.speed[1] / HALL_SAMPLE_FREQ;
  59. break;
  60. case 0x05:
  61. Hall.theta[2] = 0.4506f + 2.0f * PI / 3;
  62. Hall.count[2] = Hall.ccr;
  63. Hall.angle = Hall.theta[2] ;
  64. Hall.speed[2] = (Hall.speed[2]+ (Hall.theta[2]-Hall.theta[1]) / (Hall.count[2] / HALL_SPEED_FACTOR))/2.0f;
  65. Hall.angle_add = Hall.speed[2] / HALL_SAMPLE_FREQ;
  66. break;
  67. case 0x01:
  68. Hall.theta[3] = 0.4506f + PI;
  69. Hall.angle = Hall.theta[3];
  70. Hall.count[3] = Hall.ccr;
  71. Hall.speed[3] = (Hall.speed[3] + (Hall.theta[3]-Hall.theta[2]) / (Hall.count[3] / HALL_SPEED_FACTOR))/2.0f;
  72. Hall.angle_add = Hall.speed[3] / HALL_SAMPLE_FREQ;
  73. break;
  74. case 0x03:
  75. Hall.theta[4] = 0.4506f + 4.0f * PI / 3;
  76. Hall.angle = Hall.theta[4] ;
  77. Hall.count[4] = Hall.ccr;
  78. Hall.speed[4] = (Hall.speed[4]+(Hall.theta[4]-Hall.theta[3]) / (Hall.count[4] / HALL_SPEED_FACTOR))/2.0f;
  79. Hall.angle_add = Hall.speed[4] / HALL_SAMPLE_FREQ;
  80. break;
  81. case 0x02:
  82. Hall.theta[5] = 0.4506f + 5.0f * PI / 3;
  83. Hall.angle = Hall.theta[5] ;
  84. Hall.count[5] = Hall.ccr;
  85. Hall.speed[5] = (Hall.speed[5]+ (Hall.theta[5]-Hall.theta[4]) / (Hall.count[5] / HALL_SPEED_FACTOR))/2.0f;
  86. Hall.angle_add = Hall.speed[5] / HALL_SAMPLE_FREQ;
  87. break;
  88. default: break;
  89. }
  90. }
  91. }
  92. // 电流环中调用的角度插值函数
  93. void Hall_Update_Interpolated_Angle(void)
  94. {
  95. static uint8_t last_state = 0xFF;
  96. // 检查状态是否变化
  97. if(Hall.state != last_state) {
  98. last_state = Hall.state;
  99. }
  100. else {
  101. // 状态未变化,累加角度
  102. Hall.angle += Hall.angle_add;
  103. }
  104. // 角度归一化
  105. if(Hall.angle >= 2*PI) Hall.angle -= 2*PI;
  106. if(Hall.angle < 0) Hall.angle += 2*PI;
  107. }