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
Ich sehe im Code nur einen Kanal (COM0B) aktiviert. Warum sollte der andere (COM0A) also funktionieren?
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.
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.
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.
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: ..."
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)
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.
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
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
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
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.