- 3D-Druck Einstieg und Tipps         
Ergebnis 1 bis 9 von 9

Thema: Timer Atmega16 NiboBee

  1. #1

    Timer Atmega16 NiboBee

    Anzeige

    Powerstation Test
    Hallo,

    ich hab ein Problem mit folgenden Code:

    Code:
    #include <C:/Program Files (x86)/NIBObeeLib/include/nibobee/iodefs.h>
    #include <C:/Program Files (x86)/NIBObeeLib/include/nibobee/led.h>
    #include <C:/Program Files (x86)/NIBObeeLib/include/nibobee/delay.h>
    #include <C:/Program Files (x86)/NIBObeeLib/include/nibobee/motpwm.h>
    #include <C:/Program Files (x86)/NIBObeeLib/include/nibobee/i2cmaster.h>
    #include <C:/Program Files (x86)/NIBObeeLib/include/nibobee/sens.h>
    
    #include <C:/Users/Max/Documents/Atmel Studio/6.1/Beschleunigungssensor/Beschleunigungssensor/BMA020.h>
    #include <C:/Users/Max/Documents/Atmel Studio/6.1/Beschleunigungssensor/Beschleunigungssensor/i2c_communicate.c>
    
    #include <avr/io.h>
    
    //Prototyping
    void fahren(int16_t, int16_t);
    void yAchse(void);
    long abstand (long);
    void stop(void);
    
    //Variablendeklaration
    int16_t speed_l, speed_r;
    int8_t sensor_l, sensor_r;
    long mess_abs;
    long counter=0;
    long old=0;
    
    int16_t main()
    {
    	//Pause vor Start 
    	delay(3000);
    	
    	//Initialisierung
    	led_init();
    	void i2c_init(void);
    	motpwm_init();
    	sens_init();
    	
    	enable_interrupts();
    	
    	//Timerinitialisierung
    	TCCR2 = (1<<CS01);
    	TIMSK |= (1<<CS01);
    	sei();
    
    	
    	//PortC Bit 3 als Ausgang setzen
    	DDRC = 0b00001000;
    
    	//PORTC = (1<<PC3); 
    
    //Endlosschleife
    	while(1==1)
    	{	
    	PORTC |= (1<<PC3);
    	
    	#ifndef TIMER2_OVF_vect
    	#endif
    		
    	//Reset
    	led_set(LED_L_RD, 0);
    	led_set(LED_R_RD, 0);
    	led_set(LED_R_YE, 0);
    	
    	//Sensoren abfragen
    		sensor_l	= sens_getLeft();
    		sensor_r	= sens_getRight();	
    		
    	//Abstand
    		if (mess_abs>0)
    		{
    			led_set(LED_R_YE, 1);
    			stop();
    			counter=0;
    		}
    		
    	//Beschleunigungssensor
    
    		//Beschleunigungssensor abfragen
    		yAchse();
    		
    		//Abstand messen
    		abstand(counter);
    		
    		//langsam
    		if (BMA_Y>0 && speed_l != 80 && sensor_l == 0 && sensor_r == 0)
    		{
    			speed_l	= 80;
    			speed_r	= 80;
    			led_set(LED_L_YE, 1);
    		}
    		
    		//schnnell
    		if (BMA_Y<10 && speed_l!=400 && sensor_l == 0 && sensor_r == 0)
    		{
    			speed_l	= 500;
    			speed_r = 500;
    			led_set(LED_L_YE, 0);
    		}
    		
    		
    	//Kolission
    		//Kolission detektieren Sensor links
    		if (sensor_l != 0)
    		{
    			led_set(LED_L_RD, 1);
    		}
    
    		//Kolission detektieren Sensor rechts
    		if (sensor_r != 0)
    		{
    			led_set(LED_R_RD, 1);
    		}
    		
    		fahren(speed_l, speed_r);
    	}
    	return 0;
    }
    
    //Funktionendeklaration
    void fahren(int16_t wert_l, int16_t wert_r)
    {
    	if (sensor_l || sensor_r != 0 )
    	{
    		motpwm_setLeft(-400);
    		motpwm_setRight(-400);
    			
    		delay(2000);
    		
    		motpwm_setLeft(-400);
    		motpwm_setRight(400);
    		
    		delay(500);
    	}
    	
    	motpwm_setLeft(wert_l);
    	motpwm_setRight(wert_r);
    
    }
    
    void yAchse(void)
    {
    	BMA_sleep(0);
    	BMA_init(RANGE_2g | BANDWIDTH_25hz);
    	BMA_acc_y();
    }
    
    long abstand (long counter)
    {
    	PORTC &= ~(1<<PC3);
    	delay(1);
    	PORTC |= (1<<PC3);
    	delay(1);
    	PORTC &= ~(1<<PC3);
    	
    	old = counter;
    	
    	while(PINC & (1<<PINC2))
    	{
    	
    	}
    	
    	mess_abs = counter - old;
    	mess_abs *= 136.53 /1000/10;
    	
    	return mess_abs;
    }
    
    void stop(void)
    {
    	motpwm_setLeft(-400);
    	motpwm_setRight(-400);
    			
    	delay(2000);
    			
    	motpwm_setLeft(-400);
    	motpwm_setRight(400);
    	
    	motpwm_setLeft(-400);
    	motpwm_setRight(400);
    	
    	delay(500);
    	
    	//counter =0;
    }
    
    #ifndef TIMER2_OVF_vect
    #endif
    ISR (TIMER2_OVF_vect)
    {
    	counter = counter + 1;
    }
    Das Programm läuft im Grunde so wie es soll, lediglich der Timer funktioniert nicht. Genauer mess_abs wird nie größer als 0, kann mir jemand einen Denkanstoss geben? Es geht also um die Funktion abstand und den Timer ...

  2. #2
    Erfahrener Benutzer Robotik Visionär
    Registriert seit
    26.11.2005
    Ort
    bei Uelzen (Niedersachsen)
    Beiträge
    7.942
    Das passende Schlüsselwort sollte VOLATILE sein. Damit sollte man alle Variablem kennzeichnen, die in der ISR und im Hauptprogramm genutzt werden.

  3. #3
    Nur bei der Variablendeklaration? Oder auch um ISR und dem Prototyping?

  4. #4
    Erfahrener Benutzer Robotik Einstein Avatar von Searcher
    Registriert seit
    07.06.2009
    Ort
    NRW
    Beiträge
    1.703
    Blog-Einträge
    133
    Code:
    //Timerinitialisierung     
    TCCR2 = (1<<CS01);     
    TIMSK |= (1<<CS01);
    Hier verwendest Du Bits vom Timer0 für Timer2. Kommt mir spanisch vor

    Gruß
    Searcher
    Hoffentlich liegt das Ziel auch am Weg
    ..................................................................Der Weg zu einigen meiner Konstruktionen

  5. #5
    Ich habe den Code mal zerlegt, ist vielleicht übersichtlicher...

    Code:
    void main (void)
    {
    //Timerinitialisierung
    	TCCR2 = 0b001;
    	TIMSK |= (1<<TOIE2);
    	sei();
    
    while(1)
    {}
    
    }
    
    ISR (TIMER2_OVF_vect)
    {
    	counter = counter + 1;
    }
    Dieser Timer sollte bei 15MHz Takt alle 17µs die ISR aufrufen, stimmt das?

  6. #6
    Erfahrener Benutzer Robotik Einstein Avatar von Searcher
    Registriert seit
    07.06.2009
    Ort
    NRW
    Beiträge
    1.703
    Blog-Einträge
    133
    Zitat Zitat von PinQin Beitrag anzeigen
    Dieser Timer sollte bei 15MHz Takt alle 17µs die ISR aufrufen, stimmt das?
    Würd ich rein nach Datenblatt auch so sehen. Allerdings kenne ich mich mit C und den Nibobee Funktionen nicht aus. Nicht, daß da irgendeine Funktion den Timer2 auch noch nutzt.

    Kommt auf eine Interruptfrequenz von ca. 58,5kHz und damit ist der µC schon gut beschäftigt und man könnte mal überprüfen, ob das in Zusammenarbeit mit übrigem Programm und Interrupts nicht zuviel ist?

    TCCR2 = 0b001; find ich nicht so gut. Binärzahl entsprechend der Registerbreite angeben, also 0b00000001 oder gleich übersichtlich mit TCCR2 |= (1<<CS20); (wenn andere Bits nicht beeinflußt werden sollen)

    PS: 15MHz ist eine unübliche Taktfrequenz?

    Gruß
    Searcher
    Hoffentlich liegt das Ziel auch am Weg
    ..................................................................Der Weg zu einigen meiner Konstruktionen

  7. #7
    Erfahrener Benutzer Robotik Visionär
    Registriert seit
    26.11.2005
    Ort
    bei Uelzen (Niedersachsen)
    Beiträge
    7.942
    Da die ISR recht kurz ist, sollte es auch mit einer so hohen Frequenz noch funktionieren. Einfach nur in der ISR Zählen ist aber ggf. auch unnötig - das kann der Timer auch in Hardware. Also einfach den Vorteiler um den Faktor 256 höher setzen und dann das Timer register auslesen statt der Variabele Counter. Besser wäre es da aber den 16 Bit timer(1) zu nutzen - dann hätte man auch da 16 Bit Auflösung. Oft reicht das. Der Timer direkt hätte auch noch gleich den Vorteil, das da Hardware für den ungestörten Zugriff auch 16 Bit werte vorhanden ist. Bei der Softwarelösung müsste man die Zugriffe auf Counter im Hauptprogramm noch alle mit Cli() ... Sei() schützen, wenn es nicht zu seltenen Ausreißern kommen darf.

  8. #8
    Den 16-bit Timer kann ich leider nicht nutzen, da der schon verwendet wird. Ich habe es jetzt mit dem 8er Vorteiler realisiert. Die Auflösung reicht noch nicht ganz aus, aber vorerst haben mich eure Antworten ein ganzes Stück weiter gebracht. Ich kann die Distanz jetzt auf ein paar cm genau einstellen. Ich werde in den nächsten Tagen noch die Idee den Zählerwert direkt zu verwenden umsetzen, dann müsste das Ganze noch genauer werden. Der Counterwert wäre dann ja Counter + (überlauf*256)?!

    Vielen Dank,

    PinQin!

  9. #9
    Erfahrener Benutzer Robotik Visionär
    Registriert seit
    26.11.2005
    Ort
    bei Uelzen (Niedersachsen)
    Beiträge
    7.942
    Im Prinzip stimmt das mit Counter + (überlauf*256), aber man muss aufpassen ob ggf. noch ein Überlauf Interrupt ansteht, also der counter schon wieder klein ist, aber die ISR für den Überlauf noch nicht aufgerufen wurde.

Ähnliche Themen

  1. Atmega16 - Zwei Timer verwenden. - Nur einer funktioniert
    Von Kesandal im Forum C - Programmierung (GCC u.a.)
    Antworten: 8
    Letzter Beitrag: 24.06.2011, 13:52
  2. [ERLEDIGT] ATMEGA16 - Timer zerschossen?
    Von Kesandal im Forum C - Programmierung (GCC u.a.)
    Antworten: 6
    Letzter Beitrag: 19.06.2011, 19:50
  3. NIBOBee und Timer- für Anfänger
    Von Rabenauge im Forum Sonstige Roboter- und artverwandte Modelle
    Antworten: 24
    Letzter Beitrag: 26.03.2010, 11:07
  4. ATMega16 und Timer Verständnisproblem
    Von -tim- im Forum Assembler-Programmierung
    Antworten: 14
    Letzter Beitrag: 30.12.2006, 12:03
  5. 1 MHz Clock Signal mit ATMega16 Timer erzeugen ?
    Von LySsA im Forum Basic-Programmierung (Bascom-Compiler)
    Antworten: 6
    Letzter Beitrag: 30.05.2005, 19:22

Stichworte

Berechtigungen

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

LiFePO4 Speicher Test