一个可行的 BLDC 原型设计制作和展示方案——ATmega328P + L6234 + BLDC + Arduino IDE
本帖最后由 MianQi 于 2024-5-25 11:47 编辑整个方案的组成:ATmega328P + L6234 + BLDC + Arduino IDE
1、MCU 选用 Arduino UNO R3
2、电动机驱动芯片选用 ST 的 L6234 双列直插 20 脚
3、电源:12v
这是整套方案的实物照:
这是电动机:
这是驱动芯片 L6234 及其外围电路:
参考的例程在这里-https://simple-circuit.com/arduino-brushless-dc-motor-control-l6234/
但是例程中的示例程序在Arduino IDE中能编译通过,电动机却不能正常运行。于是开始查找原因。
很快发现,设置部分没有开启全局中断,加上这一句“sei(); //Enable global interrupt”之后,电动机能转,但是不能连续转,从这段程序中受到启发:“ i= 50000;// Motor start while(i> 100){ delayMicroseconds(i); bldc_move(); bldc_step++; bldc_step%= 6; i= i - 20; }”,在主循环中加入两句“delayMicroseconds(500);”和一句“delayMicroseconds(3500);”,电动机依然不能连续运转,于是开始查MCU –ATmega328P 的数据手册,最终发现,要在检测反向电动势的6个函数中的三个下降沿触发中加入“ACSR= 0x02;”,给ACSR(AnalogComparator Control and StatusRegiste)寄存器一个明确的赋值。现在,电动机能连续运转,但是重启和调速仍然有问题,最终发现针对这套实际的硬件,要修改常量“PWM_MIN_DUTY”,从原来的“50”逐步试出来要改为“100”才行。
项目的演示视频在这里- https://www.bilibili.com/video/BV1iz421m7EL/分步骤讲解在这里:1、https://www.bilibili.com/video/BV1rM4m1r7v2/2、https://www.bilibili.com/video/BV15y411Y7UC/3、https://www.bilibili.com/video/BV1ry411a7BP/4、https://www.bilibili.com/video/BV1LE421F7gx/5、https://www.bilibili.com/video/BV1rm421K71w/6、https://www.bilibili.com/video/BV1dJ4m1A7ef/7、https://www.bilibili.com/video/BV1GT421S7uo/8、https://www.bilibili.com/video/BV1vM4m1k7vZ/9、https://www.bilibili.com/video/BV1P1421q7nn/
看起来很不错啊
这个芯片好用吗 看到分享的链接了,学习一下,非常赞。
xuanhuanzi 发表于 2024-5-19 15:46
这个芯片好用吗
从数据手册的说明来看,这个芯片是专为 BLDC 设计地。从外围电路的搭建以及管脚接线的实际经验来看,用起来的确很方便。 有代码么?抄一下代码,
哈哈哈 Arduino IDE 版本的是一个单独的文件:
/*
* Sensorless brushless DC (BLDC) motor control with Arduino UNO and L6234 driver.
*/
#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);
sei();
}
// Analog comparator ISR
ISR (ANALOG_COMP_vect) {
// BEMF debounce
for(int 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();
//delay(10);
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 9PWM duty cycle
OCR1B= duty; // Set pin 10 PWM duty cycle
OCR2A= duty; // Set pin 11 PWM duty cycle
} Microchip Studio 版本的程序由四个文件组成:
main.c main.h bldc.c bldc.h
main.c
/*
* main.c
*/
#ifndef F_CPU
#define F_CPU 16000000ul
#endif
#include "main.h"
#include <avr/cpufunc.h>
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#include "bldc.h"
#define PWM_MAX_DUTY 250
#define PWM_MIN_DUTY 50
//#define PWM_MIN_DUTY 100
#define PWM_START_DUTY 100
unsigned int bldc_step = 0;
volatile unsigned int value_pinc = 0;
volatile unsigned char motor_speed = 0;
unsigned int delay_ms_speed = 10; //10-35ms = 10000-35000us
void motor_start(void);
void motor_restart(void);
void bldc_move(void);
int main(void)
{
/* Replace with your application code */
init_Timer0();
init_ADC();
init_UART();
init_GPIO();
init_Timer1();
init_Timer2();
// Analog comparator setting - ACSR – Analog Comparator Control and Status Registe
// ACD ACBG ACO ACI ACIE ACIC ACIS1 ACIS0
// Bit 4 – ACI: Analog Comparator Interrupt Flag - ACI is cleared by writing a logic one to the flag.
//ACSR = 0x10; // Disable and clear (flag bit) analog comparator interrupt
ACSR |= 0x08; // Enable analog comparator interrupt - Bit 3 – ACIE: Analog Comparator Interrupt Enable
//motor_speed = PWM_START_DUTY;
//SET_PWM_DUTY(motor_speed);
//Enable PCINT
PCICR = 0x02;
PCMSK1 = 0x03;
sei(); // Enable global interrupt
motor_start();
while (1)
{
//unsigned char i = PINC0;
///* Insert nop for synchronization*/
//_NOP();
//unsigned char j = PINC1;
///* Insert nop for synchronization*/
//_NOP();
////TX(motor_speed);
////while(!PINC0){
//while((!i) && (motor_speed < PWM_MAX_DUTY)){
//motor_speed++;
//SET_PWM_DUTY(motor_speed);
////delay(1);
////_delay_us(500);
//}
////while(!PINC1){
//while((!j) && (motor_speed > PWM_MIN_DUTY)){
//motor_speed--;
//SET_PWM_DUTY(motor_speed);
////delay(1);
////_delay_us(500);
//}
//SET_PWM_DUTY(motor_speed);
//motor_restart();
bldc_move();
//_delay_us(3500);
//_delay_ms(10);
_delay_us(10000);
for(unsigned int i = 0; i < motor_speed / 10; ++i) {
//_delay_ms(1);
_delay_us(10);
}
bldc_step++;
bldc_step %= 6;
}
}
void init_GPIO(void){
DDRB|= 0x0E;// Configure UNO pins 9, 10 and 11 as outputs
PORTB= 0x00;
DDRD|= 0x38;// Configure UNO pins 3, 4 and 5 as outputs
PORTD= 0x00;
DDRC&= 0xFC; // Configure UNO pins A0(D14), A1(D15) as inputs
PORTC |= 0x03; // Set pins A0 and A1 input_pullup
}
ISR (PCINT1_vect) {
value_pinc = PINC & 0x03;
if(value_pinc == 0x01) {
//motor_speed++;
motor_speed += 10;
} else if(value_pinc == 0x02) {
//motor_speed--;
motor_speed -= 10;
}
motor_restart();
}
// Timer/Counter0 overflow ISR - Vector program address - 0x0020
ISR (TIMER0_OVF_vect) {
//TX('A');
++counter_adc;
if(counter_adc >= 61) {
//ADCSRA |= 0b01000000; // Bit 6 – ADSC: ADC Start Conversion
ADCSRA = 0x8D | (1<<ADSC);
counter_adc = 0;
} else {
;
}
}
// ADC ISR -ADC conversion complete - 0x002A
ISR (ADC_vect) {
unsigned int temp = ADC; // 0 - 1023
temp /= 4; // 0 - 254
motor_speed = temp;
//motor_speed = ADCH;
//TX(motor_speed);
//counter_adc = 0;
//SET_PWM_DUTY(motor_speed);
}
// Analog comparator ISR - Vector program address - 0x002E
ISR (ANALOG_COMP_vect) {
// BEMF debounce
for(unsigned int i = 0; i < 10; i++) {
if(bldc_step & 1){
if(!(ACSR & 0x20)) i -= 1;
}
else {
if((ACSR & 0x20))i -= 1;
}
}
//bldc_move();
//_delay_us(500);
//_delay_ms(6);
bldc_step++;
bldc_step %= 6;
}
void init_Timer0(void) {
// Timer0 module used for ADC sampling frequency
TCCR0A = 0x00; //Timer/Counter Mode of Operation = Normal
// Timer0 module setting: set clock source to clkI/O / 1024 (from prescaler)
TCCR0B = 0b00000101; //16MHz / 1024 / 256 = 61 (microsecond)
// CS02 CS01 CS00 = 101
// Timer/Counter0 Overflow Interrupt Enable = TOIE0
TIMSK0 = 0x01;
}
void init_ADC() {
// ADMUX – ADC Multiplexer Selection Register
// Bit 7 6 5 4 3 2 1 0
//(0x7C) REFS1 REFS0 ADLAR – MUX3 MUX2 MUX1 MUX0
ADMUX = 0x40; // AVCC with external capacitor at AREF pin | ADC0
//DDRC &= ~0b00000001;
// ADCSRA – ADC Control and Status Register A
// Bit 7 6 5 4 3 2 1 0
//(0x7A) ADEN ADSC ADATE ADIF ADIE ADPS2 ADPS1 ADPS0
ADCSRA = 0x8D; // ADC Enable | single conversion mode |Bit 3 – ADIE: ADC Interrupt Enable
// Bits 2:0 – ADPS2:0: ADC Prescaler Select Bits
//ADCSRA |= 0b00000101; // Division Factor - 32
//The ADLAR bit in ADMUX, and the MUXn bits in ADMUX affect the way the result is read from the registers.
//If ADLAR is set, the result is left adjusted.
//if the result is left adjusted and no more than 8-bit precision is required, it is sufficient to read ADCH
//ADMUX |= 1<<ADLAR;
}
void init_UART(void) {
UCSR0A = 0b00000000; //single transmission speed, multiprocessor disabled
UCSR0B = 0b00011000; //enable Rx & Tx
UCSR0C = 0b00000110; //asynchronous, no parity, 1 stop, 8 bits
UBRR0 = 103; //load the value for 9600 bps baud rate into whole UBRR register
}
void init_Timer1(void) {
// Timer1 module setting: set clock source to clkI/O / 1 (no prescaling)
TCCR1A = 0;
TCCR1B = 0x01;
}
void init_Timer2(void) {
// Timer2 module setting: set clock source to clkI/O / 1 (no prescaling)
TCCR2A = 0;
TCCR2B = 0x01;
}
void TX(unsigned char TXData) {
//do nothing until UDR0 is ready for more data to be written to it; wait for USART UDRE flag
while ((UCSR0A & (1 << UDRE0)) == 0) {};
//when flag is set send data by placing the byte into UDR0
UDR0 = TXData;
}
void SET_PWM_DUTY(unsigned char duty){
if(duty < PWM_MIN_DUTY)
duty= PWM_MIN_DUTY;
if(duty > PWM_MAX_DUTY)
duty= PWM_MAX_DUTY;
OCR1A = duty; // Set pin 9PWM duty cycle
OCR1B = duty; // Set pin 10 PWM duty cycle
OCR2A = duty; // Set pin 11 PWM duty cycle
}
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 motor_start(void){
SET_PWM_DUTY(PWM_START_DUTY);
//unsigned int i = 5000;
unsigned int i = 5000;
while(i > 100) {
////_delay_us(i);
//for(unsigned int j=i; j > 0; --j){
////_delay_us(1);
//_NOP();
//_NOP();
//}
bldc_move();
_delay_ms(6);
bldc_step++;
bldc_step %= 6;
i = i - 20;
}
}
void motor_restart(void) {
SET_PWM_DUTY(motor_speed);
unsigned int i = 5000;
bldc_move();
_delay_ms(6);
bldc_step++;
bldc_step %= 6;
i = i - 20;
} main.h
/*
* main.h
*/
#ifndef MAIN_H_
#define MAIN_H_
#ifndef F_CPU
#define F_CPU 16000000ul
#endif
#include <util/delay.h>
volatile unsigned int counter_adc = 0;
void init_ADC(void);
void init_UART(void);
void init_Timer0(void);
void init_GPIO(void);
void init_Timer1(void);
void init_Timer2(void);
void TX(unsigned char TXData);
void SET_PWM_DUTY(unsigned char duty);
#endif /* MAIN_H_ */ bldc.c
/*
* bldc.c
*/
#include <avr/io.h>
//#include <util/delay.h>
#include "bldc.h"
void BEMF_A_RISING(){
ADCSRB = (0 << ACME); // Select AIN1(PD7-UNO_pin_7) as comparator negative input
ACSR |= 0x03; // Set interrupt on rising edge
//ADCSRA |= (1<<ADEN); // Enable the ADC module
}
void BEMF_A_FALLING(){
ADCSRB = (0 << ACME); // Select AIN1(PD7-UNO_pin_7) as comparator negative input
ACSR &= ~0x01; // Set interrupt on falling edge
//ACSR |= 0x02;
//ADCSRA |= (1<<ADEN); // Enable the ADC module
ACSR = 0x02;
}
void BEMF_B_RISING(){
ADCSRA = (0 << ADEN); // Disable the ADC module
//ADCSRA &= 0x7F;
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
//ADCSRA &= 0x7F;
ADCSRB = (1 << ACME);
ADMUX = 2; // Select analog channel 2 as comparator negative input
ACSR &= ~0x01;
//ACSR |= 0x02;
ACSR = 0x02;
}
void BEMF_C_RISING(){
ADCSRA = (0 << ADEN); // Disable the ADC module
//ADCSRA &= 0x7F;
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
//ADCSRA &= 0x7F;
ADCSRB = (1 << ACME);
ADMUX = 3; // Select analog channel 3 as comparator negative input
ACSR &= ~0x01;
//ACSR |= 0x02;
ACSR = 0x02;
}
void AH_BL(){
//Set "IN1" make arm_A upper close and bottom open
PORTD &= ~0x18; //~0x18=0b11100111 UNO pin_4|pin_3 - IN2|IN3
PORTD |= 0x20; //0x20=0b00100000, UNO pin_5 - OC0B - IN1
//Turn pin 11 (OC2A) PWM ON (pin 9 & pin 10 OFF)
//UNO pin_11 - EN1 - OC2A
//Clear OC2A on compare match, set OC2A at BOTTOM, (non-inverting mode)
TCCR1A = 0; //Normal port operation, OC1A/OC1B disconnected.
TCCR2A = 0x81; //WGM2 WGM1 WGM0 - 1 0 1 PWM, phase correct OCRA
//TCCR2B = 0x08; //WGM22 = 1
//Set "EN2" make arm_B upper close and bottom open
//Clear "pin_D9 - EN3" make arm_C upper open and bottom close
PORTB = 0x04; //UNO - pin_D10 - EN2
}
void AH_CL(){
//Set "IN1" make arm_A upper close and bottom open
PORTD &= ~0x18; //~0x18=0b11100111 UNO pin_4|pin_3 - IN2|IN3
PORTD |= 0x20; //0x20=0b00100000, UNO pin_5 - OC0B - IN1
//Turn pin 11 (OC2A) PWM ON (pin 9 & pin 10 OFF)
//UNO pin_11 - EN1 - OC2A
TCCR1A = 0; //Normal port operation, OC1A/OC1B disconnected.
TCCR2A = 0x81; //WGM2 WGM1 WGM0 - 1 0 1 PWM, phase correct OCRA
//TCCR2B = 0x08; //WGM22 = 1
//Set "EN3" make arm_C upper close and bottom open
//Clear "pin_D9 - EN3" make arm_C upper open and bottom close
PORTB=0x02; //UNO pin_9 - EN3 - OC1B
}
void BH_CL(){
//Set "IN2" make arm_B upper close and bottom open
PORTD &= ~0x28; //~0x28=0b11010111 UNO pin_5|pin_3 - IN1|IN3
PORTD |=0x10; //0x10=0b00010000 UNO pin_4 - IN2
//Turn pin 10 (OC1B) PWM ON (pin 9 & pin 11 OFF)
//WGM13 WGM12 WGM11 WGM10 - 1 0 1 1 PWM, phase correct OCR1B TOP BOTTOM
//COM1A1/COM1B1 COM1A0/COM1B0 - 1 0 Clear OC1A/OC1B on compare match, set OC1A/OC1B at BOTTOM (non-inverting mode)
//TCCR1B - ICNC1 ICES1 – WGM13 WGM12 CS12 CS11 CS10
//TCCR1B = 0x20;
//TCCR1A = 0x2C;//TCCR1A - COM1A1 COM1A0 COM1B1 COM1B0 – – WGM11 WGM10
TCCR2A =0; // Turn pin 10 (OC1B) PWM ON (pin 9 & pin 11 OFF)
TCCR1A =0x21; //
//Set "EN3" make arm_C upper close and bottom open
//Clear "pin_D9 - EN3" make arm_C upper open and bottom close
PORTB=0x02; //UNO pin_9 - EN3
}
void BH_AL(){
//Set "IN2" make arm_B upper close and bottom open
PORTD &= ~0x28;
PORTD |=0x10;
//Turn pin 10 (OC1B) PWM ON (pin 9 & pin 11 OFF)
//WGM13 WGM12 WGM11 WGM10 - 1 0 1 1 PWM, phase correct OCR1B TOP BOTTOM
//COM1A1/COM1B1 COM1A0/COM1B0 - 1 0 Clear OC1A/OC1B on compare match, set OC1A/OC1B at BOTTOM (non-inverting mode)
//TCCR1B - ICNC1 ICES1 – WGM13 WGM12 CS12 CS11 CS10
//TCCR1B = 0x20;
//TCCR1A = 0x2C;//TCCR1A - COM1A1 COM1A0 COM1B1 COM1B0 – – WGM11 WGM10
TCCR1A = 0x21;
TCCR2A =0;
//Set "EN1" make arm_A upper close and bottom open
//Clear "pin_D11 - EN1" make arm_A upper open and bottom close
PORTB=0x08;
}
void CH_AL(){
//Set "IN3" make arm_C upper close and bottom open
PORTD &= ~0x30;
PORTD |=0x08;
//Turn pin 9 (OC1A) PWM ON (pin 10 & pin 11 OFF)
//WGM13 WGM12 WGM11 WGM10 - 1 0 1 1 PWM, phase correct OCR1B TOP BOTTOM
//COM1A1/COM1B1 COM1A0/COM1B0 - 1 0 Clear OC1A/OC1B on compare match, set OC1A/OC1B at BOTTOM (non-inverting mode)
//TCCR1B - ICNC1 ICES1 – WGM13 WGM12 CS12 CS11 CS10
//TCCR1B = 0x20;
//TCCR1A = 0x2C;//TCCR1A - COM1A1 COM1A0 COM1B1 COM1B0 – – WGM11 WGM10
TCCR1A = 0x81;
TCCR2A =0;
//Set "EN1" make arm_A upper close and bottom open
//Clear "pin_D11 - EN1" make arm_A upper open and bottom close
PORTB=0x08;
}
void CH_BL(){
//Set "IN3" make arm_C upper close and bottom open
PORTD &= ~0x30;
PORTD |=0x08;
//Turn pin 9 (OC1A) PWM ON (pin 10 & pin 11 OFF)
//WGM13 WGM12 WGM11 WGM10 - 1 0 1 1 PWM, phase correct OCR1B TOP BOTTOM
//COM1A1/COM1B1 COM1A0/COM1B0 - 1 0 Clear OC1A/OC1B on compare match, set OC1A/OC1B at BOTTOM (non-inverting mode)
//TCCR1B - ICNC1 ICES1 – WGM13 WGM12 CS12 CS11 CS10
//TCCR1B = 0x20;
//TCCR1A = 0x8C;//TCCR1A - COM1A1 COM1A0 COM1B1 COM1B0 – – WGM11 WGM10
TCCR1A = 0x81;
TCCR2A = 0;
//Set "EN2" make arm_B upper close and bottom open
//Clear "pin_D11 - EN2" make arm_B upper open and bottom close
PORTB=0x04;
} bldc.h
/*
* bldc.h
*/
#ifndef BLDC_H_
#define BLDC_H_
//unsigned int bldc_step = 0;
void bldc_move(void);
//Back EMF PinOut
// BEMF_C PORTD7/UNO_D7/AIN1
// BEMF_B PORTC2/UNO_A2/ADC2
// BEMF_A PORTC3/UNO_A3/ADC3
void BEMF_A_RISING(void);
void BEMF_A_FALLING(void);
void BEMF_B_RISING(void);
void BEMF_B_FALLING(void);
void BEMF_C_RISING(void);
void BEMF_C_FALLING(void);
//Phase PWM(EN) IN
//1 - AB OC2B - PORTB11 - EN1 (PORTD5)IN1=1 | (PORTD4)IN2=0
//2 - AC OC2B - PORTB11 - EN1 (PORTD5)IN1=1 | (PORTD3)IN3=0
//3 - BC OC1B - PORTB10 - EN2 (PORTD4)IN2=1 | (PORTD3)IN3=0
//4 - BA OC1B - PORTB10 - EN2 (PORTD4)IN2=1 | (PORTD5)IN1=0
//5 - CA OC1A - PORTB9 - EN3 (PORTD3)IN3=1 | (PORTD5)IN1=0
//6 - CB OC1A - PORTB9 - EN3 (PORTD3)IN3=1 | (PORTD4)IN2=0
void AH_BL(void);
void AH_CL(void);
void BH_CL(void);
void BH_AL(void);
void CH_AL(void);
void CH_BL(void);
void motor_start(void);
#endif /* BLDC_H_ */ 实际上,BLDC 的驱动程序用 ASM 来写更合适,这个帖子的浏览量当前是 15K,什么时候超过 100K,我就写一个 avrasm 版本的程序。 开源方案? MianQi 发表于 2024-6-17 16:43
实际上,BLDC 的驱动程序用 ASM 来写更合适,这个帖子的浏览量当前是 15K,什么时候超过 100K,我就写一个...
期待楼主分享一下ASM版本的,不过汇编会的人不多了。楼主厉害。 幸福小强 发表于 2024-6-26 22:16
开源方案?
“开源方案”这个叫法有点大了,就是这么个东西,我测试过了能用,感兴趣的人自己测试一下,有问题可以在这里讨论。 MianQi 发表于 2024-6-26 22:18
“开源方案”这个叫法有点大了,就是这么个东西,我测试过了能用,感兴趣的人自己测试一下,有问题可以在 ...
非常好,学习学习。感谢。 该方案用 ATmega328P 作主控,L6234 为驱动芯片,控制 BLDC。电路含电源、主控、驱动、电机接口,通过 Arduino IDE 编程,实现霍尔传感器测速与 FOC 算法。制作分 PCB 绘制、焊接,编程调控制逻辑,最后组装演示正反转、调速,用串口或 OLED 显示状态。
该方案以 ATmega328P 为控制核心,通过 Arduino IDE 编程生成 PWM 信号,经 L6234 电机驱动芯片放大后控制 BLDC 运转。制作时搭建最小系统板,连接驱动电路与 BLDC,烧录测速、正反转程序;展示可通过串口显转速,用 LED 指示转向,实现基础调速与状态监控,整体成本低、易上手
页:
[1]