Skip to content

Instantly share code, notes, and snippets.

@0xFEEDC0DE64
Created August 14, 2019 15:29
Show Gist options
  • Save 0xFEEDC0DE64/eeedfb9a8f1a48090e9d335bb88a08db to your computer and use it in GitHub Desktop.
Save 0xFEEDC0DE64/eeedfb9a8f1a48090e9d335bb88a08db to your computer and use it in GitHub Desktop.
class BldcHelper {
public:
BldcHelper(volatile const uint16_t &dc, const int &offsetdc, AverageHelper<float> &currentAvg, __IO uint32_t &BDT,
const __IO uint32_t &IDR_u, uint16_t hall_u_pin, const __IO uint32_t &IDR_v, uint16_t hall_v_pin, const __IO uint32_t &IDR_w, uint16_t hall_w_pin,
__IO uint32_t &TIM_U, __IO uint32_t &TIM_V, __IO uint32_t &TIM_W) :
m_dc(dc),
m_offsetdc(offsetdc),
m_currentAvg(currentAvg),
m_BDT(BDT),
m_IDR_u(IDR_u),
m_hall_u_pin(hall_u_pin),
m_IDR_v(IDR_v),
m_hall_v_pin(hall_v_pin),
m_IDR_w(IDR_w),
m_hall_w_pin(hall_w_pin),
m_TIM_U(TIM_U),
m_TIM_V(TIM_V),
m_TIM_W(TIM_W)
{}
void readHall()
{
const float current = std::abs((m_dc - m_offsetdc) * settings.MOTOR_AMP_CONV_DC_AMP);
m_currentAvg.pushValue(current);
//disable PWM when current limit is reached (current chopping)
if(current > settings.DC_CUR_LIMIT || !settings.enable)
{
m_BDT &= ~TIM_BDTR_MOE;
}
else
{
m_BDT |= TIM_BDTR_MOE;
}
//determine next position based on hall sensors
uint8_t hall_u = !(m_IDR_u & m_hall_u_pin);
uint8_t hall_v = !(m_IDR_v & m_hall_v_pin);
uint8_t hall_w = !(m_IDR_w & m_hall_w_pin);
uint8_t hall = hall_u * 1 + hall_v * 2 + hall_w * 4;
m_pos = hall_to_pos[hall];
m_pos += 2;
m_pos %= 6;
}
void updatePwm() const
{
//update PWM channels based on position
int u, v, w;
blockPWM(m_pwm, m_pos, u, v, w);
int weaku, weakv, weakw;
if (m_pos > 0)
blockPWM(m_weak, (m_pos+5) % 6, weaku, weakv, weakw);
else
blockPWM(-m_weak, (m_pos+1) % 6, weaku, weakv, weakw);
u += weaku;
v += weakv;
w += weakw;
m_TIM_U = std::clamp(u + pwm_res / 2, 10, pwm_res-10);
m_TIM_V = std::clamp(v + pwm_res / 2, 10, pwm_res-10);
m_TIM_W = std::clamp(w + pwm_res / 2, 10, pwm_res-10);
}
volatile int m_pos{0};
volatile int m_pwm{0};
volatile int m_weak{0};
private:
static constexpr int pwm_res = 64000000 / 2 / PWM_FREQ; // = 2000
static constexpr std::array<uint8_t, 8> hall_to_pos { 0, 0, 2, 1, 4, 5, 3, 0, };
static void blockPWM(int pwm, int pos, int &u, int &v, int &w) {
switch(pos) {
case 0:
u = 0;
v = pwm;
w = -pwm;
break;
case 1:
u = -pwm;
v = pwm;
w = 0;
break;
case 2:
u = -pwm;
v = 0;
w = pwm;
break;
case 3:
u = 0;
v = -pwm;
w = pwm;
break;
case 4:
u = pwm;
v = -pwm;
w = 0;
break;
case 5:
u = pwm;
v = 0;
w = -pwm;
break;
default:
u = 0;
v = 0;
w = 0;
}
}
const volatile uint16_t &m_dc;
const int &m_offsetdc;
AverageHelper<float> &m_currentAvg;
__IO uint32_t &m_BDT;
const __IO uint32_t &m_IDR_u;
const uint16_t m_hall_u_pin;
const __IO uint32_t &m_IDR_v;
const uint16_t m_hall_v_pin;
const __IO uint32_t &m_IDR_w;
const uint16_t m_hall_w_pin;
__IO uint32_t &m_TIM_U;
__IO uint32_t &m_TIM_V;
__IO uint32_t &m_TIM_W;
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment