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

[mega8][c] problem z pętlami

bkawlatow 11 Gru 2010 11:43 966 6
REKLAMA
  • #1 8853706
    bkawlatow
    Poziom 10  
    Witam.
    Proszę o pomoc.Napisałem program mający na celu sterowanie trzema kanałami PWM.Proszę o sprawdzenie działania pętli ,nie mam pojęcia gdzie może tkwić problem.Funkcje PWM na początku powinny być wywoływane z wartością 0,a następnie wartość ta zwiększana płynnie do wartości następnego elementu w tabeli.Gdy licznik osiągnie ten poziom wywoływana powinna zostać funkcja opóźniająca.Jednak po wgraniu softu do Atmegi kanały PWM dają stałą wartość.Dodam że wszystko jest sprawne(połączenia i same funkcje PWM1,PWM2,PWM3 sprawdzałem na sztywno ustawionych wartościach wywoływania tych funkcji).Wydaje mi się że jest gdzieś błąd w main() i pętlach while.Proszę o pomoc i wyrozumiałość


    
    
    #include<avr/io.h>
    #include<inttypes.h>
    #include <avr/interrupt.h>
    #define F_CPU 4000000U
    #include<util/delay.h>
    
    
    
    
     void pwm1(int y){
    //ok
    DDRB |= _BV(PB1);
    TCCR1A =  (1<<WGM10) | (1<<COM1A1) | (1<<COM1A0) |(1<<COM1B1) | (1<<COM1B0);
    TCCR1B = _BV(CS10) |_BV(WGM12) ;
    OCR1A = y; //wypełnienie (0 = 0%, 255 = 100%)
    }
    
    
    void pwm2(int y){
    //ok
    DDRB |= _BV(PB2);
    //TCCR1A = _BV(COM1A1) | _BV(COM1B1) | _BV(WGM10);
    TCCR1A =  (1<<WGM10) | (1<<COM1A1) | (1<<COM1A0) |(1<<COM1B1) | (1<<COM1B0);
    TCCR1B = _BV(CS10) |_BV(WGM12) ;
    OCR1B = y; //wypełnienie (0 = 0%, 255 = 100%) 
    }
    
    void pwm3(int y){
    //ok
    DDRB |= _BV(PB3) ;
    TCCR2 = (_BV(WGM21) | _BV(WGM20) | _BV(COM21) | _BV(COM20) | _BV(CS20));
    OCR2 =y;  //wypełnienie (0 = 0%, 255 = 100%)
    }
    
    
    void czekajsek(double y){//petla opozniajaca
    double z;
    z=y/(0.05);
    
    while(z>1)
    {
    _delay_ms(50);
    z--;
    }
    
    
    
    }
    
      
    
       
     int main(void)
    {
    
       DDRC = 0x00;
       PORTC = 0x11;
    int tab[]={0,3,5,10,50,250};
    int i,a;
       while(1)
    {
    i=0;
    a=0;
    	while(a<4)
      		 {
           
    		   pwm1(i);
    			pwm2(i);
    			pwm3(i);
    			czekajsek(1);//odczekanie 1 sek przy wartości podanej w tabeli
    
              while(i<tab[a])//połynne zwiekszanie wypełnienia
                	 {
                	    pwm1(i);
    					pwm2(i);
    					pwm3(i);
    					i++;
    					_delay_ms(10);
    			 	}
           		a++;	
         	}
    
    
    
    
    
    	while(a>0)//to samo w druga strone
       {
            pwm1(i);
    		pwm2(i);
    		pwm3(i);
            czekajsek(1);
    
              while(i>tab[a])
                          {
                                     pwm1(i);
    				pwm2(i);
    				pwm3(i);
    				_delay_ms(10);
    				i--;
    			 }
             	a--;
    		
    	}
    
    
    
    
    
    }
       
    }
    
    
    [/code]
  • REKLAMA
  • #2 8853935
    maniex
    Poziom 10  
    ja mam teorię, że program nie wchodzi do pętli while:



    
    
    
     int main(void)
    {
    
       DDRC = 0x00;
       PORTC = 0x11;
    int tab[]={0,3,5,10,50,250};
    int i,a;
       while(1)
    {
    i=0; 
    a=0;<----------TUTAJ USTAWIASZ 'i' oraz 'a'=0
    	while(a<4) <------TEN WARUNEK JEST SPEŁNIONY
      		 {
           
    		   pwm1(i);
    			pwm2(i);  
    			pwm3(i);  
    			czekajsek(1);//odczekanie 1 sek przy wartości podanej w tabeli<-----DOTĄD SIĘ WYKONUJE
    
              while(i<tab[a])//połynne zwiekszanie wypełnienia<-----TEN WARUNEK NIE JEST SPEŁNIONY, BO i=0 oraz tab[a=0]=0
                	 {
                	    pwm1(i);
    					pwm2(i);
    					pwm3(i);
    					i++;
    					_delay_ms(10);
    			 	}
           		a++;	
         	}
    
    
    
    
    
    	while(a>0)//to samo w druga strone <----TEN WARUNEK TEŻ NIE JEST SPEŁNIONY, BO NIE WYKONAŁA SIĘ PĘTLA POWYŻEJ I 'a' CIĄGLE JEST =0
       {
            pwm1(i);
    		pwm2(i);
    		pwm3(i);
            czekajsek(1);
    
              while(i>tab[a])
                          {
                                     pwm1(i);
    				pwm2(i);
    				pwm3(i);
    				_delay_ms(10);
    				i--;
    			 }
             	a--;
    		
    	}
    
    
    
    
    
    
    


    ja bym jeszcze zamienił funkcję czekajsek(1), na _delay_ms(1000).
  • REKLAMA
  • REKLAMA
  • #4 8854101
    Konto nie istnieje
    Poziom 1  
  • #5 8854124
    maniex
    Poziom 10  
    Freddie Chopin napisał:
    maniex napisał:
    ja mam teorię, że program nie wchodzi do pętli while

    Ja mam teorię, że nie masz racji (poza wywaleniem funkcji czekajsek() i użyciem standardowej wersji).


    rzeczywiście, pomyliłem miejsce nawiasu klamrowego...
  • #6 8854449
    bkawlatow
    Poziom 10  
       while(a<4) <------TEN WARUNEK JEST SPEŁNIONY
             {
           
             pwm1(i);
             pwm2(i); 
             pwm3(i); 
             czekajsek(1);//odczekanie 1 sek przy wartości podanej w tabeli<-----DOTĄD SIĘ WYKONUJE
    
              while(i<tab[a])//połynne zwiekszanie wypełnienia<-----TEN WARUNEK NIE JEST SPEŁNIONY, BO i=0 oraz tab[a=0]=0
                    {
                       pwm1(i);
                   pwm2(i);
                   pwm3(i);
                   i++;
                   _delay_ms(10);
                 }
                 a++;   //zwiekszanie a 
            }
    

    piszesz że ten warunek nie jest spełniony-ok.Ale drugi raz ta pętla wystartuje ze zwiększonym a.I wtedy program wskoczy do tej nie wykonywanej pętli.Chyba że się mylę ale nie wydaje mi sie...
    Dodam że kompilowałem program w Visualu i wszystko gra.Zmieniłem funkcję czekajsek i dalej to samo..
  • REKLAMA
  • #7 8854472
    maniex
    Poziom 10  
    masz rację, pomyliłem się. post wcześniej napisałem, że pomyliłem miejsce zamykającego nawiasu klamrowego ;)
REKLAMA