Attiny13A 2 PWM Ausgänge

Gast #5803179
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
#5803253
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.
Gast #5803276
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.
#5803323
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: ..."
#5804473
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
Gast #5804664
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
}
Gast #5804696
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
}

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren