Elektroda.pl
Elektroda.pl
X
Tektronix
Proszę, dodaj wyjątek dla www.elektroda.pl do Adblock.
Dzięki temu, że oglądasz reklamy, wspierasz portal i użytkowników.

podwojna petla na ATtiny13 - bład

04 Kwi 2008 18:10 1047 3
  • Poziom 13  
    Witam napisalem procedurke ktora ma sterowac zarowka i stopniowo ja rozjasniac przez okres podany w zmiennej "czas" i pojawil sie problem. Czy ktos moze mi powiedziec czego taki fragment kodu nie chce mi sie wykonac?

    Code:
    void zapal(uint8_t czas)
    
    {
    TCCR0A|= _BV(COM0A1);

    OCR0A=0;
    while(OCR0A<255)
       {
       OCR0A++;
       while(czas>1) {czas--;_delay_loop_2(116);};
       };
    };


    glownie chodzi o to ze nie wykonuje sie petla wewnetrzna opozniajaca (podejrzewam ze kazda petla podwojna bedzie miala ten problem). Program sie kompiluje bez zadnych komunikatow ale po wgraniu do procka nie dziala tak jak trzeba. Zajelo mi troche czasu zeby sie zorientowac o co chodzi ze program nie dziala tak jak sobie zalozylem ale dalej nie wiem dlaczego tak sie dzieje. jezeli zastapie petle opozniajaca opoznieniem o odpowiedniej dlugosci to procedura dziala normalnie. w innej czesci programu petla taka sama jak ta wewnetrzna dziala zgodnie z zalozeniem
  • Tektronix
  • Pomocny post
    Poziom 24  
    A jak dokładnie ten program "nie działa"?
    Według zapisu powinien działać tak:
    -zwiększa wypełnienie o 1 (OCR0A=1)
    -odczekuje zadany czas (czas*delay_loop_2)
    -zwiększa wypełnienie "bez zatrzymywania" aż do 255

    Radziłbym dodać zmienną pomocniczą np. czas2 i taki zapis:
    Code:

    void zapal(uint8_t czas)
    {
    uint8_t czas2;
    TCCR0A|= _BV(COM0A1);

    OCR0A=0;
    while(OCR0A<255)
       {
       OCR0A++;
       czas2=czas;
       while(czas2>1) {czas2--;_delay_loop_2(116);};
       };
    };
  • Tektronix
  • Poziom 13  
    kurde teraz widze jaka glupote walnalem :P jak ja moglem tego nie zauwazyc. Petla opozniajaca na cala procedure wykonywala sie tylko raz w moim przypadku. Dzieki bardzo!!!
  • Poziom 22  
    Jakby ktoś z zewnątrz zajrzał może wynajdzie błąd, bo samemu póki co nic nie widzę. Taki oto programik. Ma generować dwie szpilki na wyjściu w określonym odstępie i co określony czas:

    Code:
    ----- SZPILKA-----
    
    void pulse(){
       IR_ON;
       asm("nop");
       asm("nop");
       asm("nop");
       IR_OFF;
    }

    -----MAIN-----
    int main(){
       OCR0A   =   PULSE_DELAY;                        
       TIMSK0   |=   (1<<OCIE0A);                                   TCCR0A   |=   (1<<WGM01);                        
       asm("sei");                                 
       pulse();                                         TCNT0   =   0;                              
       TCCR0B   |=   (1<<CS00);
            WDTCR   |=   (1<<WDTIE);                     
       WDTCR   |=   (1<<WDP2) | (1<<WDP1);      
       MCUCR   |=   (1<<SE);                        
       asm("sleep");                                 
       for(;;);                                    
    }


    Ma wykonać pierwszą szpilkę, przygotować timer do przerwania kiedy ma być wykonana druga szpilka i włączać WDT żeby wygenerował przerwanie żeby powtórzyć sekwencję generacji szpilek. Na końcu przejście w IDLE MODE.

    Code:
    SIGNAL (SIG_OUTPUT_COMPARE0A){
    
    
       TCCR0B   &=   ~(1<<CS00);                        
       MCUCR   &=   ~(1<<SE);                        
       pulse();
       WDTCR   |=   (1<<WDTIE);                        
       asm("sei");
       MCUCR   |=   (1<<SM1) | (1<<SE);                  
       asm("sleep");                                 
    }


    Ma wygenerować drgugą szpilkę i przejść w POWER DOWN w oczekiwaniu na przerwanie z WDT generujące sekwencję od początku.

    Code:
    SIGNAL (SIG_WATCHDOG_TIMEOUT){
    
       MCUCR   &=   ~((1<<SM1) | (1<<SE));                  
       pulse();
       TCNT0   =   0;                              
       TCCR0B   |=   (1<<CS00);                        
       asm("sei");                                 
       MCUCR   |=   (1<<SE);                        
       asm("sleep");                                 
    }


    Podobnie jak MAIN. Generacja pierwszej szpilki i czekanie na przerwanie z timera.

    Wszystko chodzi prawie dobrze, jednak widzę na oscyloskopie, że układ generuje niekiedy 3 szpilki (podejrzewam, że co drugi raz). Widzę, że to wykonaniu przerwania z WDT następuje reset całego procka !!!!! i stąd ta trzecia szpilka. Nigdzie nie włączałem przecież WDE, skąd ten reset i to nie za każdym razem?

    Dodam, że jak nie wchodzę w POWER DOWN to wszystko jest OK i nie ma resetu.


    Proszę umieszczać listingi programów w znacznikach "Code". [c_p]