C TINY2313 - Soft PWM - TIMER0_OVF

Janiiix3

Aktives Mitglied
28. Sep. 2013
1.333
10
38
Hannover
Sprachen
  1. ANSI C
  2. C#
Hallo Leute ;)

Ich würde gerne in einer Interrupt Routine (TIMER0_OVF) eine Software PWM generieren...
Das klappt nicht wie gewünscht... Bei "PWM0 = 2;" sind die Lampen ganz schwach an...
Gehe ich jetzt auf "PWM0= 10;" sind sie gleich auf volle Power... Was mache ich falsch ?

Code:
#define F_CPU 8000000						// Interner RC Oszillator. Frequenz = 8000000 Hz ( 4 ms. Einschwingzeit )

#define ABSCHALTZEIT	24000   				// ABSCHALTZEIT der HighPowerLED´s ( Der TIMER0 läuft ca. jede 10ms in den Interrupt ) 24000
#define HELLIGKEIT		3000				// Wert für den Überlauf ( OCR1A )
#define AB_DIMM_ZEIT	120					// Geschwindigkeit für das ab dimmen der LED´s

#define key_SOS			PD3					// Taste SOS
#define key_ON			PD2					// Taste ON
#define key_UP			PD1					// Taste UP
#define key_DOWN		PD0					// Taste Down

#define TIMER_START     TCCR1B |=   ((1<<CS12) | (1<<CS11) | (1<<CS10));
#define TIMER_STOP      TCCR1B &= ~ ((1<<CS12) | (1<<CS11) | (1<<CS10));

#define XPE_1_AN		PORTB |= (1<<PB0)	// HighPowerLED 1 an
#define XPE_2_AN		PORTB |= (1<<PB1)	// HighPowerLED 2 an
#define XPE_3_AN		PORTB |= (1<<PB2)	// HighPowerLED 3 an
#define XPE_4_AN		PORTB |= (1<<PB3)	// HighPowerLED 4 an

#define alle_AN			PORTB |= (0b00001111)
#define alle_AUS		PORTB &= ~(0b00001111)

#define XPE_1_AUS		PORTB &= ~(1<<PB0)	// HighPowerLED 1 aus
#define XPE_2_AUS		PORTB &= ~(1<<PB1)	// HighPowerLED 2 aus
#define XPE_3_AUS		PORTB &= ~(1<<PB2)	// HighPowerLED 3 aus
#define XPE_4_AUS		PORTB &= ~(1<<PB3)	// HighPowerLED 4 aus

#define ALARM_AN		PORTB |=  (1<<PB4)	// Summer an
#define ALARM_AUS		PORTB &= ~(1<<PB4)	// Summer aus

#include <avr/io.h>							// Library für die I/O (Ports)
#include <avr/sleep.h>						// Library für den Schlaf Modus
#include <avr/interrupt.h>					// Library für die Interrupts
#include <stdint.h>							// Benötigt Library für Uint16_t Werte

volatile uint8_t PWM0 = 10;
    
uint8_t PWMStatus;

int main(void)
{


	TCCR0B = (1<<CS00);
	TIMSK  = (1<<TOIE0);
	sei();									// Interrupts global aktivieren
	
	

	while(1)
	{
		
		
	}// Ende While
	
}// Ende Main


ISR(TIMER0_OVF_vect) // Schaltet nach jedem Überlauf ( Overflow ) die HighPowerLED´s an
{
	static uint8_t counter = 0;



	counter++;

	if (counter >= 100)
	{
		counter = 0;
	
	if (PWM0 > 0)
	{
		alle_AN;
	}
		else
			
	{
		alle_AUS;
	}

	}// Ende Master if
	
		else
	{

	if (counter == PWM0)
	{
		alle_AUS;
	}
	
	}

} // Ende ISR (TIMER1_OVF_vect)
 
Hallo Janiiix,

es liegt an deinen if-Abfragen, das funktioniert so einfach nicht.

Wie bist du auf sowas gekommen? Deine LED-An-Aus Geschichte wird nur dann ausgeführt, wenn counter 100 erreicht und dann vergleichst du immer wenn counter = 0 ist :hmmmm:


Probiere mal folgendes


Code:
// PWM0 = 0..100

ISR(TIMER0_OVF_vect) 
{
    static uint8_t counter = 0;
    
    counter++;

    if (counter >= 100)
    {
        counter = 0;
        if (PWM0 > 0) LED_an
    }
    
    if (counter == PWM0) LED_aus
    
}
 
sorry,

das habe ich noch vergessen ...

Code:
volatile uint8_t PWM0 = 10;


das steht so in meinem Buch...
 
das steht so in meinem Buch...

Auch wenn das so im Buch steht. Es geht so nicht!

Es müsste dann schon so beginnen ...

Code:
counter++;

if (counter >= 100)
{
    counter = 0;
}

// ... hier die Vergleiche mittels if

Eine Klammer sitzt falsch. Selbst wenn das korrigiert ist, sind die if-Abfragen ziemlich "ungünstig".

Verwende testweise mal mein Beispiel.
 
so...?

