打印
[应用相关]

带Arduino和L6234驱动器的无刷直流电机控制

[复制链接]
1057|1
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
这篇文章展示了如何使用 Arduino UNO 板和 L6234 三相电机驱动器控制 PC CD-ROM(或 DVD-ROM)驱动器无传感器 BLDC 电机。这款BLDC电机是CD-ROM驱动器的主轴电机,我之所以选择它,是因为它不消耗高功率,L6234驱动器可以轻松驱动。
关于L6234三相电机驱动器:
L6234是一款DMOS三重半桥驱动器,输入电源电压高达52V,输出电流为
5A。它可以用于非常广泛的应用。
它已在多功率BCD60II技术中实现,该技术允许在同一芯片上将隔离的DMOS
晶体管与CMOS和双极电路组合在一起。它采用 Power DIP 20 (16+2+2)
和 Power SO 20 封装。
所有输入均兼容TTL/CMOS,每个半桥均可由其自己的专用输入
和使能驱动。
DMOS结构具有固有续流体二极管,因此可以避免使用双极性配置
中必需的外部二极管。DMOS结构允许在Vs=42V时具有6.5 mA(典型值)的极低静态
电流,无论负载如何。

https://www.st.com/en/motor-drivers/l6234.html
方框图:


L6234 引脚配置:
L6234 芯片采用 20 引脚 PowerDIP 封装 (16+2+2),在 PowerSO20 中,每个封装都有其引脚配置,如下所示:


L6234 驱动器有 3 个输出:OUT1、OUT2 和 OUT3。每个输出由 2 个引脚控制:输入 (IN) 和使能 (EN),例如 OUT1 由 IN1 和 EN1 控制。下图显示了每个半桥的控制逻辑:



所需硬件:

  • Arduino板(UNO,NANO ...)
  • CD-ROM无刷直流电机
  • L6234 三相电机驱动器 — 数据表
  • 6 x 33k 欧姆电阻
  • 3 x 10k 欧姆电阻
  • 4 x 1 欧姆电阻(2 W 或更高)
  • 2 x 1N4148 二极管
  • 100 uF电解电容器(16V或更高)
  • 1 uF 电解电容器(16V 或更高)
  • 220 nF (0.22 uF) 陶瓷电容器
  • 100 nF (0.1 uF) 陶瓷电容器
  • 10 nF (0.01 uF) 陶瓷电容器
  • 2 x 按钮
  • 12V电源
  • 面包板
  • 跳线





使用特权

评论回复
沙发
xuanhuanzi|  楼主 | 2024-5-19 16:06 | 只看该作者
(所有接地端子连接在一起)

无刷电机的速度由连接到 Arduino A0 和 A1 引脚的两个按钮控制。

Arduino代码:
项目代码如下,有关代码的更多信息,请参阅上面的第一个相关项目。
/* 
* Sensorless brushless DC (BLDC) motor control with Arduino UNO and L6234 driver.
* This is a free software with NO WARRANTY.
* http://simple-circuit.com/
*/


#define SPEED_UP          A0
#define SPEED_DOWN        A1
#define PWM_MAX_DUTY      255
#define PWM_MIN_DUTY      50
#define PWM_START_DUTY    100

byte bldc_step = 0, motor_speed;
unsigned int i;
void setup() {
  DDRD  |= 0x38;           // Configure pins 3, 4 and 5 as outputs
  PORTD  = 0x00;
  DDRB  |= 0x0E;           // Configure pins 9, 10 and 11 as outputs
  PORTB  = 0x31;
  // Timer1 module setting: set clock source to clkI/O / 1 (no prescaling)
  TCCR1A = 0;
  TCCR1B = 0x01;
  // Timer2 module setting: set clock source to clkI/O / 1 (no prescaling)
  TCCR2A = 0;
  TCCR2B = 0x01;
  // Analog comparator setting
  ACSR   = 0x10;           // Disable and clear (flag bit) analog comparator interrupt
  pinMode(SPEED_UP,   INPUT_PULLUP);
  pinMode(SPEED_DOWN, INPUT_PULLUP);
}
// Analog comparator ISR
ISR (ANALOG_COMP_vect) {
  // BEMF debounce
  for(i = 0; i < 10; i++) { if(bldc_step & 1){ if(!(ACSR & 0x20)) i -= 1; } else { if((ACSR & 0x20)) i -= 1; } } bldc_move(); bldc_step++; bldc_step %= 6; } void bldc_move(){ // BLDC motor commutation function switch(bldc_step){ case 0: AH_BL(); BEMF_C_RISING(); break; case 1: AH_CL(); BEMF_B_FALLING(); break; case 2: BH_CL(); BEMF_A_RISING(); break; case 3: BH_AL(); BEMF_C_FALLING(); break; case 4: CH_AL(); BEMF_B_RISING(); break; case 5: CH_BL(); BEMF_A_FALLING(); break; } } void loop() { SET_PWM_DUTY(PWM_START_DUTY); // Setup starting PWM with duty cycle = PWM_START_DUTY i = 5000; // Motor start while(i > 100) {
    delayMicroseconds(i);
    bldc_move();
    bldc_step++;
    bldc_step %= 6;
    i = i - 20;
  }
  motor_speed = PWM_START_DUTY;
  ACSR |= 0x08;                    // Enable analog comparator interrupt
  while(1) {
    while(!(digitalRead(SPEED_UP)) && motor_speed < PWM_MAX_DUTY){ motor_speed++; SET_PWM_DUTY(motor_speed); delay(100); } while(!(digitalRead(SPEED_DOWN)) && motor_speed > PWM_MIN_DUTY){
      motor_speed--;
      SET_PWM_DUTY(motor_speed);
      delay(100);
    }
  }
}

