image.png

freertos初始化

  1. void MX_FREERTOS_Init(void) {
  2. /* USER CODE BEGIN Init */
  3. xTaskCreate(OpenLoopPosControlTask, "OpenPos", 64, NULL, 6, &openLoopPosControlTaskHandle);
  4. vTaskSuspend(openLoopPosControlTaskHandle);
  5. xTaskCreate(OpenLoopVelControlTask, "OpenVel", 64, NULL, 6, &openLoopVelControlTaskHandle);
  6. vTaskSuspend(openLoopVelControlTaskHandle);
  7. xTaskCreate(TorqueControlTask, "TorCtrl", 128, NULL, 6, &torqueControlTaskHandle);
  8. vTaskSuspend(torqueControlTaskHandle);
  9. xTaskCreate(VelocityControlTask, "VelCtrl", 64, NULL, 6, &velocityControlTaskHandle);
  10. vTaskSuspend(velocityControlTaskHandle);
  11. xTaskCreate(PositionControlTask, "PosCtrl", 64, NULL, 6, &positionControlTaskHandle);
  12. vTaskSuspend(positionControlTaskHandle);
  13. xTaskCreate(SpringTask, "Spring", 64, NULL, 6, &springTaskHandle);
  14. vTaskSuspend(springTaskHandle);
  15. xTaskCreate(KnobTask, "Knob", 64, NULL, 6, &knobTaskHandle);
  16. vTaskSuspend(knobTaskHandle);
  17. xTaskCreate(TaskSelectTask, "Select", 64, NULL, 6, &taskSelectTaskHandle);
  18. /* USER CODE END Init */
  19. /* USER CODE BEGIN RTOS_MUTEX */
  20. /* add mutexes, ... */
  21. /* USER CODE END RTOS_MUTEX */
  22. /* USER CODE BEGIN RTOS_SEMAPHORES */
  23. /* add semaphores, ... */
  24. /* USER CODE END RTOS_SEMAPHORES */
  25. /* USER CODE BEGIN RTOS_TIMERS */
  26. /* start timers, add new ones, ... */
  27. /* USER CODE END RTOS_TIMERS */
  28. /* USER CODE BEGIN RTOS_QUEUES */
  29. /* add queues, ... */
  30. /* USER CODE END RTOS_QUEUES */
  31. /* Create the thread(s) */
  32. /* definition and creation of defaultTask */
  33. osThreadDef(defaultTask, StartDefaultTask, osPriorityIdle, 0, 64);
  34. defaultTaskHandle = osThreadCreate(osThread(defaultTask), NULL);
  35. /* USER CODE BEGIN RTOS_THREADS */
  36. /* add threads, ... */
  37. /* USER CODE END RTOS_THREADS */
  38. }

多任务

  1. void TaskSelectTask(void *argument) {
  2. FOC_CONTROL_MODE mode = OPEN_LOOP_POSITION_CONTROL;
  3. portENTER_CRITICAL();
  4. gui_draw_mode_selection(mode);
  5. portEXIT_CRITICAL();
  6. TickType_t xLastWakeTime = xTaskGetTickCount();
  7. HAL_GPIO_WritePin(LED_GPIO_Port, LED_Pin, GPIO_PIN_SET);
  8. while (1) {
  9. if (button_press_pending_flag) {
  10. if (button_left_press_pending_flag) {
  11. if (mode) mode--;
  12. else mode = FOC_CONTROL_MODE_NUM - 1;
  13. gui_draw_mode_selection(mode);
  14. } else if (button_right_press_pending_flag) {
  15. mode++;
  16. if (mode > FOC_CONTROL_MODE_NUM - 1) mode = 0;
  17. gui_draw_mode_selection(mode);
  18. } else if (button_confirm_press_pending_flag) {
  19. switch (mode) {
  20. case OPEN_LOOP_POSITION_CONTROL:
  21. SuspendToRunOtherTask(openLoopPosControlTaskHandle);
  22. break;
  23. case OPEN_LOOP_SPEED_CONTROL:
  24. SuspendToRunOtherTask(openLoopVelControlTaskHandle);
  25. break;
  26. case TORQUE_CONTROL:
  27. SuspendToRunOtherTask(torqueControlTaskHandle);
  28. break;
  29. case SPEED_CONTROL:
  30. SuspendToRunOtherTask(velocityControlTaskHandle);
  31. break;
  32. case POSITION_CONTROL:;
  33. SuspendToRunOtherTask(positionControlTaskHandle);
  34. break;
  35. case SPRING:
  36. spring_pid = &pid_spring;
  37. SuspendToRunOtherTask(springTaskHandle);
  38. break;
  39. case SPRING_WITH_DAMP:
  40. spring_pid = &pid_spring_with_damp;
  41. SuspendToRunOtherTask(springTaskHandle);
  42. break;
  43. case DAMP:
  44. spring_pid = &pid_damp;
  45. SuspendToRunOtherTask(springTaskHandle);
  46. break;
  47. case KNOB:
  48. SuspendToRunOtherTask(knobTaskHandle);
  49. break;
  50. case ZERO_RESISTANCE:
  51. spring_pid = &pid_zero_resistance;
  52. SuspendToRunOtherTask(springTaskHandle);
  53. break;
  54. }
  55. gui_draw_mode_selection(mode);
  56. continue;
  57. }
  58. button_reset_all_flags();
  59. }
  60. vTaskDelayUntil(&xLastWakeTime,
  61. 10);
  62. }
  63. }

每一个任务函数

  1. void OpenLoopPosControlTask(void *argument) {
  2. float angle = 0, Ud = 1;
  3. TickType_t xLastWakeTime = xTaskGetTickCount();
  4. while (1) {
  5. if (button_press_pending_flag) {
  6. if (button_left_press_pending_flag) {
  7. angle -= _PI_2;
  8. } else if (button_right_press_pending_flag) {
  9. angle += _PI_2;
  10. } else if (button_cancel_press_pending_flag) {
  11. SuspendToRunOtherTask(taskSelectTaskHandle);
  12. continue;
  13. }
  14. button_reset_all_flags();
  15. }
  16. FOC_SVPWM(0, Ud, angle);
  17. vTaskDelayUntil(&xLastWakeTime,
  18. 1); // every FOC control task need at least 1ms delay otherwise cannot detect key press normally
  19. }
  20. }
  21. void OpenLoopVelControlTask(void *argument) {
  22. float angle = 0, Ud = 1, delta_angle = 0;
  23. TickType_t xLastWakeTime = xTaskGetTickCount();
  24. while (1) {
  25. if (button_press_pending_flag) {
  26. if (button_left_press_pending_flag) {
  27. delta_angle -= 0.01;
  28. if (delta_angle < -_PI) delta_angle = -_PI;
  29. } else if (button_right_press_pending_flag) {
  30. delta_angle += 0.01;
  31. if (delta_angle > _PI) delta_angle = _PI;
  32. } else if (button_cancel_press_pending_flag) {
  33. SuspendToRunOtherTask(taskSelectTaskHandle);
  34. continue;
  35. }
  36. button_reset_all_flags();
  37. }
  38. angle += delta_angle;
  39. FOC_SVPWM(0, Ud, angle);
  40. vTaskDelayUntil(&xLastWakeTime,
  41. 1); // every FOC control task need at least 1ms delay otherwise cannot detect key press normally
  42. }
  43. }
  44. #ifdef FOC_MODE_VOLTAGE_CONTROL
  45. void TorqueControlTask(void *argument) {
  46. TickType_t xLastWakeTime = xTaskGetTickCount();
  47. float Uq = 0;
  48. while (1) {
  49. if (button_press_pending_flag) {
  50. if (button_left_press_pending_flag) {
  51. Uq -= 1.0;
  52. } else if (button_right_press_pending_flag) {
  53. Uq += 1.0;
  54. } else if (button_cancel_press_pending_flag) {
  55. SuspendToRunOtherTask(taskSelectTaskHandle);
  56. continue;
  57. }
  58. button_reset_all_flags();
  59. }
  60. FOC_open_loop_voltage_control_loop(Uq);
  61. vTaskDelayUntil(&xLastWakeTime,
  62. 1); // every FOC control task need at least 1ms delay otherwise cannot detect key press normally
  63. }
  64. }
  65. #endif
  66. #ifdef FOC_MODE_CURRENT_CONTROL
  67. void TorqueControlTask(void *argument) {
  68. TickType_t xLastWakeTime = xTaskGetTickCount();
  69. float Iq = 0;
  70. while (1) {
  71. if (button_press_pending_flag) {
  72. if (button_left_press_pending_flag) {
  73. Iq -= 100.0;
  74. } else if (button_right_press_pending_flag) {
  75. Iq += 100.0;
  76. } else if (button_cancel_press_pending_flag) {
  77. SuspendToRunOtherTask(taskSelectTaskHandle);
  78. continue;
  79. }
  80. button_reset_all_flags();
  81. }
  82. FOC_current_control_loop(Iq);
  83. //vTaskDelayUntil(&xLastWakeTime,
  84. // 1); // every FOC control task need at least 1ms delay otherwise cannot detect key press normally
  85. }
  86. }
  87. #endif
  88. void VelocityControlTask(void *argument) {
  89. float velocity = 0;
  90. TickType_t xLastWakeTime = xTaskGetTickCount();
  91. while (1) {
  92. if (button_press_pending_flag) {
  93. if (button_left_press_pending_flag) {
  94. velocity -= 5;
  95. } else if (button_right_press_pending_flag) {
  96. velocity += 5;
  97. } else if (button_cancel_press_pending_flag) {
  98. SuspendToRunOtherTask(taskSelectTaskHandle);
  99. continue;
  100. }
  101. button_reset_all_flags();
  102. }
  103. FOC_velocity_control_loop(velocity);
  104. vTaskDelayUntil(&xLastWakeTime,
  105. 1); // every FOC control task need at least 1ms delay otherwise cannot detect key press normally
  106. }
  107. }
  108. void PositionControlTask(void *argument) {
  109. float angle = 0;
  110. TickType_t xLastWakeTime = xTaskGetTickCount();
  111. gui_draw_position_mode(angle, 1);
  112. while (1) {
  113. if (button_press_pending_flag) {
  114. if (button_left_press_pending_flag) {
  115. angle -= _PI_2;
  116. } else if (button_right_press_pending_flag) {
  117. angle += _PI_2;
  118. } else if (button_cancel_press_pending_flag) {
  119. SuspendToRunOtherTask(taskSelectTaskHandle);
  120. gui_draw_position_mode(angle, 1);
  121. continue;
  122. }
  123. button_reset_all_flags();
  124. gui_draw_position_mode(angle, 0);
  125. }
  126. FOC_position_control_loop(angle);
  127. vTaskDelayUntil(&xLastWakeTime,
  128. 1); // every FOC control task need at least 1ms delay otherwise cannot detect key press normally
  129. }
  130. }
  131. void SpringTask(void *argument) {
  132. TickType_t xLastWakeTime = xTaskGetTickCount();
  133. while (1) {
  134. if (button_press_pending_flag) {
  135. if (button_cancel_press_pending_flag) {
  136. SuspendToRunOtherTask(taskSelectTaskHandle);
  137. continue;
  138. }
  139. button_reset_all_flags();
  140. }
  141. FOC_spring_loop(0, spring_pid);
  142. vTaskDelayUntil(&xLastWakeTime,
  143. 1); // every FOC control task need at least 1ms delay otherwise cannot detect key press normally
  144. }
  145. }
  146. void DampTask(void *argument) {
  147. }
  148. void KnobTask(void *argument) {
  149. TickType_t xLastWakeTime = xTaskGetTickCount();
  150. // Settings
  151. uint8_t select_param = 0;
  152. const uint8_t max_select_param = 3;
  153. uint8_t change_param = 0;
  154. uint8_t values[3] = {4, 5, 4}; // [0]: sector_num [1]: k [2]: max_force
  155. pid_knob.Kp = values[1];
  156. pid_knob.max_u = values[2];
  157. pid_knob.min_u = -values[2];
  158. gui_draw_knob_mode(values[0], values[1], values[2], select_param, change_param, 1);
  159. while (1) {
  160. if (button_press_pending_flag) {
  161. if (button_confirm_press_pending_flag) {
  162. if(select_param){
  163. change_param = !change_param;
  164. }
  165. } else if (button_left_press_pending_flag) {
  166. if(change_param){
  167. values[select_param - 1] --;
  168. // reconfigure
  169. pid_knob.Kp = values[1];
  170. pid_knob.max_u = values[2];
  171. pid_knob.min_u = -values[2];
  172. gui_draw_knob_mode(values[0], values[1], values[2], select_param, change_param, 0);
  173. }else{
  174. if (select_param == 0) {
  175. select_param = max_select_param;
  176. } else select_param--;
  177. }
  178. } else if (button_right_press_pending_flag) {
  179. if(change_param){
  180. values[select_param - 1] ++;
  181. // reconfigure
  182. pid_knob.Kp = values[1];
  183. pid_knob.max_u = values[2];
  184. pid_knob.min_u = -values[2];
  185. gui_draw_knob_mode(values[0], values[1], values[2], select_param, change_param, 0);
  186. }else{
  187. if (select_param == max_select_param) {
  188. select_param = 0;
  189. } else select_param++;
  190. }
  191. } else if (button_cancel_press_pending_flag) {
  192. SuspendToRunOtherTask(taskSelectTaskHandle);
  193. gui_draw_knob_mode(values[0], values[1], values[2], select_param, change_param, 1);
  194. continue;
  195. }
  196. button_reset_all_flags();
  197. gui_draw_knob_mode(values[0], values[1], values[2], select_param, change_param, 0);
  198. }
  199. FOC_knob_loop(values[0]);
  200. vTaskDelayUntil(&xLastWakeTime,
  201. 1); // every FOC control task need at least 1ms delay otherwise cannot detect key press normally
  202. }
  203. }
  204. /* USER CODE END Application */