ISR(TIMER0_OVF_vect) // Schaltet nach jedem Überlauf ( Overflow ) die HighPowerLED´s an
{
static uint8_t counter = 0;

counter++;

if (counter >= 100)
{
counter = 0;
}

if (PWM0 > 0)
{
alle_AN;
}
else

{
alle_AUS;
}


if (counter == PWM0)
{
alle_AUS;
}

} // Ende ISR (TIMER1_OVF_vect)
 
Ja, so müsste es funktionieren.

also, wenn ich das so alles richtig geschrieben habe, klappt es immer noch nicht...!
Gibt es nicht vill. eine Effektivere PWM Methode die man mit dem "OVF" realisieren kann?
 
Mach mal diesen Teil ...

Code:
if (PWM0 > 0)
{
        alle_AN;
}
  else        
{
        alle_AUS;
}

hinter counter = 0 in die Klammer.

Oder verwende einfach mein Beispiel.
 
egal welchen Wert ich für "PWM0" nehme... es passiert nichts

Code:
ISR(TIMER0_OVF_vect) // Schaltet nach jedem Überlauf ( Overflow ) die HighPowerLED´s an
{
	static uint8_t counter = 0;

	counter++;

	if (counter >= 100)
	{
		counter = 0;
	if (PWM0 > 0)
	{
		alle_AN;
	}
		else
	{
		alle_AUS;
	}
	
	}	

} // Ende ISR (TIMER1_OVF_vect)
 
Also so müsste es in dem erwähnten Buch stehen:

(Im geposteten Sourcecode war eine Klammer falsch gesetzt)

Code:
ISR(TIMER0_OVF_vect)
{
  static uint8_t counter = 0;

  counter++;

  if (counter >= 100)
  {
    counter = 0;
    if (PWM0 > 0)
    {
      alle_AN;
    } else {
      alle_AUS;
    }    
  }    

  if (counter == PWM0)
  {
    alle_AUS;
  }

} // Ende ISR (TIMER1_OVF_vect)


Mein Beispiel aus dem Beitrag 2:
Code:
// PWM0 = 0..100

ISR(TIMER0_OVF_vect) 
{
    static uint8_t counter = 0;
    
    counter++;

    if (counter >= 100)
    {
        counter = 0;
        if (PWM0 > 0) LED_an
    }
    
    if (counter == PWM0) LED_aus
    
}
 
so klappt es jetzt danke ;)

Code:
volatile uint8_t PWM0 = 1;
    
uint8_t keystatus;

int main(void)
{
	DDRB = 0xFF;
	
	OCR1A   = 77;							// Legt den Wert ZUM Überlaufes fest ( ca. jede 10 ms.)
	TCCR1A |= (1<<WGM01);					// Compare Match (Normal Mode) keine Funktion am PIN &&    TIFR |= 0x01;			// Clear Interrupt Flag ( Wird nur für Polling benötigt! Nicht für Interrupt )
	TIMSK  |= (1<<OCIE0A);					// Compare Match Interrupt enable
	TCCR1B |= ((1<<CS02) | (1<<CS00));		// Prescaler auf 1024 setzen (F_CPU/1024)
	
	TCCR0B = (1<<CS00);
	TIMSK  = (1<<TOIE0);
	sei();									// Interrupts global aktivieren
	
	

	while(1)
	{

				
	}// Ende While
	
}// Ende Main

ISR(TIMER1_COMPA_vect)
{

}



ISR(TIMER0_OVF_vect) // Schaltet nach jedem Überlauf ( Overflow ) die HighPowerLED´s an
{
	static uint8_t counter = 0;

	counter++;

	if (counter >= 100)
	{
		counter = 0;
	
	if (PWM0 > 0)
	{
		alle_AN;
	}
		else
	{
		alle_AUS;
	}

	}
	
		else
		
	{
	
	if (counter == PWM0)
	{
		alle_AUS;
	
	}
	
	
	
	}
	

} // Ende ISR (TIMER1_OVF_vect)
 

Über uns

  • Makerconnect ist ein Forum, welches wir ausschließlich für einen Gedankenaustausch und als Diskussionsplattform für Interessierte bereitstellen, welche sich privat, durch das Studium oder beruflich mit Mikrocontroller- und Kleinstrechnersystemen beschäftigen wollen oder müssen ;-)
  • Dirk
  • Du bist noch kein Mitglied in unserer freundlichen Community? Werde Teil von uns und registriere dich in unserem Forum.
  •  Registriere dich

User Menu

 Kaffeezeit

  • Wir arbeiten hart daran sicherzustellen, dass unser Forum permanent online und schnell erreichbar ist, unsere Forensoftware auf dem aktuellsten Stand ist und der Server regelmäßig gewartet wird. Auch die Themen Datensicherheit und Datenschutz sind uns wichtig und hier sind wir auch ständig aktiv. Alles in allem, sorgen wir uns darum, dass alles Drumherum stimmt :-)

    Dir gefällt das Forum und unsere Arbeit und du möchtest uns unterstützen? Unterstütze uns durch deine Premium-Mitgliedschaft!
    Wir freuen uns auch über eine Spende für unsere Kaffeekasse :-)
    Vielen Dank! :ciao:


     Spende uns! (Paypal)