首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >无传感器无刷直流电机控制BEMF段

无传感器无刷直流电机控制BEMF段
EN

Stack Overflow用户
提问于 2020-01-04 09:32:36
回答 2查看 1K关注 0票数 1

我试着做一个无传感器的无刷直流电机控制驱动器。我找到了一个Arduino代码,我想将它转换为ARM Stm32。但我不完全明白ISR中断部分会发生什么。有人能很快解释我吗?为什么使用bldc_step&1和什么时候降低i

代码语言:javascript
复制
byte bldc_step = 0, motor_speed, pin_state;
 
void setup()
{
  DDRD  |= 0xE0;  // configure pins 5, 6 and 7 as outputs
  PORTD  = 0x00;
  DDRB  |= 0x0E;  // configure pins 9, 10 and 11 as outputs
  PORTB  = 0x31;

  pinMode(2, INPUT_PULLUP);
  pinMode(3, INPUT_PULLUP);
  pinMode(4, INPUT_PULLUP);
}
 
// pin change interrupt 2 (PCINT2) ISR
ISR (PCINT2_vect)
{
  if( (PIND & PCMSK2) != pin_state )
    return;
  // BEMF debounce
  for(byte i = 0; i < 20; i++)
  {
    if(bldc_step & 1){
      if(PIND & PCMSK2)     i -= 1;
    }
    else {
      if(!(PIND & PCMSK2))  i -= 1;
    }
  }
 
  bldc_move();
  bldc_step++;
  bldc_step %= 6;
}
 
// BLDC motor commutation function
void bldc_move()
{
  switch(bldc_step)
  {
    case 0:
      AH_BL();
      BEMF_C_FALLING();
      break;
    case 1:
      AH_CL();
      BEMF_B_RISING();
      break;
    case 2:
      BH_CL();
      BEMF_A_FALLING();
      break;
    case 3:
      BH_AL();
      BEMF_C_RISING();
      break;
    case 4:
      CH_AL();
      BEMF_B_FALLING();
      break;
    case 5:
      CH_BL();
      BEMF_A_RISING();
  }
}
  
  PCICR  = 4;  // enable pin change interrupt for pins PCINT23..16 (Arduino 0 to 7)
  
 
 
void BEMF_A_RISING()
{
  PCMSK2 = 0x04;    // enable Arduino pin 2 (PCINT18) interrupt, others are disabled
  pin_state = 0x04;
}
void BEMF_A_FALLING()
{
  PCMSK2 = 0x04;    // enable Arduino pin 2 (PCINT18) interrupt, others are disabled
  pin_state = 0;
}
void BEMF_B_RISING()
{
  PCMSK2 = 0x08;    // enable Arduino pin 3 (PCINT19) interrupt, others are disabled
  pin_state = 0x08;
}
void BEMF_B_FALLING()
{
  PCMSK2 = 0x08;    // enable Arduino pin 3 (PCINT19) interrupt, others are disabled
  pin_state = 0;
}
void BEMF_C_RISING()
{
  PCMSK2 = 0x10;    // enable Arduino pin 4 (PCINT20) interrupt, others are disabled
  pin_state = 0x10;
}
void BEMF_C_FALLING()
{
  PCMSK2 = 0x10;    // enable Arduino pin 4 (PCINT20) interrupt, others are disabled
  pin_state = 0;
}
 
