Forum: Mikrocontroller und Digitale Elektronik Attiny13A 2 PWM Ausgänge


von Tobias (Gast)


Lesenswert?

Hallo zusammen,
ich bräuchte mal Hilfe zum Thema PWM bei einem Attiny13A

Ich schnall das einfach nicht... (salopp gesagt)

Der Attiny13A hat ja 2 PWM Ausgänge 8bit,
was auch reichen sollte 2 LED´s unterschiedlich zu dimmen.

Wie ich eine LED mit PWM betreibe bekomme ich hin, aber offenbar läuft 
dies im Fast PWM Mode, welches mir ja dann den 2. Kanal blockiert. Hier 
mal der CODE.. (ja ich weißt Ordnung fehlt.

https://pastebin.com/8Ewibbbu

Zur Aufgabenstellung:
Ich möchte 2 LEDs unterschiedlich faden lassen, selbe frequenz, nur das 
wenn die eine an fadet, soll gleichzeitig die 2. LED ausfaden.

Der Code ist einfach nur zusammengewürfelt und kopiert und in 
keinsterweise sortiert, optimiert oder sonst was... das ist erst mal 
mein Testgeschnipsel.


Vielen Dank schon mal

Grüße
Tobias

: Verschoben durch User
von Carl D. (jcw2)


Lesenswert?

Ich sehe im Code nur einen Kanal (COM0B) aktiviert. Warum sollte der 
andere (COM0A) also funktionieren?

von Tobias (Gast)


Lesenswert?

Hallo,
Okay wenn ich den aktiviere, wie steuer ich den dann im pwm_write an?
OCR0B ist doch PB1
Geht es dann mit OCR0A?

Wenn PB1 den Wert 255 hat soll PB0 den Wert 0 haben.

von Carl D. (jcw2)


Lesenswert?

Tobias schrieb:
> Hallo,
> Okay wenn ich den aktiviere, wie steuer ich den dann im pwm_write an?
> OCR0B ist doch PB1
> Geht es dann mit OCR0A?
PB0 zeigt die "A"-PWM, so denn auch aktiviert.

> Wenn PB1 den Wert 255 hat soll PB0 den Wert 0 haben.
Das klingt eher nach komplementärer Ausgang, was der Tiny13 nicht direkt 
kann.
2 LEDs zu dimmen ist aber was anderes. Wenn es also nur darum geht, Die 
Helligkeit der LEDs komplementär zu sehen, dann ist die exakte 
Phasenlage egal, d.h. CCR0A = ~OCR0B.

von c-hater (Gast)


Lesenswert?

Tobias schrieb:

> Ich schnall das einfach nicht... (salopp gesagt)
>
> Der Attiny13A hat ja 2 PWM Ausgänge 8bit,
> was auch reichen sollte 2 LED´s unterschiedlich zu dimmen.

Das stimmt doch. Was genau schnallst du daran also nicht?

> Wie ich eine LED mit PWM betreibe bekomme ich hin, aber offenbar läuft
> dies im Fast PWM Mode, welches mir ja dann den 2. Kanal blockiert.

Nein, das tut der Fast PWM Mode natürlich NICHT.

Dein Problem ist also offensichtlich: zu doof/faul das Datenblatt zu 
lesen.

> Der Code ist einfach nur zusammengewürfelt und kopiert

Genau das ist das Problem. Selbst DB lesen, selbst denken, selbst Code 
schreiben funktioniert einfach besser...

No mercy.

von Carl D. (jcw2)


Lesenswert?

Hallo Tobias,
falls du nicht nur beim AVR, sondern auch hier im Forum Anfänger bist:
Nicht jeden Post lesen, denn manche sind nur dazu geschrieben, deine 
Neugier zu zerstören. Mit der Zeit erkennt man siche Posts schon am 
zweiten Wort unter der Überschrift. "Autor: ..."

von Georg M. (g_m)


Lesenswert?

Tobias schrieb:
> OCR0B ist doch PB1

Nein, OC0B ist PB1.

OCR0A ist für OC0A(PB0) zuständig.
OCR0B ist für OC0B(PB1) zuständig.

(OCR = Output Compare Register)

von Thomas E. (thomase)


Lesenswert?

Tobias schrieb:
> Ich möchte 2 LEDs unterschiedlich faden lassen, selbe frequenz, nur das
> wenn die eine an fadet, soll gleichzeitig die 2. LED ausfaden.

Das geht auch mit einer PWM: Eine Led gegen GND, eine an Vcc und die 
beiden anderen Enden der Leds an den PWM-Ausgang.

von Dergute W. (derguteweka)


Lesenswert?

Moin,

Hier waer' Code zum zusammenwuerfeln und kopieren, mit dem man sogar 4 
LEDs mit einem attiny13a unterschiedlich dimmen kann...

Beitrag "Hilfe! - Schaltplan für Modellauto gesucht"

Gruss
WK

von Tobias B. (bomber28)


Lesenswert?

Carl D. schrieb:
> Das klingt eher nach komplementärer Ausgang, was der Tiny13 nicht direkt
> kann.
> 2 LEDs zu dimmen ist aber was anderes. Wenn es also nur darum geht, Die
> Helligkeit der LEDs komplementär zu sehen, dann ist die exakte
> Phasenlage egal, d.h. CCR0A = ~OCR0B.

Vielen Dank, das hat mir auf jedenfall geholfen


Carl D. schrieb:
> Hallo Tobias,
> falls du nicht nur beim AVR, sondern auch hier im Forum Anfänger bist:
> Nicht jeden Post lesen, denn manche sind nur dazu geschrieben, deine
> Neugier zu zerstören. Mit der Zeit erkennt man siche Posts schon am
> zweiten Wort unter der Überschrift. "Autor: ..."

Ich gebe um solche Pfosten nichts.... Ich mache das hier immer mal 
wieder nur nebenbei für mich oder für bekannte.. da mein Beruf 
(Zerspanungsmechaniker) und meine Familie mich sehr in Beschlag nehmen, 
bleibt für sowas hier leider nicht viel Zeit

Georg M. schrieb:
> Nein, OC0B ist PB1.
>
> OCR0A ist für OC0A(PB0) zuständig.
> OCR0B ist für OC0B(PB1) zuständig.
>
> (OCR = Output Compare Register)

Danke dir, auch das hat mir geholfen.


Ich habs jetzt hinbekommen mit den hier genannten Hinweisen und bissle 
testen.

Danke nochmal an alle

von Tim T. (tim_taylor) Benutzerseite


Lesenswert?

Nur falls mal einer nach sucht und ne Lösung finden will:
1
#include <avr/io.h>
2
#include <avr/interrupt.h>
3
#include <inttypes.h>
4
5
uint8_t richtung;
6
7
8
int main( void ) {
9
10
  // Analog Comparator deaktivieren
11
  ACSR |= (1 << ACD);
12
13
  // Analog to Digital Converter deaktivieren
14
  ADCSRA &= ~(1 << ADEN);
15
16
  // Analog to Digital Converter komplett abschalten
17
  PRR |= (1 << PRADC);
18
19
  // Digitale Input Buffer für PIN5, PIN4, PIN3, PIN2, PIN1 und PIN0 abschalten
20
  DIDR0 = (1 << ADC0D) | (1 << ADC2D) | (1 << ADC3D) | (1 << ADC1D) | (1 << AIN1D) | (1 << AIN0D);
21
22
  // Pin PB1 und PB0 als Ausgang, Rest als Eingang
23
  DDRB = (1 << DDB1) | (1 << DDB0);
24
25
  // PORTB Pullup für PINB4, PINB3 und PINB2 an
26
  PORTB = (1 << PINB4) | (1 << PINB3) | (1 << PINB2);
27
28
  // PWM für beide Ausgänge auf 50%
29
  OCR0A = 0x7F;
30
  OCR0B = 0x7F;
31
32
  // Fast PWM, set OC0A on Compare Match, clear OC0A at TOP, clear OC0B on Compare Match, set OC0B at TOP
33
  TCCR0A = (1 << COM0A1) | (1 << COM0A0) | (1 << COM0B1) | (0 << COM0B0)| (1 << WGM01) | (1 << WGM00);
34
 
35
  // Timer0 Prescaler 8 => ( 9.600.000 Hz / 8 ) / 8 = 150.000 Hz
36
  TCCR0B = (1 << CS01);
37
38
  // Overflow Interrupt für Timer0 / Counter0 erlauben
39
  TIMSK0 = (1 << TOIE0);
40
41
  // Global Interrupts aktivieren
42
  sei();
43
44
  while( 1 );
45
46
  return 0;
47
48
}
49
50
// ( 9.600.000 Hz / 8 ) / ( 8 * 256 ) = ~586 Hz
51
ISR( TIM0_OVF_vect ) {
52
53
  if ( richtung ) {
54
55
    OCR0A++;
56
    OCR0B++;
57
    
58
    if ( OCR0A == 0xFF ) richtung = 0;
59
60
  }
61
  else {
62
63
    OCR0A--;
64
    OCR0B--;
65
66
    if ( OCR0A == 0x00 ) richtung = 1;
67
68
  }
69
70
}

: Bearbeitet durch User
von Tobias (Gast)


Lesenswert?

Ich habs so gelöst.

Vielleicht nicht perfekt aber funktioniert
1
 
2
// 9.6 MHz, built in resonator
3
// defines
4
#define F_CPU 9600000
5
#define LED PB1 
6
#define LED1 PB0
7
 
8
// includes
9
#include <avr/io.h>
10
#include <util/delay.h>
11
 
12
 
13
void pwm_setup (void)
14
{
15
    // Set Timer 0 prescaler to clock/8.
16
    // At 9.6 MHz this is 1.2 MHz.
17
    TCCR0B |= (1 << CS01);
18
  
19
    // Set to 'Fast PWM' mode
20
    TCCR0A |= (1 << WGM01) | (1 << WGM00);
21
 
22
    // Clear OC0B output on compare match, upwards counting.
23
    TCCR0A |= (1 << COM0B1); // Ausgang PB1
24
  TCCR0A |= (1 << COM0A1); // Ausgang PB0
25
}
26
 
27
void pwm_write (int val)
28
{
29
    OCR0B = val; // Gibt den Wert an PB1 aus
30
  OCR0A = ~val; // Gibt den Wert an PB0 aus, negativ
31
}
32
 
33
int main (void)
34
{
35
  // Variablen
36
  int pwm = 0;
37
  int count = 0;
38
  
39
    // Ausgang definieren
40
    DDRB |= (1 << LED);
41
  DDRB |= (1 << LED1);  
42
 
43
    pwm_setup();
44
  
45
  
46
    while (1) {
47
48
        pwm_write(pwm);
49
    _delay_ms(15);
50
    
51
    if (pwm==255)
52
    {
53
      count = 1;
54
    }
55
    if (pwm==0)
56
    {
57
      count = 0;
58
    }
59
    
60
    if (count == 0) 
61
    {
62
      pwm = pwm + 5;
63
    }
64
    if (count == 1)
65
    {
66
      pwm = pwm - 5;
67
    }    
68
    }
69
}

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.