www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik ATmega48 - Timer0: PWM mit Poti zum LED dimmen in C


Autor: Squat *** (squat)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Langsam weiß ich nicht mehr weiter.

Ich möchte, wie in der Überschrift beschrieben eine bzw. zwei LED dimmen 
(später sollen die LEDs mit 2 Pumpen und Fet getauscht werden).

Dazu möchte ich ein Poti verwenden. Die Funktion des ADC sollte 
funktionieren, da ich mit einer Abfrage 4 LEDs leuchten lasse (je 
nachdem, welcher Wert ansteht).

Der Timer1 wird für einen andere Aufgabe benötigt und wird daher auch 
verwendet.
//ICC-AVR application builder : 13.04.2010 16:15:44
// Target : m48
// Crystal: 8.0000Mhz

#include <iom48v.h>
#include <macros.h>

unsigned char i = 0;
unsigned int result;

void port_init(void)
{
 PORTB = 0xF1;
 DDRB  = 0x0E;
 PORTC = 0x43; 
 DDRC  = 0xBC;
 PORTD = 0x00;
 DDRD  = 0xFF;
}

void timer0_init(void)
{
    OCR0A = 0x80;
  OCR0B = 0x80;
  TCCR0A |= (1 << WGM01) | (1 << WGM00);    // Fast PWM
  TCCR0A |= (1 << COM0A1);                  // Fast PWM, non-inverting mode
  TCCR0A &= ~(1 << COM0A0);
  TCCR0A |= (1 << CS02);                    // Prescaler: 1/256
  
//  TCCR0B |= (1 << WGM01) | (1 << WGM00);  // Fast PWM
//  TCCR0B |= (1 << COM0B1);                // Fast PWM, non-inverting mode
//  TCCR0B &= ~(1 << COM0B0); 
//  TCCR0B |= (1 << CS02);                  // Prescaler: 1/256

        
}

//TIMER1 initialize - prescale:64
// WGM: 0) Normal, TOP=0xFFFF
// desired value: 100mSec
// actual value: 100,000mSec (0,0%)
void timer1_init(void)
{
 TCCR1B = 0x00; //stop
 TCNT1H = 0xCF; //setup
 TCNT1L = 0x2C;
 OCR1AH = 0x30;
 OCR1AL = 0xD4;
 OCR1BH = 0x30;
 OCR1BL = 0xD4;
 ICR1H  = 0x30;
 ICR1L  = 0xD4;
 TCCR1A = 0x00;
 TCCR1B = 0x03; //start Timer
}

//ADC initialize
// Conversion time: 6uS
void adc_init(void)
{
 ADCSRA = 0x00; //disable adc
 ADMUX = 0x00;  //select adc input 0
 ACSR  = 0x80;
 ADCSRB = 0x00;
 ADCSRA = 0x01;
 
}

#pragma interrupt_handler timer1_ovf_isr:iv_TIM1_OVF
void timer1_ovf_isr(void)
{
 //TIMER1 has overflowed
 TCNT1H = 0xCF; //reload counter high value
 TCNT1L = 0x2C; //reload counter low value


 
//----------------------------------------------------------------------------//
       //         AD-Wandlung
//----------------------------------------------------------------------------//
       // Dummy-Readout
       ADCSRA = (1<<ADEN) | (1<<ADPS2) | (1<<ADPS1);  // ADC aktivieren, Frequenzvorteiler: setzen auf 64 (8 MHz / 64 = 125 kHz) und ADC aktivieren
       ADMUX = 0x00;                                  // Kanal waehlen (ADC0)
       ADMUX |= (1<<REFS0) | (1<<REFS1);              // interne Referenzspannung nutzen 
       ADCSRA |= (1<<ADSC);                           // eine ADC-Wandlung
       while(!(ADCSRA & (1<<ADIF)));                  // auf Abschluss der Konvertierung warten (ADIF-bit)
       result = ADC;                                  // ADC muss einmal gelesen werden,
                                                      // sonst wird Ergebnis der nächsten Wandlung
                                                      // nicht übernommen.
       
       //ADC-Messung mit arithmetischen Mittel aus 4 Messungen
       result = 0;
       for (i=0;i<4;i++)
            {
          ADCSRA |= (1<<ADSC);                        // Messung ausfuehren
        while ( ADCSRA & (1<<ADSC) );                 // Konvertierung abwarten
        result += ADC;                                // aufaddieren zur Mittelwertbildung (ADC auslesen der zwei Bits
        }
        ADCSRA &= ~(1<<ADEN);                         // ADC ausschalten
        
        result /= 16;                                 // Mittelwert aus 4 und 8Bit für PWM (1024 / 4 = 256)
        
        OCR0A = result;                               // OC0A (PD6) = Poti-wert
        OCR0B = result;                               // OC0B (PD5) = Poti-wert


//----------------------------------------------------------------------------//
       //         AD-Abfrage zur Prüfung auf Funktion - Komentare sind für ein anders Projekt
//----------------------------------------------------------------------------//
       if (result < 63)  //410 = 5,4V
               {
          PORTD &= ~0x15; // PD4, PD2 &PD0 low
          PORTD |= 0x08; // PD3 high => LED an
          }
       if ((result < 127) & (result >= 63)) //430 = 5,7V
             {
          PORTD &= ~0x0D; // PD3, PD2 & PD0 low
          PORTD |= 0x10; // PD4 high => LED an
          }
       if ((result < 191) & (result >= 127)) //915 = 10,8V, 975 = 11,5V bei 100K und 330R
             {
          PORTD &= ~0x1c; // PD4, PD3 & PD2 low
          PORTD |= 0x01; // PD0 high => LED an
          } 
       if  (result >= 191)
          {
          PORTD &= ~0x19; // PD4, PD3 & PD0 low
          PORTD |= 0x04; // PD2 high => LED an
          }
                   
}  
////////////////////////////////////////////////////////////////////////////////
// Hauptprogramm
////////////////////////////////////////////////////////////////////////////////
void main(void)
{
 //stop errant interrupts until set up
 CLI(); //disable all interrupts
 port_init();
 timer0_init();
 timer1_init();
 adc_init();
 

 MCUCR = 0x00;
 EICRA = 0x00; //extended ext ints
 EIMSK = 0x00;
 
 TIMSK0 = 0x01; //timer 0 interrupt sources
 TIMSK1 = 0x01; //timer 1 interrupt sources
 TIMSK2 = 0x00; //timer 2 interrupt sources
 
 PCMSK0 = 0x00; //pin change mask 0 
 PCMSK1 = 0x00; //pin change mask 1 
 PCMSK2 = 0x00; //pin change mask 2
 PCICR = 0x00; //pin change enable 
 PRR = 0x00; //power controller
 SEI(); //re-enable interrupts
 //all peripherals are now initialized
   
 while(1);
  // Endlosschleife, blinken läuft im 100ms Interrupt
 
  
}

Vielen Dank für euche Hilfe.