void AH_BL()
{
  PORTD &= ~0xA0;
  PORTD |=  0x40;
  TCCR1A =  0;      // turn pin 11 (OC2A) PWM ON (pin 9 & pin 10 OFF)
  TCCR2A =  0x81;   //
}
void AH_CL()
{
  PORTD &= ~0xC0;
  PORTD |=  0x20;
  TCCR1A =  0;      // turn pin 11 (OC2A) PWM ON (pin 9 & pin 10 OFF)
  TCCR2A =  0x81;   //
}
void BH_CL()
{
  PORTD &= ~0xC0;
  PORTD |=  0x20;
  TCCR2A =  0;       // turn pin 10 (OC1B) PWM ON (pin 9 & pin 11 OFF)
  TCCR1A =  0x21;    //
}
void BH_AL()
{
  PORTD &= ~0x60;
  PORTD |=  0x80;
  TCCR2A =  0;      // turn pin 10 (OC1B) PWM ON (pin 9 & pin 11 OFF)
  TCCR1A =  0x21;   //
}
void CH_AL()
{
  PORTD &= ~0x60;
  PORTD |=  0x80;
  TCCR2A =  0;       // turn pin 9 (OC1A) PWM ON (pin 10 & pin 11 OFF)
  TCCR1A =  0x81;    //
}
void CH_BL()
{
  PORTD &= ~0xA0;
  PORTD |=  0x40;
  TCCR2A =  0;       // turn pin 9 (OC1A) PWM ON (pin 10 & pin 11 OFF)
  TCCR1A =  0x81;    //
}
 
void SET_PWM_DUTY(byte duty)
{
  OCR1A  = duty;  // set pin 9  PWM duty cycle
  OCR1B  = duty;  // set pin 10 PWM duty cycle
  OCR2A  = duty;  // set pin 11 PWM duty cycle
}
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2020-01-05 19:05:03

此代码用于反电磁力(BEMF)信号的去噪,等效代码在https://github.com/esden/open-bldc-mk/blob/master/bldc.c中。

代码语言:javascript
复制
ISR(ANA_COMP_vect){
unsigned char i;

/* debounce the bemf signal */
for(i=0; i<BEMF_DEBOUNCE_COUNT; i++){
    if(bldc_phase & 1){
        if(BEMF_L) i -= BEMF_DEBOUNCE_DEC;
    }else{
        if(BEMF_H) i -= BEMF_DEBOUNCE_DEC;
    }
}

有关脱钩及其原因,请参见https://en.wikipedia.org/wiki/Switch#Contact_bounce

这里实现的精确算法是带有垂直计数器的解跳开关(,cf https://www.compuphase.com/electronics/debouncing.htm --带有垂直计数器的跳开关)。

bldc_step & 1中,&运算符是按位的,也就是说,二进制bldc_step中的45 & 35 = 3300101101 & 00100011 = 00100001是一个字节,按位排列--使用1来确定它相当于测试是否设置了bldc_step的最后一个位。使用PIND & PCMSK2检查PIND是高还是低

这段代码和其余的反跳循环实现了https://www.compuphase.com/electronics/debouncing.htm中描述的垂直计数器。

票数 0
EN

Stack Overflow用户

发布于 2020-11-15 09:14:22

电机的速度取决于施加的电压直流,其中D是职责。

代码语言:javascript
复制
Fm = D.VP.KV.poles/120 = D.Vp/M
Tm = M/(D.Vp)

bemf检测后的理想延迟为30 deg:

代码语言:javascript
复制
delay = Tm/12 = M/(12.D.Vp) = M'/(D.Vp)     : M'=M/12

M‘-伏特*秒为30°延迟后,过零点检测。比较器ISR只在定时计数。PWM脉冲越宽,计数越快。

循环最大时间:

代码语言:javascript
复制
m = N.ticks.Cycles

循环是每条指令的滴答。循环只在吨上升或下降BEMF时才计算(向上)到N。计数的PWM脉冲将是:

代码语言:javascript
复制
Pc = m/ton  or  Pc = m/(D.Ts)

循环的估计时间是:

代码语言:javascript
复制
dt = Pc.Ts = m.Ts/(D.Ts) = m/D

所需的延迟和环路的时间必须相等:延迟= dt

代码语言:javascript
复制
M'/(Vp.D) = m/D or m = M'/Vp

这种方法也被称为“反EMF集成方法”。M‘= D.Vp.Tm’是从ZCP到下一换相的集成bemf电压。您可以在这里阅读更多有关这方面的内容:https://www.ncbi.nlm.nih.gov/pmc/articles/PMC3231115/

调整N和PWM频率(Fs=1/Ts)可以给你几乎完美的30度延迟后,bemf检测。电机的磁极和千伏应该被知道。如果没有调整,此代码将不能与任何电机一起工作。干杯

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/59589497

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档