-         
Ergebnis 1 bis 3 von 3

Thema: ATtiny13 und ~85: ADC-Ergebnis ist nicht auswertbar für PWM

  1. #1
    Erfahrener Benutzer Robotik Visionär Avatar von oberallgeier
    Registriert seit
    01.09.2007
    Ort
    Oberallgäu
    Beiträge
    8.062

    ATtiny13 und ~85: ADC-Ergebnis ist nicht auswertbar für PWM

    Anzeige

    Hallo alle,
    ich bitte wieder mal um Hilfe.

    Projektziel: Bei meinem Labornetzteil (KORAD KA3005D) soll der Lüfter nur bei Bedarf geschaltet werden, aktuell läuft er ständig. Den Bedarf definiere ich dann, wenn die Temperatur am Kühlkörper der Leistungsstufe 40°C erreicht oder überschreitet. Dann soll bis etwa 70°C die Drehzahl des Lüfters bis zu dessen Maximum ansteigen.
    Der Lüfter - zweidrahtig - wird aktuell mit ca. 13V versorgt. Die Drehzahl ist anfangs eher "mittel" und steigt mit steigendem Strombedarf auf "hoch". Die Geräuschkulisse stört mich aber auch im Standby-Betrieb.

    Lösung: Ein NTC (ca. 47k bei RT, Anschluss an Vcc) bildet mit einem Festwiderstand (47k gegen GND) einen Spannungsteiler, dessen Mittelanschluss an den ADC geht. Es sind mit steigender Temperatur steigende ADC-Werte im Bereich von ca. 500 bis 800 feststellbar (Testaufbau mit mega328 - ermittelt durch UART-Ausgabe). Oberhalb eines bestimmten Grenzwertes soll der Motor drehen und mit steigender Temperatur auch die Drehzahl steigern. Arbeitsbereich und Funktion wurden ohne Controller ausgemessen. Die PWM soll also die Drehzahl temperaturabhängig mit variabler Einschaltdauer steuern. Motortreiber ist ein A4950, VIN ca. 13V, über einen Spannungswandler werden die 5,0V für Controller und Spannungswandler erzeugt (Controllerversorgung und Spannungsteiler abgepuffert mit ELKO 10uF und Kerko 100nF).

    Arbeitsweise: Der zugrundeliegende ADC-Werte-Bereich wurde mit dem mega328 ermittelt. Mit diesem Bereich soll der tiny13 die entsprechende Motordrehzahl über den A4950 steuern. Ein Testlauf ohne ADC-Betrieb bestätigt die Funktion des Testaufbaues auf dem Steckbrett. Dieser Testlauf wird in einer for-Schleife mit 254 Schritten realisiert. Funktion gut, Ergebnis ist auch der ungefähr bestimmbare Einsatz der Motorfunktion. Siehe dazu Codeausschnitt "main".

    Problem: Der vom ADC generierte Messwert - free running - kann nicht für die Steuerung der PWM übernommen werden, ein entsprechender Befehl wird nicht ausgeführt. Weder wird die Ansteuerung des Timers in der ISR des ADC berücksichtigt - siehe Codebeispiel "ADC" - noch eine Ansteuerung aus dem "main". Auch eine Ansteuerung der Hardware-PWM aus der Timer-ISR zeigt keine Motorfunktion - siehe Codebeispiel "Timer". Zur Kontrolle der jeweiligen Varianten wird in den entsprechenden Routinen das Anspringen der ISR jeweils über ein Toggeln einer Kontroll-LED bestätigt. Um Probleme der beschränkten Flash- und RAM-Kapazität des tiny13 auszuschalten wurde ein fast identischer (ISR-Namen) Code auf dem tiny85 getestet. In beiden Fällen kein Erfolg.

    Anmerkung:
    a) Die entsprechenden Variablen sollten korrekt angepasst sein (uint8_t oder uint16_t) - es geht ja auch im Betrieb ohne ADC.
    b) Die verschiedenen Varianten laufen jeweils alternativ - nicht gleichzeitig *gg*

    Bitte kann mir jemand Tipps geben ob mein Code falsch ist - und wo - oder ob ne Stelle in der Dokumentation der Controller diese Funktion - ADC-Wert steuert Hardware-PWM - verneint? Oder was läuft da schief. Derzeit butter ich seit Tagen in Magermilch :-/

    Programmcode-Ausschnitt "main"
    Code:
    // ============================================================================= =
      sei();                // ###  Globalen Interrupt freigeben <<<<<#####
    // - - - - - - - - - - - - - - - -
    //##>> Init ADC ==>>>>   wird erst nach der Motor-Probefahrt initialisiert
    // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    //      T E S T   Motor mal schneller (PWM 0=>254), dann langsamer
      PORTB     |=  (1 <<PB4);      // LED ein
      for ( uint8_t n=0; n<=254; n++ )
      { OCR0A  =  n; wms ( 10); }
      PORTB     &= ~(1 <<PB4);      // LED aus
      wms ( 1000);
      PORTB     |=  (1 <<PB4);      // LED ein
      for ( uint8_t n=254; n>0; n-- )
      { OCR0A  =  n; wms ( 10); }
      PORTB     &= ~(1 <<PB4);      // LED aus
                                    //
    // ============================================================================= =
      cli ( );                      // Globalen Interrupt sperren, ADC initialisieren
    // - - - - - - - - - - - - - - - -
      ADC3_10free ( );              // Init ADC Kanal 3, 10 Bit, free running      adc
                                    //    zur Messung der Temperatur mittels NTC
      adccnt        =       0;      // Nulle Anzahl der Messungen des ADC
    // ============================================================================= =
      sei();                // ###  Globalen Interrupt freigeben <<<<<#####
                                    //
    // ============================================================================= =
    //      Es folgt der eigentliche Betrieb des Motors durch Auswertung des NTC
      while ( 1 )                   //
      {                             //
        cli ( );                    //
    //  pwm         =  ADCH;        //
        pwm         =  ADCMW8;      // ADCMW8 :  unsigned integer 8
        sei ( );                    //
        OCR0A       =   pwm - 200;        //
        wms (    1);
    // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
      return 0;                     //
     }                              //        
    // =====  Ende des Testabschnittes, er kann aus mehreren Abschnitten bestehen ====
    Programmcode-Ausschnitt "Timer"
    Code:
    // ============================================================================= =
    // ===  Initialisierung Timer0 ATtiny13/@9,6 MHz für ISR TIM0_COMPA
    // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
      void TC0_init (void)          // Init Tmr/Cntr 0, 8-Bit;
     {                            //
    // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
      TCCR0A    |=  (1<<COM0A1);    // Clear OC0A/OC0B = PB0/~1                  71/72
                                    // ... on Compare Match, set on TOP
      TCCR0A    |=  (1<<WGM01)|(1<<WGM00);  // Fast PWM, Mode3 TOP=0xFF=dez255      79
                    //  das ergibt aus 9,6 MHz mit Prescaler clk/1  37,5 kHz, siehe u.
      TCCR0B    |=  (1<<CS00);      // clk/1 <=> No prescaling                      74
                                    //   => bei 9,6 MHz mit Prescaler clk/1  37,5 kHz
                                    //      Gemessen mit DISCO2: 35,7 .. 36,1 kHz
      TIMSK0    |=  (1<<TOIE0);     // Tmr/Cntr0 Overflow interrupt enabled
      OCR0A      =          0;      // HW-PWM default setzen
     }              // Ende void TC0_init (void)
    // ============================================================================= =
    
    
    // ============================================================================= =
    // ===  Nicht unterbrechbare ISR für Timer0, COMPA   =========================== =
    //      Vector No. 11, Program Address 0x000A, Source TIMER0_COMPA,
    // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
      ISR(TIM0_OVF_vect)          // Vector No. 11, PrgAddr 0x000A
     {                      //
      Izeit_A --;           //
      if ( Izeit_A ) return;    // Zeit noch nicht abgelaufen => gleich return
      Izeit_A  =  Izthrznt;     //
      return;               //
     }      // Ende ISR(TIMER0_COMPA_vect), Vector No. 11, PrgAddr 0x000A
    // ============================================================================= =
    Programmcode-Ausschnitt "ADC"
    Code:
    // ============================================================================= =
    // ===  Initialisierung fuer ADC#3/tiny13 @ 9,6Mhz, Interrupt free running
    //      ATtiny13_doc8126F_komplett_05-12_-neu-..-neu.pdf  ==>    8126F-AVR-05/12
    // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
      void ADC3_10free (void)       // Init m328/ADC4, 10 Bit, free runn. Interrupt
     {                            //
    // - - - - - - - - - - - - - - -
      ADMUX        |=  (1<<REFS0);  // Referenzspannung ist AVcc                    92
      ADMUX        |=  (1<<MUX1)|(1<<MUX0);         // => Messungen auf Kanal 3     93
      ADMUX        |=  (1<<ADLAR);  // ADC Left Adjust Result                       92
      ADCSRA       |=  (1<<ADATE);                  // Auto Triggering Enable       93
      ADCSRA       |=  (1<<ADPS2)|(1<<ADPS1)|(1<<ADPS0);    // ==>  Prescal clock/128
                    // 9,6 MHz: clk/128 => 75 kHz bzw 13cykl entsprechend 183 µs
      ADCSRA       |=  (1<<ADEN);   // ADC Enable                                   x
      ADCSRA       |=  (1<<ADSC);   // starte gleich die erste Wandlung             x
      ADCSRA       |=  (1<<ADIE);   // ADC Interrupt Enable                         x
     }              // Ende von void ADC_in_10free(void)
    // ============================================================================= =
    
    
    // ============================================================================= =
    // ===  ISR für ADC3, übernimmt ADC-Wert aktuell free running
    //      bei 9,6 MHz: clk/128 => 75 kHz bzw 13cykl entsprechend 183 us (siehe oben)
    // ============================================================================= =
    // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
      ISR(ADC_vect)                 //
     {                              //
    // - - - - - - - - - - - - - - - -
      PORTB        ^=  (1 <<PB4);   // LED toggeln für Test
      ADCMW8        = ADCH;         // ADCMW8 :  unsigned integer 8
     }      // Ende ISR(ADC_vect)
    // ============================================================================= =
    Danke im Voraus
    Ciao sagt der JoeamBerg

  2. #2
    Erfahrener Benutzer Roboter Genie Avatar von Searcher
    Registriert seit
    07.06.2009
    Ort
    NRW
    Beiträge
    1.552
    Blog-Einträge
    127
    Hallo oberallgeier,

    Code:
      ADMUX        |=  (1<<REFS0);  // Referenzspannung ist AVcc
    der Kommentar paßt beim ATtiny13 nicht. Mit REFS0 wird die interne 1,1V Referenz als Vref hergenommen.

    Könnte das das Problem sein?

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

  3. #3
    Erfahrener Benutzer Robotik Visionär Avatar von oberallgeier
    Registriert seit
    01.09.2007
    Ort
    Oberallgäu
    Beiträge
    8.062
    Zitat Zitat von Searcher Beitrag anzeigen
    .. der Kommentar paßt beim ATtiny13 nicht .. Könnte das das Problem sein? ..
    Vielen vielen Dank! Natürlich isses so - zwar würde es beim Tiny85 passen, dann aber nur mit Modifikationen. Was für ein übles Eigentor. RTFM - gilt wieder - wie immer.

    Danke! Nun läufts richtig gut!

    Programmcode-Ausschnitt "Timer"
    Code:
      ADMUX        &= ~(1<<REFS0);  // Referenzspannung ist Vcc
    Geändert von oberallgeier (04.10.2019 um 10:27 Uhr)
    Ciao sagt der JoeamBerg

Ähnliche Themen

  1. [ERLEDIGT] Tischmultimeter am PC nicht auswertbar - Uni-T UT804
    Von Cysign im Forum PC-, Pocket PC, Tablet PC, Smartphone oder Notebook
    Antworten: 7
    Letzter Beitrag: 17.09.2015, 22:03
  2. 2-Timerprobleme kann ich nicht lösen(Attiny13 o.ä)
    Von oderlachs im Forum Microcontroller allgemeine Fragen/Andere Microcontroller
    Antworten: 9
    Letzter Beitrag: 17.02.2014, 16:05
  3. Antworten: 0
    Letzter Beitrag: 05.07.2011, 18:14
  4. ADC sendet Ergebnis nicht
    Von zappel76 im Forum Basic-Programmierung (Bascom-Compiler)
    Antworten: 9
    Letzter Beitrag: 11.09.2010, 13:53
  5. Eigener C Code auf ATTiny13 funktioniert nicht
    Von chaotic im Forum C - Programmierung (GCC u.a.)
    Antworten: 2
    Letzter Beitrag: 26.04.2008, 11:29

Berechtigungen

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