- Akku Tests und Balkonkraftwerk Speicher         
Seite 2 von 3 ErsteErste 123 LetzteLetzte
Ergebnis 11 bis 20 von 23

Thema: Timer mit einem ATTiny2313 - ERLEDIGT, danke euch allen

  1. #11
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    29.05.2005
    Ort
    Rott am Inn
    Alter
    37
    Beiträge
    373
    Anzeige

    E-Bike
    Hallo,
    also ich häng jetz mal mein Beispiel für den mega8 ms timer an.
    Code:
    #include <avr/io.h>
    #include <avr/interrupt.h>
    
    #define F_CPU 16000000
    #define timer (256-F_CPU/64/1000) 
    int ms;
    
    
    ISR(TIMER0_OVF_vect)											//Timer Interrupt Vector
    {TCNT0 = timer;
     ms++;
    }
    
    
    int main(void)
    {
    //Ports Init 
    DDRC |= (1<<PORTC3);
    
    	
    //Timer Init
    TIMSK |= (1<<TOIE0);											//Timerinterrupt freigeben
    TCCR0 |= (1<<CS00) | (1<<CS01) | (!(1<<CS02));					//Timer Prescaler = 64
    
    sei();															//Interrupts global aktivieren
    
    //main Schleife
        for (;;) 
    	{	if(ms >=100)
    	 	{PORTC ^= (1<<PORTC3);ms = 0;}   
    	
    	
    	}
    }
    läuft nur timer0 über so wird in die timer isr gesprungen. hoffe ich konnt dir helfen. Ach übrigens 0x05 ist 0b00000101.
    mfg franz

  2. #12
    Erfahrener Benutzer Begeisterter Techniker
    Registriert seit
    02.05.2004
    Alter
    39
    Beiträge
    388
    Vielen dank für die antwort, es tut sich schonmal was.

    Ich wäre froh wen du mir zwei dinge noch erklären könntest.
    zum einen was passiert hier?:
    Code:
    ISR(TIMER0_OVF_vect)                                 //Timer Interrupt Vector 
    {TCNT0 = timer; 
     ms++; 
    }
    Timer wird ja durch: (256-F_CPU/64/1000)
    ersetzt. Was passiert den hier genau?
    TCNT0 ist ja das Daten Register des Timer 0.
    Hier wird diesem Register ja ein Wert zugewissen.... wird nicht normal ein Wert aus diesem Register gelesen?
    Die Variable ms wird nach jedem Interupt um 1 erhöht... richtig?


    Code:
    {if(ms >=100) 
           {PORTB ^= (1<<PORTB0);ms = 0;}
    Und was geschieht hier?
    Wen die Variable ms grösser oder gleich 100 ist... also nach 100 interupts...
    Wird PORTB im zustand gewechselt... also High zu low und low zu High... anschliessend wird die Variable ms auf null gesetzt und die Schleife beginnt von vorn?

  3. #13
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    29.05.2005
    Ort
    Rott am Inn
    Alter
    37
    Beiträge
    373
    Hi,
    also zu 1. ich weise timer0 einen erechneten Wert zu um genau auf 1ms zu kommen. Das heißt jeder Interrupt ist 1ms. Dann springt das Programm alle ms in die ISR und weißt dem Register wieder diesen Wert zu und zählt meine Variable 1 hoch. Die Variable timer errechnet sich aus 256(weil der timer0 8-bit breit ist) - Quarztakt/Prescaler/1000 (wegen ms).

    zu 2. ja richtig erkannt nach 100ms wird der Zustand des Ports gewechselt und meine Variable auf 0 zurückgesetzt, dadurch beginnt der Vorgang erneut.
    hoffe es ist jetz klarer sonst frag einfach nochmal nach
    mfg franz

  4. #14
    Erfahrener Benutzer Begeisterter Techniker
    Registriert seit
    02.05.2004
    Alter
    39
    Beiträge
    388
    Es klappt.. endlich. Nur etwas will nicht.
    Ich hab mir folgenden code zusammengeschrieben:
    Code:
    #include <avr\io.h>
    #include <inttypes.h>
    #include <avr\interrupt.h>
    
    #define F_CPU 3686400
    #define timer (256-F_CPU/64/1000) 
    
    #define RotH PORTB0
    #define RotV PORTB1
    #define BlauV PORTB2
    
    int ms; 
    
    void initPorts()
    {
    	DDRB |= (1<<PB0) | (1<<PB1) | (1<<PB2);
    }
    
    ISR(TIMER0_OVF_vect)                                 					//Timer Interrupt Vector 
    {
    	TCNT0 = timer; 
    	ms++; 
    }
    
    int main(void)
    {
    
    	initPorts();														// Timer Interrupt initialisieren
    	TIMSK |= (1<<TOIE0);   
    	TCCR0=0x05;															// 0b00000011, Vorteiler 1024 ca. 4khz
    	sei();                  											// enable interrupts
    	do 
    	{
    
    		PORTB &= ~( (1<<RotH) | (1<<PORTB1) | (1<<PORTB2));				//PORTB Pins 0,1,2 auf low
    
    		if(ms >= 5)
    		{
    			PORTB |= (1<<RotH);											//Rot High
    
    			if(ms >=30) 
    			{
    				PORTB |= (1<<RotV);										//Gelb High
    				if(ms >= 100)
    				{
    					PORTB &= ~(1<<RotH);								//ROT Low
    					PORTB |= (1<<BlauV);								//GRUEN High
    					if(ms >= 200)
    					{
    						ms = 0;											//ms auf NULL
    					}
    					
    
    				}
    				
    			}
    
    		}
    	}
    	while (true);     													
    }
    //======================================================================
    Dieser funktioniert auch, ausser das das setzten von PORTB0 auf low nicht klappt.
    Ich meinte einmal gelesen zu haben, das es damit zusammenhäng wie man die PORT's definiert und schaltet. Also ob man sie erst als Ausgänge setzt und dann auf High oder umgekehrt.

    Kann mir da vieleicht jemand behilflich sein?

  5. #15
    Erfahrener Benutzer Robotik Einstein Avatar von SprinterSB
    Registriert seit
    09.06.2005
    Ort
    An der Saar
    Beiträge
    2.802
    Die Ports werden ja immer nur sehr kurz auf HIGH gesetzt, weil sie in jedem Durchlauf der do-Schleife wieder auf LOW gesetzt werden. Ähmliches gilt nochmals für PORTB0. Du solltest hier komplett in if-then-else verzweigen und immer das setzen/löschen, was gerade angesagt ist statt die Werte immer wieder hin- und her zu setzen.


    Noch was generelles:
    -- korrekt schreibt man avr/io.h, nicht avr\io.h (auch unter Win32)
    -- der Zugriff auf ms müsste eigentlich atomar sein, sollte aber für das Programm hier trotzdem zu keinen Ausfällen wie Kernschmelze führen
    Disclaimer: none. Sue me.

  6. #16
    Erfahrener Benutzer Begeisterter Techniker
    Registriert seit
    02.05.2004
    Alter
    39
    Beiträge
    388
    Damit dieses Problem weg ist möste ich einen Operator haben mit dem ich abfragen könnte ob ms zum Beispiel zwischen 50 und 70 liegt anstatt nur grösser/gleich als.

    if(ms >=50 & <= 70) klappt nicht.

    Oder muss ich das ganz anderst machen?
    Wäre sehr froh wen mir jemand ein Beispiel machen könnte wie man es richtig macht.

    Dankeschön

  7. #17
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    29.05.2005
    Ort
    Rott am Inn
    Alter
    37
    Beiträge
    373
    Hi,
    also du musst wenn dann schreiben if(ms>=50 & ms<=70) dann klappts auch , hoffe ich konnt dir helfen.
    mfg franz

  8. #18
    Erfahrener Benutzer Begeisterter Techniker
    Registriert seit
    02.05.2004
    Alter
    39
    Beiträge
    388
    Sehr schön, so klappts. danke euch vielmals

  9. #19
    Erfahrener Benutzer Begeisterter Techniker
    Registriert seit
    02.05.2004
    Alter
    39
    Beiträge
    388
    Ich hab das programm nun auf den Tiny geschrieben.
    Nur scheint es darauf nicht zu funktionieren. Das ist mein Code:
    Code:
    #include <avr/io.h> 
    #include <inttypes.h> 
    #include <avr/interrupt.h> 
    
    #define F_CPU 3686400 
    #define timer (256-F_CPU/64/1000) 
    
    #define RotH PORTB0 
    #define RotV PORTB1 
    #define BlauV PORTB2 
    
    int ms; 
    
    void initPorts() 
    { 
       DDRB |= (1<<PB0) | (1<<PB1) | (1<<PB2); 
    } 
    
    ISR(TIMER0_OVF_vect)                                                //Timer Interrupt Vector 
    { 
       TCNT0 = timer; 
       ms++; 
    } 
    
    int main(void) 
    { 
    
       initPorts();                                          // Timer Interrupt initialisieren 
       TIMSK |= (1<<TOIE0);    
       TCCR0A=0x05;                                             // 0b00000011, Vorteiler 1024 ca. 4khz 
       sei();                                                   // enable interrupts 
    
       do 
       { 
    
          if(ms <= 1) 
          { 
             PORTB &= ~( (1<<RotH) |   (1<<RotV) | (1<<BlauV));                           //PORTB Pins 0,1,2 auf low 
          } 
    
          if(ms >= 5& ms <= 100) 
          { 
             PORTB |= (1<<RotV);       
          } 
    
          if(ms >= 100& ms <= 210) 
          { 
             PORTB |= (1<<RotH); 
          } 
    
          if(ms >= 210& ms <= 400 ) 
          { 
             PORTB |= (1<<BlauV); 
             PORTB &= ~(1<<RotV); 
          } 
    
          if(ms >= 600) 
          { 
             ms = 0; 
          } 
    
       } 
       while (true);    
    
    }
    Ich habe einzig den TCCR0=0x05; auf TCCR0A=0x05; gewechselt da der beim Tiny anderst heisst. Hab ich sonst noch einen Fehler?
    Auf dem Mega 8 hat es wunderbar funktioniert

  10. #20
    Erfahrener Benutzer Begeisterter Techniker
    Registriert seit
    02.05.2004
    Alter
    39
    Beiträge
    388
    Weis dazu keiner etwas?

Seite 2 von 3 ErsteErste 123 LetzteLetzte

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •  

12V Akku bauen