void BEMF_A_RISING(){
  ADCSRB = (0 << ACME);    // Select AIN1 as comparator negative input
  ACSR |= 0x03;            // Set interrupt on rising edge
}
void BEMF_A_FALLING(){
  ADCSRB = (0 << ACME);    // Select AIN1 as comparator negative input
  ACSR &= ~0x01;           // Set interrupt on falling edge
}
void BEMF_B_RISING(){
  ADCSRA = (0 << ADEN);   // Disable the ADC module
  ADCSRB = (1 << ACME);
  ADMUX = 2;              // Select analog channel 2 as comparator negative input
  ACSR |= 0x03;
}
void BEMF_B_FALLING(){
  ADCSRA = (0 << ADEN);   // Disable the ADC module
  ADCSRB = (1 << ACME);
  ADMUX = 2;              // Select analog channel 2 as comparator negative input
  ACSR &= ~0x01;
}
void BEMF_C_RISING(){
  ADCSRA = (0 << ADEN);   // Disable the ADC module
  ADCSRB = (1 << ACME);
  ADMUX = 3;              // Select analog channel 3 as comparator negative input
  ACSR |= 0x03;
}
void BEMF_C_FALLING(){
  ADCSRA = (0 << ADEN);   // Disable the ADC module
  ADCSRB = (1 << ACME);
  ADMUX = 3;              // Select analog channel 3 as comparator negative input
  ACSR &= ~0x01;
}

void AH_BL(){
  PORTB  =  0x04;
  PORTD &= ~0x18;
  PORTD |=  0x20;
  TCCR1A =  0;            // Turn pin 11 (OC2A) PWM ON (pin 9 & pin 10 OFF)
  TCCR2A =  0x81;         //
}
void AH_CL(){
  PORTB  =  0x02;
  PORTD &= ~0x18;
  PORTD |=  0x20;
  TCCR1A =  0;            // Turn pin 11 (OC2A) PWM ON (pin 9 & pin 10 OFF)
  TCCR2A =  0x81;         //
}
void BH_CL(){
  PORTB  =  0x02;
  PORTD &= ~0x28;
  PORTD |=  0x10;
  TCCR2A =  0;            // Turn pin 10 (OC1B) PWM ON (pin 9 & pin 11 OFF)
  TCCR1A =  0x21;         //
}
void BH_AL(){
  PORTB  =  0x08;
  PORTD &= ~0x28;
  PORTD |=  0x10;
  TCCR2A =  0;            // Turn pin 10 (OC1B) PWM ON (pin 9 & pin 11 OFF)
  TCCR1A =  0x21;         //
}
void CH_AL(){
  PORTB  =  0x08;
  PORTD &= ~0x30;
  PORTD |=  0x08;
  TCCR2A =  0;            // Turn pin 9 (OC1A) PWM ON (pin 10 & pin 11 OFF)
  TCCR1A =  0x81;         //
}
void CH_BL(){
  PORTB  =  0x04;
  PORTD &= ~0x30;
  PORTD |=  0x08;
  TCCR2A =  0;            // Turn pin 9 (OC1A) PWM ON (pin 10 & pin 11 OFF)
  TCCR1A =  0x81;         //
}

void SET_PWM_DUTY(byte duty){
  if(duty < PWM_MIN_DUTY) duty = PWM_MIN_DUTY; if(duty > PWM_MAX_DUTY)
    duty  = PWM_MAX_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
}


使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

172

主题

2200

帖子

3

粉丝