Autor: MWS (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
TIMSK0 = 0x01; //timer 0 interrupt sources
Timer0n Ovfl Int erlaubt ohne Interrupt Handler = Nirvana

Autor: Squat *** (squat)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Also verstanden habe ich deine Antwort, da ich bisher mir den Quelltext 
immer zusammengesucht habe und so langsam mir die Fakten anlese, weiß 
ich jedoch nicht wirklich, wie ich dem abhilfe schaffen kann.
TIMSK0 = 0x00; //timer 0 interrupt sources
Timer auf Null setzen oder
#pragma interrupt_handler timer0_ovf_isr:iv_TIM0_OVF
void timer0_ovf_isr(void)
{
 //TIMER0 has overflowed
}
diesen Teil einsetzen?

Hat jedoch beides nicht geholfen.

Autor: Frederik Krämer (n0ll4k)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Denke eher er meint das du den Timer interrupt einfügen solltest.

Was mir noch auffällt das ganze AD Wandler auslesen solltest du im 
Hauptprogramm machen und im Interrupt von Timer 1 dann nur den Wert 
nutzen, falls du das zyklisch mit diesem machen willst.

Autor: Squat *** (squat)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Aber wenn ich die AD-Wandlung im Hauptprogramm ablaufen lasse, dann wird 
diese doch nur einmal ausgeführt, oder wie kann ich diese Funktion in 
die While-Schleife einbauen?

Ich wollte sowie so gerne aus ein paar Abschnitte Teilprogramme 
erstellen, da ich die AD-Wandlung z.B. für 3 Ports benötige. Ich bin 
damit jedoch etwas überfragt. Gerne würde ich Quelltexte und nicht nur 
Ratschläge von euch bekommen, da es mir schwer fällt, z.B.
> das du den Timer interrupt einfügen solltest.
zu deuten.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Squat *** schrieb:
> Aber wenn ich die AD-Wandlung im Hauptprogramm ablaufen lasse, dann wird
> diese doch nur einmal ausgeführt, oder wie kann ich diese Funktion in
> die While-Schleife einbauen?

Das ist jetzt aber nicht dein Ernst, oder?

Ich empfehle das Zusammenstoppeln von geklautem Code zu unterlassen und 
erst mal mit einem guten Buch die ersten Gehversuche in richtigem 
Programmieren auf einem PC zu machen.

Autor: Frederik Krämer (n0ll4k)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Les dir mal das AVR-GCC Tutorial hier auf der Seite durch und arbeite 
das mal ab. Da hast du mehr von als blind den Quelltext 
zusammenzusuchen. Vor allem vereinfacht das die Fehlerfindung und 
Behebung um einiges.

Autor: Squat *** (squat)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich wollte an dieser Stelle von niemandem Tipps, wie ich grundsätzlich 
hier was lernen kann.

Vielleicht habe ich mich falsch ausgedrückt.

Entschuldigt Bitte.

Natürlich habe ich mich belesen. Neben den "AVR-GCC Tutorial" und den 
Grundlagen aus dem "AVR-Tutorial" habe ich noch "AVR - Hardware und 
C-Programmierung in der Praxis", sowie PROGRAMMIEREN IN C oder 
C-Programmierung unter Linux/UNIX/Windows durch gearbeitet. Daher habe 
ich neben dem Datenblatt auch das grundsätzliche Gerüst.

Ich weiß ja nicht wie Ihr lernt, aber ich lerne ganz viel durch 
ausprobieren. Und so bin ich auch soweit gekommen, habe den ADC ans 
laufen bekommen und kann diesen über 4 LEDs signalisieren, ein 
Rundumlicht aus 4 Lämpchen,  eine Jumper-Abfrage sowie das Ansteuern 
eines Servos.

Was mir jetzt noch fehlt sind ein paar C-Grundlagen, die nach und nach 
erarbeitet werden sowie weitere Hardwarefunktionen.

Und darum geht es hier. Benötige Hilfe bei der obengenannten 
Aufgabenstellung und wäre für jeden aufschlußreichen Hinweis dankbar.

Und danke an  MWS und  Frederik Krämer für die ersten Hilfestellungen.

Autor: MWS (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hier ist Dein Fehler:
TCCR0A |= (1 << CS02); 
Schau Dir das DB an, dann weist Du warum.

Wobei auch ich sagen muss, Dein Code ist schwer zu lesen, und dann fällt 
erfahrungsgemäß die Hilfe geringer aus, wenn sich da erst jemand 
umständlich durchpflügen muss.

Autor: Squat *** (squat)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Vielen Dank.

Und schon wieder konnte ich was lernen. War mir garnicht bewusst, dass 
die Parametisierung über zwei Register geht. Aber dank eurer Hilfe und 
dem Datenblatt habe ich es nun verstanden.

Mich würde noch interessieren, was zu schwer zu lesen ist. Ist das zu 
viel Quelltext oder schlecht kommentiert oder liegt es an dem 
Programmaufbau.

Eine Frage hätte ich jedoch noch. Die LED geht nicht ganz aus. Das wäre 
mit der Pumpe dann genauso. Woran liegt das?

Der vollständigkeitshalber hänge ich hier nochmal den funktionstüchtigen 
Quelltest an.
//ICC-AVR application builder : 13.04.2010 16:15:44
// Target : m48
// Crystal: 8.0000Mhz

#include <iom48v.h>
#include <macros.h>

unsigned char i = 0;
unsigned int result;

void port_init(void)
{
 PORTB = 0xF1;
 DDRB  = 0x0E;
 PORTC = 0x43; 
 DDRC  = 0xBC;
 PORTD = 0x00;
 DDRD  = 0xFF;
}

//TIMER0 initialize - prescale:256
// WGM: PWM Fast
// desired value: ...mSec
// actual value:  ...mSec ()
void timer0_init(void)
{
 //OCR0A = 0x20;
 //OCR0B = 0x40;
 TCCR0B = 0x00; //stop
 TCNT0 = 0x01; //set count
 TCCR0A = 0xA3; 
 TCCR0B = 0x04; //start timer
}

//Ist gleich zu setzen mit
//void timer0_init(void)
//{
//    OCR0A = 0x80;
//  OCR0B = 0x80;
//  TCCR0A |= (1 << WGM01) | (1 << WGM00);    // Fast PWM
//  TCCR0A |= (1 << COM0A1);                  // Fast PWM, non-inverting mode
//  TCCR0A &= ~(1 << COM0A0);
//  TCCR0B |= (1 << CS02);                    // Prescaler: 1/256



//TIMER1 initialize - prescale:64
// WGM: 0) Normal, TOP=0xFFFF
// desired value: 100mSec
// actual value: 100,000mSec (0,0%)
void timer1_init(void)
{
 TCCR1B = 0x00; //stop
 TCNT1H = 0xCF; //setup
 TCNT1L = 0x2C;
 OCR1AH = 0x30;
 OCR1AL = 0xD4;
 OCR1BH = 0x30;
 OCR1BL = 0xD4;
 ICR1H  = 0x30;
 ICR1L  = 0xD4;
 TCCR1A = 0x00;
 TCCR1B = 0x03; //start Timer
}

//ADC initialize
// Conversion time: 6uS
void adc_init(void)
{
 ADCSRA = 0x00; //disable adc
 ADMUX = 0x00;  //select adc input 0
 ACSR  = 0x80;
 ADCSRB = 0x00;
 ADCSRA = 0x01;
 
}

#pragma interrupt_handler timer1_ovf_isr:iv_TIM1_OVF
void timer1_ovf_isr(void)
{
 //TIMER1 has overflowed
 TCNT1H = 0xCF; //reload counter high value
 TCNT1L = 0x2C; //reload counter low value
 

//----------------------------------------------------------------------------//
       //         AD-Wandlung
//----------------------------------------------------------------------------//
       // Dummy-Readout
       ADCSRA = (1<<ADEN) | (1<<ADPS2) | (1<<ADPS1);  // ADC aktivieren, Frequenzvorteiler: setzen auf 64 (8 MHz / 64 = 125 kHz) und ADC aktivieren
       ADMUX = 0x00;                      // Kanal waehlen (ADC0)
       ADMUX |= (1<<REFS0) | (1<<REFS1);        // interne Referenzspannung nutzen 
       ADCSRA |= (1<<ADSC);               // eine ADC-Wandlung
       while(!(ADCSRA & (1<<ADIF)));          // auf Abschluss der Konvertierung warten (ADIF-bit)
       result = ADC;                    // ADC muss einmal gelesen werden,
                                        // sonst wird Ergebnis der nächsten Wandlung
                                        // nicht übernommen.
       
       //ADC-Messung mit arithmetischen Mittel aus 4 Messungen
       result = 0;
       for (i=0;i<4;i++)
            {
          ADCSRA |= (1<<ADSC);             // Messung ausfuehren
        while ( ADCSRA & (1<<ADSC) );        // Konvertierung abwarten
        result += ADC;                     // aufaddieren zur Mittelwertbildung (ADC auslesen der zwei Bits
        }
        ADCSRA &= ~(1<<ADEN);               // ADC ausschalten
        
        result /= 16; // 
        
        OCR0A = result;
        OCR0B = result;
        
        if (blink_state = 0)
        {}
        if (blink_state = 1)
        {}
        if (blink_state = 2)
        {}


       
       if (result < 63)  //410 = 5,4V
               {
          PORTD &= ~0x15; // PD4, PD2 &PD0 low
             PORTD |= 0x08; // PD3 high => LED an
          }
       if ((result < 127) & (result >= 63)) //430 = 5,7V
             {
          PORTD &= ~0x0D; // PD3, PD2 & PD0 low
             PORTD |= 0x10; // PD4 high => LED an
          }
           if ((result < 191) & (result >= 127)) //915 = 10,8V, 975 = 11,5V bei 100K und 330R
             {
          PORTD &= ~0x1c; // PD4, PD3 & PD2 low
             PORTD |= 0x01; // PD0 high => LED an
          } 
           if  (result >= 191)
          {
          PORTD &= ~0x19; // PD4, PD3 & PD0 low
                 PORTD |= 0x04; // PD2 high => LED an
          }

      
}

////////////////////////////////////////////////////////////////////////////////
// Hauptprogramm
////////////////////////////////////////////////////////////////////////////////
void main(void)
{
 //stop errant interrupts until set up
 CLI(); //disable all interrupts
 port_init();
 timer0_init();
 timer1_init();
 adc_init();
 

 MCUCR = 0x00;
 EICRA = 0x00; //extended ext ints
 EIMSK = 0x00;
 
 TIMSK0 = 0x00; //timer 0 interrupt sources
 TIMSK1 = 0x01; //timer 1 interrupt sources
 TIMSK2 = 0x00; //timer 2 interrupt sources
 
 PCMSK0 = 0x00; //pin change mask 0 
 PCMSK1 = 0x00; //pin change mask 1 
 PCMSK2 = 0x00; //pin change mask 2
 PCICR = 0x00; //pin change enable 
 PRR = 0x00; //power controller
 SEI(); //re-enable interrupts
 //all peripherals are now initialized
   
 while(1);
  // Endlosschleife, blinken läuft im 100ms Interrupt
 
  
}

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Squat *** schrieb:

> Mich würde noch interessieren, was zu schwer zu lesen ist.

Vieles.

zb
welche Bits werden hier gesetzt?
 TCCR0A = 0xA3; 
 TCCR0B = 0x04; //start timer
Was bedeuten sie? Warum werden sie gesetzt?

void timer1_ovf_isr(void)
{
 //TIMER1 has overflowed
 TCNT1H = 0xCF; //reload counter high value
 TCNT1L = 0x2C; //reload counter low value
Kann dein Compiler die beiden TCNT1 Register zu einem logischen 16 Bit 
Regsiter zusammenfassen? Im gcc geht zb das
  TCNT1 = 0xCF2C;
damit erhebt isch aber sofort die Frage: Huch 0xCF2C. Was'n das?
  TCNT1 = 53036;
Damit aber sofort die nächste Frage: Warum ausgerechnet dieser Wert, 
warum kein anderer? Wo kommt der Wert her? Wenn ich meine Taktfrequenz 
ändere, muss ich den anpassen? Wie muss ich den anpassen? Kann ich das 
nicht am besten so fomulieren, dass der Compiler mir den Wert 
ausrechnet, wenn ich ihm Taktfrequenz und gewünschte Zeit angebe?

Die Kommentare
void timer1_ovf_isr(void)
{
 //TIMER1 has overflowed
 TCNT1H = 0xCF; //reload counter high value
 TCNT1L = 0x2C; //reload counter low value
sind zwar ein netter Versuch, mehr aber auch nicht. Das da das High Byte 
vom Counter beschrieben wird, sehe ich auch im Code. Dazu brauch ich 
keinen Kommentar. Viel interessanter: Warum ausgerechnet mit diesem 
Wert?


Das hier
       for (i=0;i<4;i++)
            {
          ADCSRA |= (1<<ADSC);             // Messung ausfuehren
        while ( ADCSRA & (1<<ADSC) );        // Konvertierung abwarten
        result += ADC;                     // aufaddieren zur Mittelwertbildung (ADC auslesen der zwei Bits
        }
        ADCSRA &= ~(1<<ADEN);               // ADC ausschalten
        
        result /= 16; // 
ist nicht unmittelbar logisch. Du machst 4 Messungen, dividierst die 
Summe der Messungen aber durch 16. Programmfehler? (Ich weiss schon, das 
du auf einen Wertebereich 0..255 runterkommen willst. Aber dazu muss ich 
den Rest der Funktion lesen, bis mir das dämmert)

Was soll das sein?
        if (blink_state = 0)
        {}
        if (blink_state = 1)
        {}
        if (blink_state = 2)
        {}

        PORTD &= ~0x15; // PD4, PD2 &PD0 low
             PORTD |= 0x08; // PD3 high => LED an

Super. Das PD4, PD2, PD0 auf low geschaltet werden, seh ich auch im 
Code. Aber warum?

Deine Konstanten für 'Welche LED hängt wo' sind quer über den ganzen 
Programmtext verstreut.

Denkst du nicht, dass
        Led_off( VOLTAGE_LOW_LED | VOLTAGE_MEDIUM_LED | FAILURE_LED );
        Led_on( VOLATGE_GOOD_LED );
sehr viel einfacher zu lesen und zu verstehen wäre? Von der wesentlich 
einfacheren Adaptierbarkeit an einer Stelle bei Hardwareänderungen
#define LED_PORT            PORTD
#define LED_DDR             DDRD

#define VOLTAGE_LOW_LED     (1<<PD4)
#define VOLTAGE_MEDIUM_LED  (1<<PD2)
#define VOLTAGE_GOOD_LED    (1<<PD3)
#define FAILURE_LED         (1<<PD0)
mal ganz abgesehen.

Sieh dir deinen Code an, wie gepostet. Sind die Einrückungen konsistent?

etc. etc.

Autor: Djin Qiujote del manche (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>Ist das zu viel Quelltext oder schlecht kommentiert oder liegt es an dem
>Programmaufbau.
Genau. Später dann frag' nochmal. Da kommt noch mehr dazu.

>Ich wollte an dieser Stelle von niemandem Tipps, wie ich grundsätzlich
>hier was lernen kann.
Schon, aber wir sind sowas von kommunikativ hier... Du hast's nötig. Und 
wie willst Du das verhindern? Ätsch.

>Natürlich habe ich mich belesen. Neben den "AVR-GCC Tutorial" und den
>Grundlagen aus dem "AVR-Tutorial" habe ich noch "AVR - Hardware und
>C-Programmierung in der Praxis", sowie PROGRAMMIEREN IN C oder
>C-Programmierung unter Linux/UNIX/Windows durch gearbeitet.

---> 6. 3.

-----------------------------------------------


1. Manche Posts sollte man nicht beantworten.
2. Manche Antworten sollte man ignorieren.
3. Manche Texte sollte man zweimal lesen.
4. Manche Programme sollte man zweimal schreiben.
6. Ach! (Loriot)
7. Ich bin doch klüger, besser, länger, schöner als Du, egal was Du 
sagst.
8. Google

Autor: spess53 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi

>Was mir jetzt noch fehlt sind ein paar C-Grundlagen, die nach und nach
>erarbeitet werden sowie weitere Hardwarefunktionen.

Da fehlt auch noch etwas Verständnis für den Controller.

>void adc_init(void)
>{
> ADCSRA = 0x00; //disable adc
> ADMUX = 0x00;  //select adc input 0
> ACSR  = 0x80;
> ADCSRB = 0x00;
> ADCSRA = 0x01;
>}

Das ist keine Init. Bis auf zwei irrelevante Bit sind das die Zustände 
nach einem Reset. Hier solltest du die Einstellungen machen, die sich 
im Programm nicht mehr ändern. Also Referenzspannungsquelle, 
Prescaler... .
Dann kannst du die die ständige Neuinitialisierung und den Dummyread im 
Timerinterrupt sparen.

>Eine Frage hätte ich jedoch noch. Die LED geht nicht ganz aus. Das wäre
>mit der Pumpe dann genauso. Woran liegt das?

Am Non-Inverting-Mode. Wenn du wirklich auf Null herunter willst nimm 
den Inverting Mode

MfG Spess

Autor: Frank M. (ukw) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
spess53 schrieb:

> Am Non-Inverting-Mode. Wenn du wirklich auf Null herunter willst nimm
> den Inverting Mode

Oder man schaltet im Fall "Null" einfach die PWM ab.

Gruß,

Frank

Autor: spess53 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi

>Oder man schaltet im Fall "Null" einfach die PWM ab.

Inverting Mode ist aber einfacher. Kostet einen zusätzlichen 
Assemblerbefehl.

MfG Spess

Autor: Squat *** (squat)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wunderbar.

Vielen Dank an alle, die diesen Threat gefüllt haben.

Neben der Lösung konnte ich so noch weitere Denkanstöße erhalten.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.