-         

Ergebnis 1 bis 4 von 4

Thema: Atmel Tiny 13V als Controller für einen Dieselmotor

  1. #1
    Neuer Benutzer Öfters hier
    Registriert seit
    08.09.2009
    Beiträge
    12

    Atmel Tiny 13V als Controller für einen Dieselmotor

    Anzeige

    Moin Moin!
    Bei folgendem Projekt könnte ich eure Hilfe gut gebrauchen: Ich versuche mit Hilfe eines Atmel Tiny13V einen Drehzahlcontroller für einen kleinen Dieselmotor zu bauen. Dazu muss der Atmel einen Servo ansteuern können, der später fürs Gasgeben zuständig ist.
    Bisher sieht das Programm so aus:
    Code:
    #include <avr/io.h>#include <avr/interrupt.h>
    
    
    //#define f_cpu 9,6 MHz // ???
    
    
    uint8_t y;
    volatile uint16_t count, time;
    
    
    void delay(uint16_t d) // Warteschleife 1/50 Sekunde
    {
    	time=d+1; while(time);
    }
    unsigned char z;
    ISR(TIM0_COMPA_vect) // Servoansteuerung
    {
    	if (count>y) PORTB &= ~(1<<PB4); else PORTB |= (1<<PB4);
    	if (count < 500) count++; else { count=0; if(time) time--; }
    }
    
    
    int main(void)
    {
    	PORTB |= (1<<PB1);
    	DDRB = (1<<PB4)|(1<<PB1); // Servoausgang
    
    
    	TCCR0A = (0 << WGM00) | (1 << WGM01); // CTC-Mode
    	TCCR0A |= (0 << COM0A0) | (0 << COM0A1); // ohne OCR-Pin
    	TCCR0B = (0 << CS02) | (0 << CS01) | (1 << CS00); // prescaler /8
    	TIMSK0 = (1 << OCIE0A); // Interrupt ein
    	OCR0A = 12; // 100kHz 9600000/(8*12)
    	sei();
    //	y=150; //wieso kann ich y nur hier setzen?
    
    
    while(1){
    y=150; // und nicht hier?
    	
    }
    return(0);
    }
    Anmerkung: Das Programm entstammt komplett radbruchs Feder (meinen Danke noch einmal an dieser Stelle).
    Der Servo hängt am PB4, mit der Variable y setzt man die Servoposition.
    Meine Frage ist nun: Warum kann ich y nur ausserhalb der while(1)-Schleife setzten?
    Setze ich y in while(1) fährt der Servo einfach nach ganz links. (Je höher die y-Werte desto weiter "rechts" steht der Servo.)
    Da ich mich erst nen knappen Monat mit µC beschäftige bin ich mit meinem Latein am Ende...
    Vielen Dank schonmal für eure Hilfe!

  2. #2
    Moderator Robotik Visionär Avatar von radbruch
    Registriert seit
    27.12.2006
    Ort
    Stuttgart
    Alter
    54
    Beiträge
    5.781
    Blog-Einträge
    8
    Hallo

    Ich habs mal etwas geputzt:
    Code:
    #include <avr/io.h>
    #include <avr/interrupt.h>
    
    volatile uint8_t y, p;
    
    ISR(TIM0_COMPA_vect) // Servoansteuerung
    {
    	static uint16_t count=0;
    	if (count>y) PORTB &= ~(1<<PB4); else PORTB |= (1<<PB4);
    	if (count < 2000) count++; else { count=0; if(p) p--; }
    }
    
    int main(void)
    {
    	DDRB = (1<<PB4)|(1<<PB1); // Servoausgang
    	PORTB |= (1<<PB1); // und Spannungsversorgung der Schaltung?
    
    	TCCR0A = (0 << WGM00) | (1 << WGM01); // CTC-Mode
    	TCCR0A |= (0 << COM0A0) | (0 << COM0A1); // ohne OCR-Pin
    	TCCR0B = (0 << CS02) | (0 << CS01) | (1 << CS00); // kein prescaler!
    	TIMSK0 = (1 << OCIE0A); // Interrupt ein
    	OCR0A = 12; // 100kHz 1200000/12
    	sei();
    
    	y=150; 
    
    	while(1)
    	{
    		p=50; while(p); // eine Sekunde warten
    		if(y == 150) y=100; else y=150; // neue Position festlegen
    	}
    	return(0);
    }
    Das ist jetzt für 1,2MHz. Das sollte nicht funktionieren, weil die ISR nur 12 Takte Zeit hat und deshalb vermutlich überläuft (=während der Ausführung der ISR tritt schon der nächste Interrupt auf). Sollte dein Tiny wirklich mit 9,6MHz takten, sollte das OCR0A so geladen werden:

    OCR0A = 96; // 100kHz 9600000/96

    Die ISR hätte dann 96 Takte Zeit zur Ausführung.

    Gruß

    mic

    [Edit]
    Code:
    	TCCR0B = (0 << CS02) | (0 << CS01) | (1 << CS00); // kein prescaler!
    	OCR0A = 12; // 100kHz 9600000/(8*12)
    	sei();
    //	y=150; //wieso kann ich y nur hier setzen?
    
    
    while(1){
    y=150; // und nicht hier?
    Vermutlich passiert genau hier der Überlauf. Nach while(1) sind die zwölf Takte vorbei (egal welcher Kontrollertakt verwendet wird) und der Kontroller stürzt ins Interruptüberlaufsniwana. Es wird zwar noch irgendwas als Impuls ausgegeben, aber das ist völlig unkontrolliert. Bei der Zuordnung direkt nach sei() erfolgt der Absturz wenigstens mit richtig geladenem y. Ist nur so ein Nachtgedanke.
    Geändert von radbruch (02.09.2011 um 01:20 Uhr)

    Atmel’s products are not intended, authorized, or warranted for use
    as components in applications intended to support or sustain life!

  3. #3
    Neuer Benutzer Öfters hier
    Registriert seit
    08.09.2009
    Beiträge
    12
    So!
    Ein kleines Update meines Projektes:
    Ich hab mir mit hilfe des Asuro einen "Simulator" gebaut mit hilfe ich die Programmierung testen will.
    Er simuliert ein Signal, wie es von einem Drehzahlsensor stammen könnte, mit variabler Drehzahl.
    Nun scheitere ich aber schon seit einer Weile an folgendem:
    Um eine Drehzahl errechnen zu können muss ich ja die Impulse pro Zeiteinheit zählen. Ich schaffs aber nicht eine Schleife zu programmieren, die z.B. 1/4 Sekunde gewisse Befehle ausführt (Impulse an einem Beinchen zählen).
    Ich hoffe ihr versteht was mein Problem ist...

  4. #4
    Neuer Benutzer Öfters hier
    Registriert seit
    08.09.2009
    Beiträge
    12
    Code:
    #include <avr/io.h>#include <avr/interrupt.h>
    
    
    volatile uint8_t y, p;
    unsigned char b, c, a;
    
    
    ISR(TIM0_COMPA_vect) // Servoansteuerung
    {
    	static uint16_t count=0;
    	if (count>y) PORTB &= ~(1<<PB4); else PORTB |= (1<<PB4);   // solange count größer ist als y pb4=1 
    	if (count < 2000) count++; else { count=0; if(p) p--; } //p wird mit 960.0000 /96 = 100khz /2000 =50hz angesteuert (20ms) p wird runtergezählt (p=50 = eine sekunde)
    }
    
    
    int main(void)
    {
    	DDRB = (1<<PB4)|(1<<PB1); // Servoausgang
    
    
    	TCCR0A = (0 << WGM00) | (1 << WGM01); // CTC-Mode
    	TCCR0A |= (0 << COM0A0) | (0 << COM0A1); // ohne OCR-Pin
    	TCCR0B = (0 << CS02) | (0 << CS01) | (1 << CS00); // kein prescaler!
    	TIMSK0 = (1 << OCIE0A); // Interrupt ein
    	OCR0A = 96; // 100kHz 1200000/12
    	sei();
    
    
    	y=150; 
    
    
    	while(1)
    	{
    	p=13;
    	c=0;
    	 	while(p > 0) {
    		a = PINB;
    		a = a & 0x08;
    		if (a !=0){
    			c++;}
    		else{
    			c=c+0;}
           				}
    	   	if (c > 13) {  // 50 impulse pro sekunde angestrebt
    	   		y--;}
    		else if (c==13) {
    			y=y+0;}
    		else {
    			y++;}
    		
    	}
    	return(0);
    }
    Hier einmal mein Versuch... egal wieviel Hertz ich an den Eingang anlege, der Servo läuft immer gaaanz langsam runter in seine Nullstellung... verändern der C-Variable ändert auch nichts...

Ähnliche Themen

  1. Asuro Steuerung für Dieselmotor
    Von erik1563 im Forum Asuro
    Antworten: 11
    Letzter Beitrag: 01.09.2011, 13:28
  2. Atmel Tiny- Taster Problem
    Von Sepperli im Forum C - Programmierung (GCC u.a.)
    Antworten: 1
    Letzter Beitrag: 07.11.2010, 23:33
  3. Atmel Controller 162
    Von CodeX im Forum Elektronik
    Antworten: 1
    Letzter Beitrag: 02.08.2006, 18:12
  4. USB Controller von Atmel
    Von PasstScho im Forum AVR Hardwarethemen
    Antworten: 6
    Letzter Beitrag: 11.09.2005, 14:35
  5. Woher bekomme ich einen Atmel Controller???
    Von Superhirn im Forum Basic-Programmierung (Bascom-Compiler)
    Antworten: 11
    Letzter Beitrag: 26.03.2005, 20:39

Berechtigungen

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