-         
Seite 1 von 2 12 LetzteLetzte
Ergebnis 1 bis 10 von 11

Thema: 255 PWM´s hintereinander ==>> LÄUFT!!

  1. #1
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    12.06.2006
    Beiträge
    473

    255 PWM´s hintereinander ==>> LÄUFT!!

    Anzeige

    Hallo da,

    Ich habe hier eine Schaltung, mit einem Mega 8, an dem RGB LED´s über die PINs B1, B2 und B3 verteilt sind. Schalte ich PB0 HIGH, werden die anderen übersteuert und bleiben LOW.

    Ich habe in Assembler schon etwas programmiert, wo ich die beiden Standalone PWM A und B von Timer1 und den einen PWM von Timer2 alle in 8 BIT Auflösung laufen lasse. Vom Timer2 wird ein Overflowinterrupt ausgeführt. In der ISR zählt eine 8 Bit variable hoch. Diese wird mit einem Dimmwert verglichen. Ist sie mind. gleich, geht PB0 HIGH, sonst LOW.

    Im Endeffekt habe ich also 255x8Bit PWM hintereinander. Macht dann 16 Bit.

    Jetzt versuche ich das in C zu programmieren.
    -ADC einlesen geht (8Bit, weil left adjusted) (getestet)
    -die PWM´s laufen.(getestet)

    Was nicht geht ist die Schachtelung. Die Lampen blinken in einer konstanten Geschwindigkeit. Wie gesagt, hat das in ASM schon geklappt.

    Hat jemans eine Idee?
    Code:
    #include <avr/io.h>
    #include <avr/interrupt.h>
    
    int zyklus;
    int helligkeit;
    
    
    SIGNAL (SIG_OVERFLOW2){
    zyklus++;
    if (zyklus >= helligkeit) PORTB |= (1<<PB0);
    else PORTB &= (0<<PB0);
    }
    
    void init(){
    DDRB = 0b00001111;
    
    TIMSK = 0b01000000;
    
    TCNT1 = 254;
    OCR1A = 43; 
    OCR1B = 90; 
    ICR1 = 255;
    
    OCR2 = 139;
    TCCR1A |= (1<<COM1A1)|(1<<COM1A0)|(1<<COM1B1)|(1<<COM1B0)|(1<<WGM11);
    TCCR1B |= (1<<WGM13)|(1<<WGM12)|(1<<CS10);
    TCCR2 |= (1<<WGM20)|(1<<COM21)|(1<<COM20)|(1<<WGM21)|(1<<CS20);
    
    zyklus = 0;
    
    ADMUX = 0b00100000;
    ADCSRA = 0b11110101;
    
    sei();
    }
    
    
    int main(void)
    {
    int schleife;
    init();
    main2:
    
    for (schleife=0;schleife==250;schleife++){
    
    }
    
    helligkeit = ADCH;
    goto main2;
    return 0;
    }
    mfg,
    The Man
    Chuck Norris kann Windows Vista auf einem Atmel in Assembler implementieren!
    Chuck Norris coded mit 3 Tasten:"1","0" und "compile"

  2. #2
    Erfahrener Benutzer Robotik Visionär
    Registriert seit
    26.11.2005
    Ort
    bei Uelzen (Niedersachsen)
    Beiträge
    7.942
    Die Variablen in der ISR muß man als Volatile deklarieren, sonst werden die Werte am ende der ISR wahrscheinlich verworfen weil nie aus den Registern ins RAM kopiert.

    Die Warteschleifen werden auch nur ohne optimierung funktionieren. Mit optimierung werden die einfach weggelassen. Da gibt es in C extra delay routinen.
    Endlossschleifen lacht man in C nicht mit GOTO, sondern mit while(1){...}.

  3. #3
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    12.06.2006
    Beiträge
    473
    Danke für die schnelle Antwort!
    Gerade weil sie spät kam (23:29)^^

    Läuft jetzt alles. Hab mir bei der Gelegenheit auch gleich angewöhnt, für Zahlen <= 255 CHAR zu nehmen.

    Hier mal der Rumpf:
    Code:
    #include <avr/io.h>
    #include <avr/interrupt.h>
    
    volatile unsigned char zyklus;
    volatile unsigned char helligkeit; //stellt ein gemeinsames Vielfaches für die 
                                                   //jew. Anteile da
    
    
    SIGNAL (SIG_OVERFLOW2){
    zyklus++;
    if (zyklus >= helligkeit) PORTB |= (1<<PB0);
    else PORTB &= (0<<PB0);
    
    }
    
    void init(){
    DDRB = 0b00001111;
    
    TIMSK = 0b01000000;
    
    TCNT1 = 254;// vorladen von TCNT1, damit T1 und T2 nacher synchron laufen
    ICR1 = 255;
    //***********************
    // Anteile der Farben
    OCR1A = 255; 
    OCR1B = 255; 
    OCR2 = 255;
    //************************
    
    
    TCCR1A |= (1<<COM1A1)|(1<<COM1A0)|(1<<COM1B1)|(1<<COM1B0)|(1<<WGM11);
    TCCR1B |= (1<<WGM13)|(1<<WGM12)|(1<<CS10);
    TCCR2 |= (1<<WGM20)|(1<<COM21)|(1<<COM20)|(1<<WGM21)|(1<<CS20);
    
    
    sei();
    }
    
    
    int main(void)
    {
    int schleife;
    init();
    main2:
    
    for (schleife=0;schleife==250;schleife++){
    
    }
    
    goto main2;
    return 0;
    }

  4. #4
    Erfahrener Benutzer Roboter Experte Avatar von sternst
    Registriert seit
    07.07.2008
    Beiträge
    672
    Zitat Zitat von Besserwessi
    Die Variablen in der ISR muß man als Volatile deklarieren, sonst werden die Werte am ende der ISR wahrscheinlich verworfen weil nie aus den Registern ins RAM kopiert.
    Sorry, aber das ist Blödsinn.
    Das sind globale Variablen und werden daher selbstverständlich spätestens am Ende der Funktion ins RAM zurückgeschrieben.
    MfG
    Stefan

  5. #5
    Erfahrener Benutzer Roboter Experte Avatar von sternst
    Registriert seit
    07.07.2008
    Beiträge
    672
    for (schleife=0;schleife==250;schleife++){
    Diese Schleife wird genau 0-mal durchlaufen.
    Du meintest wohl eher "<=".
    MfG
    Stefan

  6. #6
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    12.06.2006
    Beiträge
    473
    ach ja stimmt. In C wird etwas gemacht solange eine Bedingung 1 ist und nicht bis eine Bedingung 1 ist...

  7. #7
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    08.07.2004
    Ort
    Südhessen
    Beiträge
    1.312
    Zitat Zitat von sternst
    Zitat Zitat von Besserwessi
    Die Variablen in der ISR muß man als Volatile deklarieren, sonst werden die Werte am ende der ISR wahrscheinlich verworfen weil nie aus den Registern ins RAM kopiert.
    Sorry, aber das ist Blödsinn.
    Das sind globale Variablen und werden daher selbstverständlich spätestens am Ende der Funktion ins RAM zurückgeschrieben.
    Er hats komisch beschrieben, aber der Grundgedanke ist korrekt.
    Wird eine Variable von zwei verschiedenen Stellen (ISR und Hauptprogramm) benutzt, so muss sie volatile sein, sonst wird sie beim Benutzen der Optimierung wegen nicht erneut aus dem RAM ausgelesen (da sie sich in dem aktuellen Ablaufstrang ja nicht geändert haben kann).

  8. #8
    Erfahrener Benutzer Roboter Experte Avatar von sternst
    Registriert seit
    07.07.2008
    Beiträge
    672
    Zitat Zitat von The Man
    ach ja stimmt. In C wird etwas gemacht solange eine Bedingung 1 ist und nicht bis eine Bedingung 1 ist...
    Auch nicht 100%ig richtig.
    Solange die Bedingung wahr ist, und "wahr" ist nicht gleich 1 sondern ungleich 0. 42 ist auch "wahr".
    MfG
    Stefan

  9. #9
    Erfahrener Benutzer Roboter Experte Avatar von sternst
    Registriert seit
    07.07.2008
    Beiträge
    672
    Zitat Zitat von thewulf00
    Er hats komisch beschrieben, aber der Grundgedanke ist korrekt.
    Der Grundgedanke, warum hier volatile zu verwenden ist, ist weder "komisch" beschrieben, noch korrekt, sondern einfach nur falsch.

    Wird eine Variable von zwei verschiedenen Stellen (ISR und Hauptprogramm) benutzt, so muss sie volatile sein,
    Auch das ist eigentlich eine falsche Verallgemeinerung. Es ist zwar sehr oft so, aber nicht immer. Im konkreten Fall ist das volatile bei zyklus z.B. überflüssig.

    sonst wird sie beim Benutzen der Optimierung wegen nicht erneut aus dem RAM ausgelesen
    Nur dass das Lesen im konkreten Fall gar nicht der Knackpunkt ist, sondern das Schreiben der Variable helligkeit ins RAM in der main-Schleife.
    MfG
    Stefan

  10. #10
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    08.07.2004
    Ort
    Südhessen
    Beiträge
    1.312
    Zitat Zitat von sternst
    Zitat Zitat von thewulf00
    Er hats komisch beschrieben, aber der Grundgedanke ist korrekt.
    Der Grundgedanke, warum hier volatile zu verwenden ist, ist weder "komisch" beschrieben, noch korrekt, sondern einfach nur falsch.
    Es ist komisch beschrieben. Aus digitaler Sicht (es gibt nur richtig und falsch) ist Deine Antwort korrekt. Aber es gibt auch Grauzonen. Man muss einfach hinter die Worte blicken, und da ist der Gedankengang schon in Ordnung gewesen.
    (z.B. Frauen sprechen gern anders, als sie es meinen )


    Zitat Zitat von sternst
    Wird eine Variable von zwei verschiedenen Stellen (ISR und Hauptprogramm) benutzt, so muss sie volatile sein,
    Auch das ist eigentlich eine falsche Verallgemeinerung. Es ist zwar sehr oft so, aber nicht immer. Im konkreten Fall ist das volatile bei zyklus z.B. überflüssig.
    Du hast völlig recht. Aber in den meisten Fällen verursacht - vor allem bei Anfängern - ein fehlendes volatile das Problem. Besserwessi wollte sicher nur helfen. Und nur auf den Sonderfällen rumzureiten, damit eine Aussage nicht als allgemeingültig stehen gelassen werden kann, ist gemein.


    Zitat Zitat von sternst
    sonst wird sie beim Benutzen der Optimierung wegen nicht erneut aus dem RAM ausgelesen
    Nur dass das Lesen im konkreten Fall gar nicht der Knackpunkt ist, sondern das Schreiben der Variable helligkeit ins RAM in der main-Schleife.
    Da hast Du natürlich recht, mein Fehler.

    Nichtsdestotrotz kann ich mich mit der Aussage, dass es "einfach nur falsch" sei, nicht anfreunden. Die Ausdrucksweise ist sicher nicht wissenschaftlich korrekt, aber sie passt hier sehr wohl.

Seite 1 von 2 12 LetzteLetzte

Berechtigungen

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