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

[ATmega32][C/avrgcc] Konroler wariuje na początku pracy

Theotus 18 Lut 2010 11:40 864 2
REKLAMA
  • #1 7712665
    Theotus
    Poziom 2  
    Witam,

    Problem z którym się spotkałem jest co najmniej dziwny i nie moge rogrzyc co moze byc jego przyczyną, podejrzewam przerwania. Od niedawna programuje uC, więc proszę o wyrozumiałość.
    Mianowicie:
    Przed dodaniem PWM na OC1A (PD5), wszystko działało ok (tak przynajmniej wyglądało). Zastosowałem FAST PWM, sterowanie dmuchawą w piecu CO:
    
    void dmuch_init(void){
    setB(TCCR1A,0x80);  //COM1A1
    setB(TCCR1B,0x08); //WGM12
    setB(TCCR1A,0x02); //WGM11
    setB(TCCR1B,0x10); // WGM13
    ICR1 = 5500;
    }
    

    funkcja wywoływana w main przed główną pętlą while(1).
    Wewnątrz while(1), w odpowiednim miejscu wywołuję funkcję której definicja to:
    
    void moc_dmuch(int moc) { 
    	OCR1A = 5500 - (moc*55);
    }

    Chodzi ładnie. Steruje mocą dmuchawy.
    Dodatkowo generuję sobie przerwania timerem 2, odliczając dzięki niemu odstępy czasu potrzebne do wywoływania innych funkcji w zadanych odstępach (np. zebranie pomiarów z czujników co 3s itp).
    
    void przerwania_init(void) {
      cli();
       ASSR = (0 << AS2);
        setB(TCCR2, 0x07); //cs20,21,22 prescaler 8 
        clearB(TCCR2, 0x40); //wgm20
        clearB(TCCR2, 0x08); //wgm21
        clearB(TCCR2, 0x30); // com21 com20
        // zezwolenie na pracę Timera 2
        TIMSK |= (1 << TOIE2);
    
        // globalne zezwolenie na przerwania
       sei();
    }

    Co overflow wchodzi w :
    
    ISR(TIMER2_OVF_vect)
    {
     // inkrementacja liczników lub zmiana zmiennych globalnych (nic poza tym)
    }
    

    I jak chodzą te dwa Timery, to program co dziwne wychodzi z while(1), uruchamiając ponownie funkcję spoza niej ( ale z main()):
    
    void init_hello(void) {
    		write_command(0x02); // kursor na początek
    		write_text("text");
    		for(int i=1;i<=100;i++)
    			_delay_ms(25);
    		write_command(0x02); // kursor na początek
    		write_text("texxt ");
    		for(int i=1;i<=100;i++)
    			_delay_ms(25);
    		write_command(0x02);
    		write_text("texxxt");
    		for(int i=1;i<=100;i++)
    			_delay_ms(30);
    		write_command(0x02); // kursor na początek
    		write_text("texxxxt");
    		for(int i=1;i<=100;i++)
    			_delay_ms(25);
    		write_command(0x02); // kursor na początek
    		write_text("texxxxxt");
    		for(int i=1;i<=100;i++)
    			_delay_ms(30);
    }

    I tak ze 3 - 4 razy, po czym działa czasem wg programu, czasem niezgodnie z nim. Czasem rzeczywiscie uruchamiajac dmuchawe, czasem nie. Raz również, gdy funkcja powyzsza była zakomentowana, to przogram wyswietlil jednen z tekstów. Jeśli chodzi tylko jeden z timerów, to jest wporzątku.
    
    int main(){
               param_init(); //ustawia param
    	ports_init(); // ustawia porty
    	lcd_setup();//inicj. LCD
    	init_hello(); // powyzsze powitanie
    	adc_init(); // ustawia porty AC, poczatkowe pomiary
    	buttons(f,f_in) // wyswietla Interfejs ( temp, stan peryferiów ON/OFF itp)
    	przerwania_init(); // START PRZERWAŃ, timer 2
               dmuch_init();  //Inicjalizacja timera 1
    
         while(1){
            // wywołanie funkji moc_dmuch(np. 50);
    
         }
    }
    

    Wydaje mi się ze ma to bezpośredni związek z przewaniami. Podejrzewam, ze moze się układ uC resetować z jakiego powodu, dlatego uruchamia init_hello 3 razy. Ale np mimo ze powtarza wywołąnie tej funkcji, to jesli w while(1), włącze któryś z elementów np. podajnik lub pompę to pozostają włączone.
    Jakiekolwiek sugestie mile widziane.
    Dzęki z góry.
  • REKLAMA
REKLAMA