- 3D-Druck Einstieg und Tipps         
Seite 1 von 2 12 LetzteLetzte
Ergebnis 1 bis 10 von 11

Thema: ATmega168A: Software PWM Periodendauer verändert sich, woran kann das liegen?

  1. #1
    Dracyria
    Gast

    Frage ATmega168A: Software PWM Periodendauer verändert sich, woran kann das liegen?

    Anzeige

    Praxistest und DIY Projekte
    Hi alle miteinander,

    ich bin ein absoluter Anfänger in der Mikrocontrollerprogrammierung.
    Für meine Bachelorarbeit habe ich ein Programm geschrieben, das analoge Spannungswerte per ADC-Wandlung einliest und abhängig von diesen ein PWM Signal ausgibt, mit dem LEDs gedimmt werden können.
    Mit angeschlossenen LEDs bekomme ich ein nettes Ergebnis, alles wie es sein soll.

    Nun habe ich zur Dokumentation ein Oszi angeschlossen und das PWM Signal in Abhängigkeit von der Eingangsspannung am ADC aufgezeichnet.
    Für beide Hardware PWM Methoden(habe Fast- und Phase-correct benutzt) bekomme ich einen wunderbaren linearen Verlauf von Tastgrad zu Eingangsspannung heraus.
    Beim Software PWM zeigt sich ein exponentieller Verlauf. Bei genauerem Nachsehen fiel mir auf, dass sich bei kleineren Eingangsspannungen am ADC Pin die Periodendauer des Software-PWM Signals verlängert.
    Was nun die Frage aufkommen lässt, woran kann das liegen?

    Ich kann einfach keine Erklärung finden und muss Montag meine Verteidigung der Bachelorarbeit abhalten. Dort wird mit Sicherheit jemandem auffallen, dass ich mich um die Begründung bisher ein wenig gedrückt habe und natürlich möchte ich da dann nicht Ideenlos stehen... >.<

    Kann mir evtl noch jemand erklären, wie ich die tolle Code-Box erstelle? Dann werde ich da meinen Quellcode reintexten damit ihr sehen könnt, was ich da fabriziert habe. Bis dahin...Ich habe für das Software PWM einen ähnlichen Code, wie hier auf RN-Wissen unter Pulsweitenmodulation-Software Pulsweitenmodulation beschrieben verwendet (For-Schleife zählt und If Bedingungen für High/Low)

    Ich wäre euch mega dankbar, wenn ihr mir bis Montag noch helfen könntet!

  2. #2
    Erfahrener Benutzer Roboter-Spezialist Avatar von schorsch_76
    Registriert seit
    25.03.2012
    Ort
    Kurz vor Neuschwanstein
    Alter
    48
    Beiträge
    456
    Code Box geht mit [code]
    und dann eben mit [/] auch code abschliessen.

  3. #3
    Dracyria
    Gast
    Nun dann hier einmal mein Hauptprogramm.

    [code]void main(void)
    {
    //Variablendefinition ohne Vorzeichen
    uint16_t result1;
    uint16_t result2;
    uint16_t result3;
    uint16_t result4;
    uint16_t result5;
    uint16_t result6;
    uint16_t j;

    DDRB=0xff; // alle B-Pins als Ausgänge definiert
    DDRC=0b11110000; // Bit 0 und 1 in Port C Eingänge da ADC[1:0]
    DDRD=0b11111000; //Alle D-Pins als Ausgänge definiert



    //Endlosschleife
    while(1)
    {
    PORTD=0b00000111;
    //alle ADC Eingänge der Reihe nach wandeln
    result1=readADC(1); //Poti3
    result2=readADC(0); //Poti2
    result3=readADC(7); //Poti1

    //Hardware PWM für J34 bis J38
    if(result3>10)
    {
    TCCR1A |=(1<<COM1A1)|(1<<WGM10)|(1<<WGM12); // 8-Bit Fast-PWM <-dito
    TCCR1B |=(1<<CS10)/*| (1<<CS11)*/; //kein Prescaling
    OCR1A = (result3/4);
    }
    if(result3<=10)
    {
    TCCR1A = (0<<COM1A1);
    }

    //Hardware PWM für J49 bis J53
    if (result1>10)
    {
    TCCR0A|=(1<<COM0A1)|(1<<WGM00)|(1<<WGM01); // 8-Bit Fast-PWM
    TCCR0B|=(1<<CS00);//Kein Prescaling
    OCR0A = (result1/4); // result2/4 da 8 Bit
    }
    if (result1<=10)
    {
    TCCR0A = (0<<COM0A1);
    }


    //Software PWM für J39 bis J48
    if (result2>10)
    {
    // 512 Stufen da Frequenz damit höher und kein Sprung in der Helligkeit zu sehen
    for (j=0; j<511; j++)
    {
    if (j<result2/2)
    {
    PORTB |= (1<<PINB0);
    PORTD |= (1<<PIND7);
    }
    if (j>=result2/2)
    {
    PORTD &= ~(PORTD);
    PORTB &= ~(PORTB);
    }
    }
    }
    if (result2<=10)
    {
    PORTD &= ~(PORTD);
    PORTB &= ~(PORTB);
    }
    }
    }[\code]

  4. #4
    Unregistriert
    Gast

    Unglücklich

    Ohh peinlich...nun steht der Code da ohne schicke Box...sorry! >.<
    Nunja ich hoffe ihr könnt darin trotzdem schon was sehen, das solch ein Verhalten eventuell auslösen könnte.

  5. #5
    Erfahrener Benutzer Robotik Visionär Avatar von oberallgeier
    Registriert seit
    01.09.2007
    Ort
    Oberallgäu
    Beiträge
    8.685
    Zitat Zitat von Dracyria Beitrag anzeigen
    .. ein Programm .. das analoge Spannungswerte per ADC-Wandlung einliest und abhängig von diesen ein PWM Signal ausgibt .. Bei genauerem Nachsehen fiel mir auf, dass sich bei kleineren Eingangsspannungen am ADC Pin die Periodendauer des Software-PWM Signals verlängert ..
    Kann es sein, dass Du bei Deiner Software PWM die Pulsdauer veränderst und die Pause gleich lang lässt? Dann ändert sich natürlich die Periode im gleichen Maß wie der Puls.
    Ciao sagt der JoeamBerg

  6. #6
    Dracyria
    Gast
    Zitat Zitat von oberallgeier Beitrag anzeigen
    ...bei Deiner Software PWM die Pulsdauer veränderst und die Pause gleich lang lässt?
    Hi danke schonmal für die schnelle Anregung aber ich glaube dass sich die Periodendauer eigentlich nicht verändern sollte, ich zähle ja in meiner For-Schleife immer wieder von 0 bis 511 und schalte den Pin dann für eine bestimmte Zeit auf High und für den Rest der Schleife auf Low.
    Müsste dann nicht exakt das herauskommen, was mir die Hardware PWM liefert, nur langsamer eben? Oder gibt es Effekte, die auftreten können, wo mein Zähler dann nicht jeden Takt +1 zählt, sondern auf dem Wert bleibt und sich so die Periodendauer ungewollt verlängert?

  7. #7
    Erfahrener Benutzer Robotik Visionär Avatar von oberallgeier
    Registriert seit
    01.09.2007
    Ort
    Oberallgäu
    Beiträge
    8.685
    .. ich zähle ja in meiner For-Schleife immer wieder von 0 bis 511 ... Oder gibt es Effekte, die auftreten können, wo mein Zähler dann nicht jeden Takt +1 zählt ..
    Leider zeigst Du nicht alle Initialisierung(en), nur Dein main-Modul. Was der ADC tut sieht man nicht, da auch die Funktion readADC ein GEheimnis bleibt.

    Wie wird der ADC ausgelesen? Vermutlich über ne ISR. Nun kann der Controller zwar auf einer separaten WErkbank analoge Daten wandeln - oder Timer incrementieren, aber ne ISR ist ein separater Maschinencode-Abschnitt - der seine Zeit braucht. Sobald aber ISR mit im Spiel sind, ist es mit der zeitlichen Konstanz von Schleifen vorbei - abgesehen von sonstigen Einflüssen wie z.B. unterschiedlichen Laufzeiten von if-Schleifen . . .
    Ciao sagt der JoeamBerg

  8. #8
    Dracyria
    Gast
    Hi, stimmt ich hätte ja auch mal den kompletten Code nehmen können.
    Ist alles der Reihe nach aufgebaut, ohne Interrupts.
    Hier noch einmal das, was vor meiner Hauptschleife steht:
    Code:
    #define F_CPU 8000000UL //Geschwindigkeit des MCs 10MHz da 3.3V Versorgungsspannung
    #include <util/delay.h> //Damit Verzögerungszeiten angegeben werden können
    #include <avr/io.h> //Für Ein- und Ausgänge
    #include <avr/pgmspace.h>
    #include <inttypes.h>
    #include <math.h>
    
    //////////////////////////////////////////////////////////////////////////
    
    //ADC Messung mit Dummyreadout
    uint16_t readADC(uint8_t channel) 
    {
    	//Variablendefinition ohne Vorzeichen
    	uint8_t i;
    	uint16_t result = 0;
    	
    	// Den ADC aktivieren, kein Prescaling
    	ADCSRA = (1<<ADEN);
    	
    	//Kanal des Multiplexers wählen, AVcc als Referenzspannung einstellen
    	ADMUX = channel | (1<<REFS0); 
    	
    	// Dummyreadout
    	ADCSRA |= (1<<ADSC);
    	while(ADCSRA & (1<<ADSC));
    	
    	//Spannung auslesen und Durchschnittswert ausrechnen.
    	for(i=0; i<3; i++) 
    	{
    		
    		//Einmalige Wandlung
    		ADCSRA |= (1<<ADSC); 
    		
    		//Auf Ergebnis warten
    		while(ADCSRA & (1<<ADSC)); 
    		
    		//Ergebnis in Variable "result" speichern
    		result += ADCW;
    	}
    	
    	// ADC wieder deaktivieren
    	ADCSRA &= ~(1<<ADEN);
    	
    	result /= 3;
    	
    	return result;
    }
    Ahh klasse habs nun gerafft wie das mit der Box geht...immerhin schonmal das ^^

  9. #9
    Erfahrener Benutzer Roboter-Spezialist Avatar von schorsch_76
    Registriert seit
    25.03.2012
    Ort
    Kurz vor Neuschwanstein
    Alter
    48
    Beiträge
    456
    Fällt dir da was auf?

    Code:
    #define F_CPU 8000000UL //Geschwindigkeit des MCs 10MHz da 3.3V Versorgungsspannung

  10. #10
    Erfahrener Benutzer Robotik Visionär Avatar von oberallgeier
    Registriert seit
    01.09.2007
    Ort
    Oberallgäu
    Beiträge
    8.685
    Gute Frage, schorsch! Hatte ich übersehen. Aber das ist ja ein fester Bezugswert. Wie sollten daraus variable Ergebnisse entstehen? Ausserdem ist heut sowieso der Termin des TO.
    Ciao sagt der JoeamBerg

Seite 1 von 2 12 LetzteLetzte

Ähnliche Themen

  1. Problem mit ATMega168A und PWM
    Von TechMo im Forum Assembler-Programmierung
    Antworten: 6
    Letzter Beitrag: 19.09.2012, 08:10
  2. Kann sich ein Programm verlangsamen?
    Von Duesentrieb im Forum Basic-Programmierung (Bascom-Compiler)
    Antworten: 6
    Letzter Beitrag: 04.11.2011, 17:22
  3. Wie berechne ich Frequenz/Periodendauer meines PWM?
    Von ricola im Forum C - Programmierung (GCC u.a.)
    Antworten: 1
    Letzter Beitrag: 12.07.2007, 16:03
  4. Antworten: 9
    Letzter Beitrag: 11.02.2006, 02:50
  5. Periodendauer beim Servo
    Von .Johannes. im Forum Motoren
    Antworten: 9
    Letzter Beitrag: 28.02.2005, 11:49

Benutzer, die dieses Thema gelesen haben: 0

Derzeit gibt es keine Benutzer zum Anzeigen.

Berechtigungen

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

12V Akku bauen