logo elektroda
logo elektroda
X
logo elektroda
REKLAMA
REKLAMA
Adblock/uBlockOrigin/AdGuard mogą powodować znikanie niektórych postów z powodu nowej reguły.

Regulator SL-BLDC na Atmega8

piotrek700 11 Sie 2010 16:03 4770 8
REKLAMA
  • #1 8388032
    piotrek700
    Poziom 13  
    Witam, próbuje napisać program sterujący silnikiem bezczujnikowym BLDC. Zaczerpnąłem schemat ze strony Link i lekko go zmodyfikowałem. Wiem, wiem, na stronce jest również wsad do mikro-kontrolera ale próbuję napisać własny program, tak dla praktyki. Sterownik ma tylko kręcić silnikiem na max'a wiec zmieniłem wyjścia pwm na inne(w sumie mogły zostać stare) Napisałem kilka linii kodu i tu się pojawia problem. Korzystam z różnych not katalogowych z internetu ale wciąż nie udaje mi się uruchomić silnika. Steruje silnikiem wykrywając przejście przez zero napięcia na wolnej fazie. Poniżej zamieszczam kod, jak ktoś ma czas może żuci okiem i zobaczy, dlaczego to nie chce działać. Z góry dziękuję.
    //wyjscia tranzystorów mocy, stan wysoki
    #define CONNECT_A_H_P 		PORTD|=0x02   //D1
    #define CONNECT_A_H_N 		PORTD|=0x01   //D0
    #define CONNECT_B_H_P 		PORTC|=0x10   //C4
    #define CONNECT_B_H_N 		PORTC|=0x08   //C3
    #define CONNECT_C_H_P 		PORTC|=0x02   //C1
    #define CONNECT_C_H_N 		PORTC|=0x01   //C0
    //wyjscia tranzystorów mocy, stan niski
    #define CONNECT_A_L_P 		PORTD&=~0x02  //D1
    #define CONNECT_A_L_N 		PORTD&=~0x01  //D0
    #define CONNECT_B_L_P 		PORTC&=~0x10  //C4
    #define CONNECT_B_L_N 		PORTC&=~0x08  //C3
    #define CONNECT_C_L_P 		PORTC&=~0x02  //C1
    #define CONNECT_C_L_N 		PORTC&=~0x01  //C0
    //definicje właczania fazy od 1-6
    #define PHASE_1     		{PORTD|=0x02;  PORTC|=0x08; }
    #define PHASE_2				{PORTD|=0x02;  PORTC|=0x01; }
    #define PHASE_3				{PORTC|=0x10;  PORTC|=0x01; }
    #define PHASE_4				{PORTC|=0x10;  PORTD|=0x01; }
    #define PHASE_5				{PORTC|=0x02;  PORTD|=0x01; }
    #define PHASE_6				{PORTC|=0x02;  PORTC|=0x1B; }
    #define PHASE_ALL_H         {PORTD|=0x03;  PORTC|=0x1B; }
    #define PHASE_ALL_L         {PORTD&=~0x03; PORTC&=~0x1B;}
    //definicje wejść przetworników ADC
    #define ADC_A  						ADMUX=5
    #define ADC_B  						ADMUX=2
    #define ADC_C  						ADMUX=7
    //ustawienia diodu zielonej
    #define LED_GREEN_ON  				PORTB|=0x01;
    #define LED_GREEN_OFF 				PORTB&=~0x01;
    #define LED_GREEN_ROT 				PORTB^=0x01;
    //definicja zbocza komparatora
    #define DETECTION_FALLING_INT       ACSR |=  0x02;
    #define DETECTION_RISING_INT        ACSR |=  0x03;
    #define DETECTION_BOTH_INT          ACSR &= ~0x03;
    //#define DETECTION_FALLING_INT       {ACSR &= ~0x03; ACSR |=  0x02; PORTD&=~0x40;}
    //#define DETECTION_RISING_INT        {ACSR &= ~0x03; ACSR |=  0x03; PORTD|= 0x40;}
    //#define DETECTION_BOTH_INT          {ACSR &= ~0x03;}
    //
    #define CENTER_H PORTD|=0x40;
    #define CENTER_L PORTD&=~0x40;
    
    #include <avr/io.h>
    #include <util/delay.h>
    #include <avr/interrupt.h>      
    #include <avr/signal.h> 
    
    int phase=1;
    
    int main(){
    	int i=4;
    	DDRD|=0x03;	 					//D0, D1         -wyjscia faz
    	DDRC|=0x1B; 					//C0, C1, C3, C4 -wyjscia faz
    	DDRB|=0x03;                     //B0, B1 		 -wyjscia LED
    	PHASE_ALL_L;                    //wszystkie fazy na 0
    	SFIOR|=0x08;			     	//włączenie multipexera komparatora					
    	ADCSRA=0x00;                    //wyłaczenie przetwornika adc
    	ADMUX=1;                        //wejscie komparatora - podłaczone do ADC1
    	ADCSRA&=~0x80; 					//wyłaczenie przetwornika ADC
    	sei(); 							//włącz obsługe przerwań
    	ACSR|=0x08;              		//właczenie przerwań od komparatora
    	while(1){
    			/*
            	PHASE_ALL_L;
    			PHASE_1;
    			_delay_ms(i);
    			PHASE_ALL_L;
    			PHASE_2;
    			_delay_ms(i);
    			PHASE_ALL_L;
    			PHASE_3;
    			_delay_ms(i);
    			PHASE_ALL_L;
    			PHASE_4;
    			_delay_ms(i);
    			PHASE_ALL_L;
    			PHASE_5;
    			_delay_ms(i);
    			PHASE_ALL_L;
    			PHASE_6;
    			_delay_ms(i);	*/
    	}
    }
    //przerwanie od komparatora porównującego BMF ze sztucznej masy i jednej fazy
    SIGNAL(SIG_COMPARATOR){
    		LED_GREEN_ROT;
    		
    		switch (phase){
    				case 1:{
    			 		ACSR&=~0x08;              		//wyłączenie przerwań od komparatora
    					PHASE_ALL_L;
    					PHASE_1;
    					ADC_C; 
    					DETECTION_FALLING_INT;
    					phase++;
    					ACSR|=0x08;              		//właczenie przerwań od komparatora
    					break;
    				}
    				case 2:{
    					ACSR&=~0x08;              		//wyłączenie przerwań od komparatora
    					PHASE_ALL_L;
    					PHASE_2;
    					ADC_B; 
    					DETECTION_RISING_INT;
    					phase++;
    					ACSR|=0x08;              		//właczenie przerwań od komparatora
    					break;
    				}
    				case 3:{
    					ACSR&=~0x08;              		//wyłączenie przerwań od komparatora
    					PHASE_ALL_L;
    					PHASE_3;
    					ADC_A; 
    					DETECTION_FALLING_INT;
    					phase++;
    					ACSR|=0x08;              		//właczenie przerwań od komparatora
    					break;
    				}
    				case 4:{
    					ACSR&=~0x08;              		//wyłączenie przerwań od komparatora
    					PHASE_ALL_L;
    					PHASE_4;
    					ADC_C; 
    					DETECTION_RISING_INT;
    					phase++;
    					ACSR|=0x08;              		//właczenie przerwań od komparatora
    					break;
    				}
    				case 5:{
    					ACSR&=~0x08;              		//wyłączenie przerwań od komparatora
    					PHASE_ALL_L;
    					PHASE_5;
    					ADC_B; 
    					DETECTION_FALLING_INT;
    					phase++;
    					ACSR|=0x08;              		//właczenie przerwań od komparatora
    					break;
    				}
    				case 6:{
    					ACSR&=~0x08;              		//wyłączenie przerwań od komparatora
    					PHASE_ALL_L;
    					PHASE_6;
    					ADC_A; 
    					DETECTION_RISING_INT;
    					phase=1;
    					ACSR|=0x08;              		//właczenie przerwań od komparatora
    					break;
    				}
    		}	
    }
    

    Schemat:
    Regulator SL-BLDC na Atmega8
  • REKLAMA
  • #2 8388554
    marcelix007
    Poziom 14  
    Jakie są objawy? Coś drga? sprawdzałeś czy MOSY się otwierają? Jakie mosfety użyłeś?
  • REKLAMA
  • #3 8388734
    piotrek700
    Poziom 13  
    Sprawa wygląda tak, jak odpalę program bez przerwań z tym co jest od komentowane w pętli głównej to silnik się obraca, powoli bo powoli ale się obraca, jak odpalę program w formie jaką podałem powyżej to obróci raz, albo i nie, zatrzyma się na jednej fazie i stoi, nawet ręczny rozruch nie pomaga. Do przerwania program wchodzi bo widzę na diodzie co się dzieje. MOSY na pewno się otwierają. Używam: IRLR2905ZPBF oraz IRFR5305PBF
  • #4 8388815
    janbernat
    Poziom 38  
    Może powinieneś wyłączać przerwania od komparatora tylko na czas zmiany kanału:
    ACSR&=~0x08;
    ADC_C;
    ACSR|=0x08;
    Bo tak to przerwania masz zablokowane przez cały czas obsługi switch-a.
    P.S.
    I nie używaj:
    _delay_ms(i);
    bo to prowadzi do dużego rozrostu kodu- o czasie nic nie wiem.
    raczej _delay_ms(1);
    czy ile tam potrzeba.
  • REKLAMA
  • Pomocny post
    #5 8388908
    marcelix007
    Poziom 14  
    #define PHASE_1 {PORTD|=0x02; PORTC|=0x08; }
    #define PHASE_2 {PORTD|=0x02; PORTC|=0x01; }
    #define PHASE_3 {PORTC|=0x10; PORTC|=0x01; }
    #define PHASE_4 {PORTC|=0x10; PORTD|=0x01; }
    #define PHASE_5 {PORTC|=0x02; PORTD|=0x01; }
    #define PHASE_6 {PORTC|=0x02; PORTC|=0x08; }

    Zdaje się że Tu jest błąd, ale nie jestem pewien czy jedyny
  • #6 8388957
    piotrek700
    Poziom 13  
    Racja, tu jest błąd, obraca się ale powoli i szarpie, wiec jeszcze coś zostaje. A co do przerwań komparatora specjalnie wyłączam na czas zmiany fazy i drugiego wejścia komparatora żeby nie wyzwolić przypadkowo niepotrzebnego przerwania.
  • #7 8389029
    marcelix007
    Poziom 14  
    Jaki masz efekt po ustawieniu wywoływania przerwania komparatora na zbocze rosnące i opadające?
  • REKLAMA
  • #8 8389054
    piotrek700
    Poziom 13  
    Kolego marcelix007 jesteś BOGIEM:) Ustawiłem zbocze na rosnące i opadające i działa:) Teraz muszę wykombinować mocny zasilacz z dużym amperażem. A przy okazji mam jeszcze jedno pytanie: sterownik działa w oparciu o wykrywanie przejścia siły elektromotorycznej przez zero na wolnym uzwojeniu. O ile mi wiadomo przejście przez zero następuje 30 stopni przed zmianą fazy i tu rodzi się moje pytanie, czy nie należy odczekać jakoś tych 30 stopni i wtedy zmieniać fazę?
REKLAMA