-         
+ Antworten
Seite 1 von 2 12 LetzteLetzte
Ergebnis 1 bis 10 von 13

Thema: Timer / Interrupte in C

  1. #1
    Neuer Benutzer Öfters hier
    Registriert seit
    27.05.2004
    Beiträge
    6

    Timer / Interrupte in C

    Hi!

    Hat jemand von euch vielleicht einen Timer für einen AVR Mikrocontroller,
    der via Interrupts funktioniert, aber ohne PWM und alles andere?
    Der soll natürlich in C geschrieben sein, nicht in Assembler.
    Ich verstehe nämlich immer noch nicht, wieso meine Versuche bei
    mir, einen Timer zu programmieren fast immer gescheitert sind.

    Martin

  2. #2
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    29.01.2004
    Beiträge
    2.441
    C kann ich leider nicht und habe auch keine Beispiele.

    Bei Bascom sind aber einige dokumentierte Beispielprogramme unter anderem auch für den Einsatz von Timern dabei.

    Ist zwar Basic, aber wenn du C kannst verstehst du wahrscheinlich trotzdem worum, bzw. wie es geht.

    Die Beispiele kannst du dir hier einzeln runteladen: http://www.mcselec.com/download/bascomlt/samples.zip

  3. #3
    Neuer Benutzer Öfters hier
    Registriert seit
    27.05.2004
    Beiträge
    6
    Ich habe es mir angeschaut, aber Basic ist ganz anders als
    C. Damit komme ich leider nicht zurecht.... Trotzdem danke für
    den Tip. Hat jemand anderes vielleicht ein Beispielprogramm für solch
    einen Timer?

  4. #4
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    28.04.2004
    Ort
    Nähe Köln
    Alter
    50
    Beiträge
    247
    Hallo

    Hier mal ein kleines Testprogramm für den Timer0 Int.


    Code:
    /* 
    Kleines Testprogramm zum testen des TIMER0 im Mega8
    Timer0 erzeugt ca alle 10ms einen Interrupt.
    
    Bei 4 MHZ dauert ein Takt 250 ns d.h. für 10 ms müssen wir
    nach 40000 Takten einen Overflow mit TIMER0 erzeugen. Da
    TIMER0 aber nur bis 255 zählen kann und bei 255 -->  256 einen Overflow
    INT erzeugt, haben wir ein Problem. Also setzen wir den Vorteiler
    von TIMER0 auf 256. Damit ergibt sich 40000 / 256 = 156,25.
    
    Da wir den Wert 156 schlecht abfragen können und der Overflow INT
    nur bei 255 --> 256 auftritt, laden wir den TIMER0 mit 100 vor. ( 256 - 156) 
    Der Timer0 zählt dann von 100 aufwärts und löst damit, nach
    156 * 256 Takten = 39936 * 250 ns = 9,984 ms einen Overflow INT aus.
    
    In der Overflow INT Routine, müssen wir dann die ca 10 ms INT nur noch zählen
    und entsprechend auswerten.
    
       Chip       Mega 8 
       Takt       4.00 MHz 
       Stand:     Test, läft im Simulator 
      Verfasser: Dino Dieter            */ 
        
    #include <avr/io.h> 
    #include <stdlib.h> 
    #include<avr/interrupt.h>			
    #include<avr/signal.h>
    
    
    //Definition einiger Datentypen, reine Geschmacksache 
    #define uchar   unsigned char      // 1 Byte ohne Vorzeichen 0 bis 255 erlaubt 
    #define uint   unsigned int      // 2 Byte ohne Vorzeichen 0 bis 65535 erlaubt 
    
    //Definition der Konstanten
    #define reload   100			// Reload Wert für Timer0  256 - 100 = 156 
    
    // Defintion der globalen Variablen
    volatile uchar count_10ms;		// Zähler für die 10ms INT
    
    // Timer0 Overflow Routinen, Aufruf alle 10 ms
    SIGNAL  (SIG_OVERFLOW0 )
    {
    		TCNT0 = reload;					//Timer0 neu einstellen auf 100
    		count_10ms++;					//Zähler um 1 erhöhen
    		
    		if(count_10ms >= 100)			//Abfrage 1 Sekunde vorbei, 100 * 10 ms
    		{
    			//dann LED umschalten
    			if(bit_is_set(PORTB,1))		//PIN gesetzt ???
    					PORTB = 0x00;
    			else
    		    	   PORTB = 0x01;
    				   
    		count_10ms = 0;					//Zähler löschen
    		}
    }
    
    //Einstellen der Hardware des AVR +++++++++++++++++++++++++++++++++++++++++++++ 
    void init(void) 
    { 
    		//Port einstellen
    		DDRB = 0x01;					//PortB.1 auf Ausgang
    		
    		//TimerO einstellen
    		TIMSK = _BV(TOIE0);			// Timer0 Overflow INT erlauben
    		TCNT0  = reload;						// TIMER0 vorladen mit 100
    		TCCR0 = _BV(CS02) ;			// Vorteiler auf 256, ab hier läuft der TIMER0
    		
    		// Global Interrupts freigeben
    		sei();
    } 
    
    //Hauptprogramm, hier startet der uC ++++++++++++++++++++++++++++++++++++++++++ 
    void main (void) 
    { 
    
        init();            // Hardware einstellen gehen 
                          
       for(;;)            // Endlosschleife 
       { 
       } 
        
    }
    MFG
    Dieter

  5. #5
    Neuer Benutzer Öfters hier
    Registriert seit
    27.05.2004
    Beiträge
    6
    Wodran kann es liegen, dass dieses Programm bei mir nicht funktioniert?
    Das Lämpchen an PortB1 bleibt einfach an und blinkt nicht.
    Ich habe es mit einem 1 MHz-Quarz und einem 8 MHz-Quarz ausprobiert.
    Martin

  6. #6
    Gast
    Hallo

    Das Programm schaltet die LED an PORTB PIN 0 um.

    Ändere mal PORTB = 0x01 in

    PORTB = 0x02 oder für ale PINs in PORTB = 0xff um.

    MFG
    Dieter

  7. #7
    Gast
    Noch was vergessen

    Dann mußt du auch noch
    if(bit_is_set(PORTB,1)) ändern in

    if(bit_is_set(PORTB,2))

    MFG
    Dieter

  8. #8
    Gast
    Und noch was.

    DDRB = 0x02;

    sollte man auch ändern.

    MFG
    Dieter

  9. #9
    Neuer Benutzer Öfters hier
    Registriert seit
    27.05.2004
    Beiträge
    6
    Ach, ich meinte eigentlich PortB0. Der ist bei meinem ATmega8 ganz links unten.
    Hast du vielleicht einen coolen Emulator, den du mir empfehlen kannst?
    Ist egal, ob der Emulator unter Windows oder Linux läuft.

    Den simulavr habe ich schon ausprobiert. Er läuft unter Linux, kann aber
    glaube ich keine Interrupts verarbeiten.

    Martin

  10. #10
    Gast
    Hallo

    Ich mache sowas alles mit dem AVRSTUDIO.

    Klappt ganz gut.

    MFG
    Dieter

+ Antworten
Seite 1 von 2 12 LetzteLetzte

Berechtigungen

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