ADVERTISEMENT

ULC_BLMC.pdf

Jak wysterować silnik BLDC 3-fazowy z BEMF przy użyciu ATmega32?

Próbuję wysterować silnik BLDC 3-f przy pomocy ATmega32 na podstawie poniższego kodu: #include <avr/interrupt.h> #include <avr/io.h> #include <util/twi.h> //Motoradresse #define MOTOR_ADR 0x70 //PHASE1 (U) #define UH_DDR DDRB |= (1<<3); #define UH_ON TCCR2A |= (1<<COM2A1); #define UH_OFF TCCR2A &= ~(1<<COM2A1); //PHASE1 (U) #define UL_DDR DDRB |= (1<<1); #define UL_ON PORTB |= (1<<1); #define UL_OFF PORTB &= ~(1<<1); //PHASE2 (V) #define VH_DDR DDRD |= (1<<5); #define VH_ON TCCR0A |= (1<<COM0B1); #define VH_OFF TCCR0A &= ~(1<<COM0B1); //PHASE2 (V) #define VL_DDR DDRB |= (1<<2); #define VL_ON PORTB |= (1<<2); #define VL_OFF PORTB &= ~(1<<2); //PHASE3 (W) #define WH_DDR DDRD |= (1<<3); #define WH_ON TCCR2A |= (1<<COM2B1); #define WH_OFF TCCR2A &= ~(1<<COM2B1); //PHASE3 (W) #define WL_DDR DDRC |= (1<<3); #define WL_ON PORTC |= (1<<3); #define WL_OFF PORTC &= ~(1<<3); #define PHASE_ALL_OFF UH_OFF;UL_OFF;VH_OFF;VL_OFF;WH_OFF;WL_OFF; #define SENSE_U ADMUX = 0; #define SENSE_V ADMUX = 1; #define SENSE_W ADMUX = 2; #define SENSE_H (ACSR&(1<<ACO)) #define START_PWM 5 volatile unsigned long i2c_timeout = 0; volatile unsigned char rx_pwm = 0; volatile unsigned char rotor_state = 0; volatile unsigned char rotor_run = 0; //############################################################################ void next_commutate_state (unsigned char startup) //############################################################################ { switch (rotor_state) { case (0): if(!SENSE_H || startup) { WH_OFF; UH_ON; SENSE_W; rotor_state = 1; TCNT1 = 1; } break; case (1): if(SENSE_H || startup) { VL_OFF; WL_ON; SENSE_V; rotor_state = 2; TCNT1 = 1; } break; case (2): if(!SENSE_H || startup) { UH_OFF; VH_ON; SENSE_U; rotor_state = 3; TCNT1 = 1; } break; case (3): if(SENSE_H || startup) { WL_OFF; UL_ON; SENSE_W; rotor_state = 4; TCNT1 = 1; } break; case (4): if(!SENSE_H || startup) { VH_OFF; WH_ON; SENSE_V; rotor_state = 5; TCNT1 = 1; } break; case (5): if(SENSE_H || startup) { UL_OFF; VL_ON; SENSE_U; rotor_state = 0; TCNT1 = 1; } break; } } //############################################################################ //back EMF zero crossing detection ISR (ANALOG_COMP_vect) //############################################################################ { if(rotor_run == 200) next_commutate_state (0); rotor_run++; if(rotor_run > 200) { rotor_run = 200; } } //############################################################################ ISR (TIMER1_OVF_vect) //############################################################################ { next_commutate_state (1); rotor_run = 0; OCR2A = START_PWM; OCR2B = START_PWM; OCR0B = START_PWM; } //############################################################################ ISR (TWI_vect) //############################################################################ { switch (TWSR & 0xF8) //TW_STATUS { //Adresse empfangen case TW_SR_SLA_ACK: TWCR |= (1<<TWINT); return; //Daten empfangen case TW_SR_DATA_ACK: rx_pwm = TWDR; TWCR |= (1<<TWINT); i2c_timeout = 0; return; //Bus-Fehler zurücksetzen case TW_NO_INFO: TWCR |=(1<<TWSTO) | (1<<TWINT); //Bus-Fehler zurücksetzen case TW_BUS_ERROR: TWCR |=(1<<TWSTO) | (1<<TWINT); } //Reset TW TWCR =(1<<TWEA) | (1<<TWINT) | (1<<TWEN) | (1<<TWIE); } //############################################################################ //Hauptprogramm int main (void) //############################################################################ { //Watchdog on WDTCSR = (1<<WDCE) | (1<<WDE); //Motordriver output UH_DDR; VH_DDR; WH_DDR; UL_DDR; VL_DDR; WL_DDR; //PWM for UH, VH and WH (>32KHz) TCCR0A |= (1<<COM0B1|1<<WGM01|1<<WGM00); TCCR0B |= (1<<CS00); TCCR2A |= (1<<COM2A1|1<<COM2B1|1<<WGM21|1<<WGM20); TCCR2B |= (1<<CS20); //TIMER1 for start commutation or Back EMF lost TCCR1B |= (1<<CS11); TIMSK1 |= (1<<TOIE1); PHASE_ALL_OFF; //Comperator init for back EMF ADCSRB |= (1<<ACME); DIDR1 |= (1<<AIN0D); ACSR |= (1<<ACIE); //I2C Init TWAR = MOTOR_ADR & 0xFE; TWCR = (1<<TWINT)|(1<<TWEA)|(1<<TWEN)|(1<<TWIE); //Interrupts enabel sei(); while(1) { asm("wdr"); if(rx_pwm > START_PWM) { ACSR |= (1<<ACIE); TIMSK1 |= (1<<TOIE1); if(rotor_run == 200) { OCR2A = rx_pwm; OCR2B = rx_pwm; OCR0B = rx_pwm; } i2c_timeout++; if(i2c_timeout>100000) { rx_pwm = 0; } } else { PHASE_ALL_OFF; ACSR&=~(1<<ACIE); TIMSK1 &= ~(1<<TOIE1); } } } Jest on dedykowany pod Atmege48/88/168 i mam problem z przerzuceniem go na 32 :( Czy ktoś mógłby mi pomóc w tej sprawie :?: Byłbym bardzo wdzięczny. Poniżej znajduje się schemat układu.


