- 12V Akku mit 280 Ah bauen         
Ergebnis 1 bis 5 von 5

Thema: Timer 1 nutzen bei einem Tiny26

  1. #1
    Benutzer Stammmitglied
    Registriert seit
    09.05.2004
    Ort
    Mannheim
    Beiträge
    79

    Timer 1 nutzen bei einem Tiny26

    Anzeige

    LiFePo4 Akku selber bauen - Video
    Hallo,

    könnte mir mal jemand ganz kurz sagen wieso, der Timer 1 beim Tiny26 (und wahrscheinlich auch anderen) so nicht funktioniert?
    Code:
    TIMSK |= (1<<TOIE0) | (1<<TOIE1);
    TIMSK &= ~(1<<OCIE1A) & ~(1<<OCIE1B);
    TCCR0 = B00000001;	// CK / 1 für Timer 0
    PLLCSR &= ~(1<<PCKE);	// CK als Timer 1 Clocksource
    TCCR1A = 0;
    TCCR1B = B00001110;	// CK/8192 -> 3.8 mal pro Sek wird der Ovf aufgerufen
    sei();
    Der Timer scheint nicht anzugehen? Timer 0 funktioniert dagegen!

    Vielen Dank und viele Grüße,

    Daniel

  2. #2
    Erfahrener Benutzer Begeisterter Techniker Avatar von H.A.R.R.Y.
    Registriert seit
    15.09.2005
    Beiträge
    306
    Hm, woher weißt Du, daß der eine Timer arbeitet, der andere dagegen nicht? Um die Interrupts auszuwerten, müssen auch entsprechende Programmteile in die Vektoren eingehängt werden. Die finde ich in Deinem Code-Auszug nicht.

    Falls Du den Simulator aus dem AVR-Studio verwendest: Schau in der Hilfe nach, dort steht bei welchen Chips welche Simulationen NICHT arbeiten. Betrifft aber nur die Simulation, die ICs selbst funktionieren.
    a) Es gibt keine dummen Fragen, nur dumme Antworten
    b) Fehler macht man um aus ihnen zu lernen
    c) Jeder IO-Port kennt drei mögliche Zustände: Input, Output, Kaputt

  3. #3
    Benutzer Stammmitglied
    Registriert seit
    09.05.2004
    Ort
    Mannheim
    Beiträge
    79
    Oook Ich glaube der Interrupt geht doch nicht, das komplette Prog. sieht bist jetzt so aus:
    Code:
    #include <avr/io.h>
    #include <avr/eeprom.h>
    #include <avr/interrupt.h>
    #include <avr/wdt.h>
    #include <avr/signal.h>
    #include <avr/delay.h>
    #include <stdbool.h>
    #include "binary.h"
    
    #define EEPROM __attribute__ ((section (".eeprom")))
    #define	LED	PA7
    #define DDRLED	B10000000
    #define DDR1	B00000010
    
    #define US1IN	PA1
    #define US1OUT	PA0
    
    
    uint8_t stop;
    volatile uint16_t countUS1 = 0;
    volatile uint8_t messungUS1 = false;
    volatile uint16_t ergUS1 = 0;
    
    SIGNAL(TIM1_OVF_vect)
    {
    	//PORTA ^= (1<<LED);	 // LED Togglen
    	PORTA &= ~(1<<LED);
    
    	countUS1 = 0;
    	PORTA &= ~(1<<US1IN);	// Senden
    	_delay_us(10);		// Warten
    	PORTA |= (1<<US1IN);
    	messungUS1 = true;
    }
    
    SIGNAL(TIM0_OVF_vect)
    {
    	// wird 31250 mal pro Sek aufgerufen also etwas mehr als 1 cm!
    	PORTA &= ~(1<<LED);
    	if (messungUS1)
    	{
    		if ((PINA & (1<<US1OUT)) == (1<<US1OUT))	// ist das Signal schon da?
    		{
    			// ja!
    			messungUS1 = false;
    			ergUS1 = countUS1;
    		}
    		else
    		{
    			countUS1++;
    			// cut bei theoretischen 4m
    			if (countUS1>730)
    				messungUS1 = false;
    		}
    	}
    }
    
    
    int main (void)
    {
    	wdt_disable();
    	DDRA = DDRLED + DDR1;
    	DDRB = 0x0;	// alle als Eingang
    	PORTB = 0xff;	// Und Pullups
    	stop = false;
    	PORTA = 0xff;
    
    	TIMSK |= (1<<TOIE0) | (1<<TOIE1);
    	TIMSK &= ~(1<<OCIE1A) & ~(1<<OCIE1B);
    	TCCR0 = B00000001;	// CK / 1 für Timer 0
    	PLLCSR &= ~(1<<PCKE);	// CK als Timer 1 Clocksource
    	TCCR1A = 0;
    	TCCR1B = B00001110;	// CK/8192 -> 3.8 mal pro Sek wird der Ovf aufgerufen
    	sei();
    	PORTA=0x0;
    	while(stop==false)
    	{
    		for (uint8_t i=0;i<10;i++)
    			_delay_ms(250);
    		PORTA ^= (1 << LED);
    		if (ergUS1!=0)
    		{		
    			for (uint8_t i=0;i<20;i++)
    				_delay_ms(250);
    			PORTA |= (1 << LED);
    			for (uint16_t i=0;i<ergUS1;i++)
    				_delay_ms(250);
    			PORTA &= ~(1 << LED);
    			ergUS1 = 0;
    		}
    	}
    	return 0;
    }
    Auch mit den alten Vektorbezeichnungen funktioniert es Leider nicht...
    Wenn ich jedoch das sei(); weglasse, blinkt zumindest die LED

    Könnte mir jemand einen Tipp geben?

    Vielen Dank,

    Daniel Stengel

  4. #4
    Erfahrener Benutzer Begeisterter Techniker Avatar von H.A.R.R.Y.
    Registriert seit
    15.09.2005
    Beiträge
    306
    Ich bin nicht der Held was C angeht; ich programmiere lieber gleich in Assembler, also kann es sein, daß ich das eine oder andere falsch verstehe. Ich versuche Dir trotzdem mal zu helfen:

    Wenn ich jedoch das sei(); weglasse, blinkt zumindest die LED
    Also sowohl Deine beiden Interruptroutinen als auch die Hauptschleife manipulieren am Status der LED. Ohne SEI sind die Interrupts wirkungslos und nur noch Dein Hauptprogramm kontrolliert die LED. So läßt sich natürlich nicht herausfinden, welcher IRQ arbeitet und wer was macht.

    Mein Vorschlag ist:
    Lege das obige Programm beiseite und führe folgende Schritte durch:
    Baue das einfachst mögliche Programm um die LED von Timer0-IRQ aus blinken zu lassen (Portinit, Timerinit, Deklaration der Interruptroutine, leere Schleife nach Inits und SEI). Sobald Deine LED blinkt, weißt Du was für Timer0 zu tun ist. Das Ganze wiederholst Du für Timer1, bis Du es auch dort hinbekommen hast. Wenn Du magst, kannst Du ja dann noch versuchen beides zu kombinieren: Timer0 schaltet die LED ein, Timer1 schaltet sie wieder aus - beide laufen mit leicht unterschiedlicher Frequenz, so das Du es auch blinken siehst. Dann sollte es möglich sein das obige Programm zu kontrollieren und zur Funktion zu bewegen - wenn der Fehler nicht ganz wo anders liegt.

    Wird der Stack eigentlich vom Compiler verwaltet, oder muß der Stackpointer auch initialisiert werden?

    Die Bezeichnungen der IRQ-Vektoren würde ich im interrupt.h vermuten. Wie erzeugt eigentlich delay.h die Verzögerung? Wenn der einen Timer verwendet, dann stört er Dich damit ganz gewaltig...
    a) Es gibt keine dummen Fragen, nur dumme Antworten
    b) Fehler macht man um aus ihnen zu lernen
    c) Jeder IO-Port kennt drei mögliche Zustände: Input, Output, Kaputt

  5. #5
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    19.02.2007
    Beiträge
    210
    ich würde die register direkt setzen um den timer 1 8bit am tiny 26 direkt anzufahren

    tccr1b zb 135 für prescale 64 dann läuft der timer

    wenn tccr1a auf compare oder pulsmode
    dann enable timer1 sonst läuft er nicht

    auch timsk sollte den richtigen wert laut datenblatt erhalten

    und zum testen dann mal orc1c auf 255
    und mit ocr1b dagegen laufen dann sollte an portb.3 ein signal kommen

Berechtigungen

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

MultiPlus Wechselrichter Insel und Nulleinspeisung Conrad