From 6b62e421f5f3da83eacbc3eed949866a72afa072 Mon Sep 17 00:00:00 2001 From: Simonwangxxx Date: Thu, 7 May 2026 18:10:45 -0400 Subject: [PATCH 01/17] ignore the first edge when the motor starts --- Core/Inc/user.h | 7 +++++++ Core/Src/user.c | 13 +++++++++---- 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/Core/Inc/user.h b/Core/Inc/user.h index 52b83b6..c41bd97 100644 --- a/Core/Inc/user.h +++ b/Core/Inc/user.h @@ -53,6 +53,13 @@ #define PWM_PULSEWIDTH_TO_CCR(p) PWM_DUTYCYCLE_TO_CCR(PWM_PULSEWIDTH_TO_DUTYCYCLE(p)) +#define HALL_EDGES_PER_REV 12.0f + +#define HALL_CAPTURE_TO_RPM(capture_value) \ + ((CLK_FREQ * 60.0f) / ((float)(capture_value) * (TIM3_PSC + 1) * HALL_EDGES_PER_REV)) + +#define MIN_MOTOR_RPM HALL_CAPTURE_TO_RPM(TIM3_CTR_PER) + /* End Macros */ diff --git a/Core/Src/user.c b/Core/Src/user.c index be0fde6..3025f9c 100644 --- a/Core/Src/user.c +++ b/Core/Src/user.c @@ -313,16 +313,21 @@ void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim) // FIXME: (Medium) divide by 2.0f bc RPM too high?? TBD (MAX rpm = ~38k, should be ~20k -> Find way to check hall sensor accuracy // FIXME: (High) Computation needs to be moved outside interrupt - if (hall_capture_value > 0) { + if (motor_rpm > 0) { // 1. Convert time between hall sensor edge transitions from # of ticks - float time_between_edges = (float)hall_capture_value * (TIM3_PSC + 1) / CLK_FREQ; + //float time_between_edges = (float)hall_capture_value * (TIM3_PSC + 1) / CLK_FREQ; // 2. Store frequency of hall sensor edge transitions as # of ticks per transition - float frequency = 1.0f / time_between_edges; + //float frequency = 1.0f / time_between_edges; // 3. Convert to Rotations per Minute // 6 transitions per 1 full rotation | 60 seconds in a minute // # of ticks per transition * 60 seconds / minute / (6 transitions/rotation) = Rotation per Minute // FIXME: (Low) Update output to be integer - motor_rpm = (frequency * 60.0f) / 12.0f; + //motor_rpm = (frequency * 60.0f) / 12.0f; + motor_rpm = HALL_CAPTURE_TO_RPM(hall_capture_value); + } + else + { + motor_rpm = MIN_MOTOR_RPM; } } } From c7ece8cc2ff243d6956b647341420bb5dfccbb6b Mon Sep 17 00:00:00 2001 From: Simonwangxxx Date: Fri, 8 May 2026 17:11:50 -0400 Subject: [PATCH 02/17] Change the input unit to us for the open loop control --- Core/Inc/user.h | 14 ++++++++++++ Core/Src/user.c | 59 ++++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 72 insertions(+), 1 deletion(-) diff --git a/Core/Inc/user.h b/Core/Inc/user.h index c41bd97..0a58fa2 100644 --- a/Core/Inc/user.h +++ b/Core/Inc/user.h @@ -60,6 +60,20 @@ #define MIN_MOTOR_RPM HALL_CAPTURE_TO_RPM(TIM3_CTR_PER) + +#define PWM_US_MIN 1000 +#define PWM_US_NEUTRAL 1500 +#define MOTOR_MIN_START_US 1550 +#define PWM_US_MAX 2000 + +#define PWM_US_TO_MS(us) ((float)(us) / 1000.0f) + +#define PWM_US_CLAMP(us) \ + (((us) < PWM_US_MIN) ? PWM_US_MIN : (((us) > PWM_US_MAX) ? PWM_US_MAX : (us))) + +#define PWM_US_TO_CCR(us) \ + ((uint32_t)PWM_PULSEWIDTH_TO_CCR(PWM_US_TO_MS(PWM_US_CLAMP(us)))) + /* End Macros */ diff --git a/Core/Src/user.c b/Core/Src/user.c index 3025f9c..6941997 100644 --- a/Core/Src/user.c +++ b/Core/Src/user.c @@ -23,6 +23,10 @@ volatile uint8_t pwm_update_flag = 0; volatile uint8_t pid_update_flag = 0; volatile uint8_t speed_update_flag = 0; volatile uint8_t hall_update_flag = 0; + +volatile int16_t debug_pwm_us = PWM_US_NEUTRAL; +volatile uint32_t debug_pwm_ccr = 0; + // FIXME: (High) motor_rpm hould probably be int16_t since magnitude on order of hundreds static volatile float motor_rpm = 0; // TODO: understand if there are any efficiency issues with changing rpm_setpoint to a gloabl static variable @@ -62,6 +66,25 @@ void User_Error_Handler(uint8_t count); /* End Function Declarations */ /* Function Definitions */ +uint32_t pwm_us_to_ccr(int16_t pulse_us); + +uint32_t pwm_us_to_ccr(int16_t pulse_us) +{ + if (pulse_us < 1000) { + pulse_us = 1000; + } else if (pulse_us > 2000) { + pulse_us = 2000; + } + + /* + * PWM_PULSEWIDTH_TO_CCR() 原来接收的是 ms, + * 所以 1500 us 要先变成 1.5 ms。 + */ + float pulse_ms = (float)pulse_us / 1000.0f; + + return (uint32_t)PWM_PULSEWIDTH_TO_CCR(pulse_ms); +} + void User_Init(void){ // Initialization function TIM_PER_CHECK(); @@ -88,7 +111,7 @@ void User_Init(void){ // Initialization function ); } -void User_Loop(void){ // Main Loop +/*void User_Loop(void){ // Main Loop // FIXME: (Medium) rpm_setpoint should probably be uint16_t // TODO: understand if there are any efficiency issues with changing to a gloabl static variable // rather than in the function's scope @@ -112,6 +135,40 @@ void User_Loop(void){ // Main Loop pid_pwm_update(rpm_setpoint); } // Note: Starts ESC at 1.5ms pulse width, then stay between 1ms and 2ms +}*/ + +void User_Loop(void) +{ + /* + * Open-loop PWM pulse-width test mode: + * I2C speed_setpoint is treated as PWM pulse width in microseconds. + * + * Examples: + * speed_setpoint = 1000 -> 1.000 ms + * speed_setpoint = 1500 -> 1.500 ms, neutral / stop + * speed_setpoint = 1550 -> 1.550 ms + * speed_setpoint = 2000 -> 2.000 ms + */ + + if (speed_update_flag == 1) { + speed_update_flag = 0; + } + + if (hall_update_flag == 1) { + hall_update_flag = 0; + } + + if (pid_update_flag == 1) { + pid_update_flag = 0; + + int16_t pulse_us = PWM_US_CLAMP(speed_setpoint); + uint32_t pwm_ccr = PWM_US_TO_CCR(pulse_us); + + debug_pwm_us = pulse_us; + debug_pwm_ccr = pwm_ccr; + + __HAL_TIM_SET_COMPARE(&htim2, TIM_CHANNEL_2, pwm_ccr); + } } // Checks that timer periods generated from CubeMX are what we want them to be From 84349422a3c2e280e3fedd66a3e37310336afe6a Mon Sep 17 00:00:00 2001 From: Simonwangxxx Date: Tue, 12 May 2026 16:01:01 -0400 Subject: [PATCH 03/17] This version has changed the control method of the upper computer over the register. Now, after inputting the address of the starting register, the values of the subsequent registers can be input one by one to control the mode and parameters of the motor. --- .cproject | 6 +- .mxproject | 13 +- Core/Inc/main.h | 11 + Core/Inc/stm32_assert.h | 53 + Core/Inc/stm32f1xx_hal_conf.h | 2 +- Core/Inc/user.h | 12 + Core/Src/main.c | 52 +- Core/Src/stm32f1xx_hal_msp.c | 74 - Core/Src/stm32f1xx_it.c | 67 +- Core/Src/user.c | 733 +- .../Inc/stm32f1xx_hal_i2c.h | 738 -- .../Src/stm32f1xx_hal_i2c.c | 7669 ----------------- .../Src/stm32f1xx_ll_dma.c | 312 + .../Src/stm32f1xx_ll_exti.c | 213 + .../Src/stm32f1xx_ll_gpio.c | 256 + .../Src/stm32f1xx_ll_i2c.c | 219 + .../Src/stm32f1xx_ll_rcc.c | 471 + .../Src/stm32f1xx_ll_utils.c | 767 ++ PID_motor_controller.ioc | 3 +- 19 files changed, 2958 insertions(+), 8713 deletions(-) create mode 100644 Core/Inc/stm32_assert.h delete mode 100644 Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_i2c.h delete mode 100644 Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_i2c.c create mode 100644 Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_ll_dma.c create mode 100644 Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_ll_exti.c create mode 100644 Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_ll_gpio.c create mode 100644 Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_ll_i2c.c create mode 100644 Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_ll_rcc.c create mode 100644 Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_ll_utils.c diff --git a/.cproject b/.cproject index e75553d..721511a 100644 --- a/.cproject +++ b/.cproject @@ -21,7 +21,7 @@