Download file - link to post

2

3

4

5

6
+12V

BLMC Brushless motor control

+12V

R1
270
+12V

RESET

A

1k

VCC
29

PC0(ADC0/PCINT8)
PC1(ADC1/PCINT9)
PC2(ADC2/PCINT10)
PC3(ADC3/PCINT11)
PC4(ADC4/SDA/PCINT12)
PC5(ADC5/SCL/PCINT13)
PB6(XTAL1/TOSC1/PCINT6)
ADC6
ADC7
PB7(XTAL2/TOSC2/PCINT7)
PD0(RXD/PCINT16)
PD1(TXD/PCINT17)
VCC
PD2(INT0/PCINT18)
VCC
PD3(INT1/OC2B/PCINT19)
PD4(T0/XCK/PCINT20)
AVCC
PD5(T1/OC0B/PCINT21)
AREF
PD6(AIN0/OC0A/PCINT22)
PD7(AIN1/PCINT23)

C15
100n
Q7

7
8

12MHz
4
6

GND
R22 33

18
20

B

23
24
25
26
27
28
19
22

PB0(ICP1/CLKO/PCINT0)
PB1(OC1A/PCINT1)
PB2(SS/OC1B/PCINT2)
PB3(MOSI/OC2A/PCINT3)
PB4(MISO/PCINT4)
PB5(SCK/PCINT5)

12
13
14
15
16
17

PC6(/RESET/PCINT14)

R23

22p
C8
22p
C9

MOSI/UH

IC3

10k

C1
100n
21

AGND

3
5

GND
GND

R4

C13

B_EMF_U
B_EMF_V
B_EMF_W
WL
SDA
SCL

100n

Q1
IRFR5305
T1
BC846

U

Q2
IRFR1205

33
UL

R3

R2
10k

GND

GND GND GND
30
31
32
1
2
9
10
11

+12V

+12V

WH
VH
SUMME_UVW

R5
270

+12V
1k
C12

UL
VL
MOSI/UH
MISO
SCK

VH

R8

100n

Q3
IRFR5305
T2
BC846

V

Q4
IRFR1205

33
VL

R7

GND

R6
10k

ATMEGA48/88/168-AU
GND

C

R25 100

3
2
1

TP1
TP2
TP3
TP4
TP5

SCK
MISO
MOSI/UH
RESET

SDA
SCL

R24 100

GND GND GND
+12V

JP1
GND

R9
270

+12V
GND

Power Supply 5V

BACK_EMF

C11

B_EMF_W

+12V

B_EMF_V

VCC
78L05

C14

D

C2

100n 100n

C3 C4
IC1
2,2µ

WH

U

C10

R21 4k7
R20 4k7

Q5
IRFR5305
T3
BC846

W

Q6
IRFR1205

33
WL

R11

R13 4k7

100µ

R12

100n
GND

SUMME_UVW

GND

1k

ATMEL APPNOTE 444 Page 7

B_EMF_U

OUT
+

IN

Voltage divider/low pass filter

+12V

A

B

C

R10
10k

R14 4k7

V

GND GND GND

W

R19 4k7

R15 4k7

10k 10k 10k

D

2,2µ
R18 R17 R16

GND

C5 C6 C7
100n 100n 100n

GND GND GND GND GND GND

1

ATMEL APPNOTE AVR443 PAGE 4

1

2

3

2011-11-18 06:24:18 C:\Documents and Settings\PawelG\Pulpit\ULC_BLMC_LAYOUT_V1\ULC_BLMC.sch (Sheet: 1/1)

4

5

6