8 bit PWM steuert nicht voll aus / casting problem

Gast #1476645
hi,
ich habe 2 Probleme mit einem mega8.
1. Ich verwende 3 PWMs:
1
        TCCR1A |= (1 << CS01);
2
        TCCR1A |= (1<<WGM10);
3
        TCCR1A |= (1<<COM1A1) | (1<<COM1B1);
4
        TCCR1B |= (1 << CS11);
5
        TCCR2 |= (1 << WGM20) | (1 << COM21);
6
        TCCR2 |= (1 << CS21) |(1 << CS20);
OC2 funktioniert einwandfrei, die OC1A/B sind aber erst bei 100% wenn 
ich 1023 in die Register schreibe, obwohl das Ganze doch 8 bit sein 
sollte?. Habe ich da was uebersehen?

2. Betrifft das erste nur etwas:
Die OCs steuern LEDs, ich wuerde dazu gerne Farb- und Helligkeitswerte 
kombinieren, und zwar getrennt.
Dazu folgendes Codeschnipsel, ergibt jetzt zwar wenig Sinn weil ich es 
zum debuggen schon ziemlich verwurstet habe, aber das
Problem konnte ich, egal wie weit ich das betrieben habe, nicht
beseitigen.
1
        if(mode_nmb > 4)  {
2
                uint8_t red = 0;
3
                red = (uint8_t)((uint16_t)value_current[0]*brightness[mode_nmb])/100;
4
                OCRED = red;
Erklaerung: value_current[] enthaelt den jeweiligen Farbwert, der mit 
einem zugehoerigen Helligkeitswert aus dem brightness[] (0-100) 
kombiniert werden soll.
Sobald ich jetzt in diesen Fall wandere, passieren die seltsamsten 
Dinge. Andere Variablen werden ueberschrieben, der Controler haengt sich 
auf, etc.
Hoffe, ihr koennt mir helfen, vielen Dank schonmal.
Gast
Gerne, von was genau? Das ganze Teil ist ziemlich viel und noch recht 
unuebersichtlich, wollte ich jetzt keinem antun.
Glaube 2. hat sich gerade erledigt, schein mich einfach mit der casterei 
verhauen zu haben (blame me, aber ich hab wirklich vorher >2h probiert).
Gast
Okay, hier die kleine Version. Ich erkenne an der LED am OCR1B durch die 
Schleife eine deutliche Helligkeitsschwankung.
1
#include <stdlib.h>
2
#include <avr/io.h>
3
#include <inttypes.h>
4
#include <util/delay.h>
5

6
void init( void )
7
{
8

9
        PORTB = (1 << PB0) | (1 << PB6) | (1 << PB7);
10
        DDRB = (1 << PB1) | (1 << PB2) | (1 << PB3);
11

12
        TCCR1A |= (0 << CS02) | (1 << CS01) | (0 << CS00);
13
        TCCR1A |= (0 << WGM12) | (0<<WGM11) | (1<<WGM10);
14
        TCCR1A |= (1<<COM1A1) | (0 << COM1A0) | (1<<COM1B1) | (0 << COM1B0);
15
        TCCR1B |= (0<<CS12) | (1 << CS11) | (0 <<CS10);
16
        //blue 8 bit
17
        TCCR2 |= (0 << WGM21) | (1 << WGM20) | (1 << COM21) | (0 << COM20);
18
        TCCR2 |= (0 << CS22) | (1 << CS21) |(1 << CS20);
19

20
}
21

22
int main(void)
23
{
24
        init();
25
        while ( 1 ){
26
                OCR1B = 255;
27
                _delay_ms(50);
28
                OCR1B = 1023;
29
                _delay_ms(50);
30
        }
31
}
Gast
Da Du in der Hauptschleife nur Timer 1 verwendest, ist der minimale 
Code:
1
#include <stdlib.h>
2
#include <avr/io.h>
3
#include <inttypes.h>
4
#include <util/delay.h>
5

6
void init( void )
7
{
8

9
        PORTB = (1 << PB0) | (1 << PB6) | (1 << PB7);
10
        DDRB = (1 << PB1) | (1 << PB2) | (1 << PB3);
11

12
        TCCR1A |= (1 << CS01;
13
        TCCR1A |= (1<<WGM10);
14
        TCCR1A |= (1<<COM1A1) | (1<<COM1B1);
15
        TCCR1B |= (1 << CS11);
16
}
17

18
int main(void)
19
{
20
        init();
21
        while ( 1 ){
22
                OCR1B = 255;
23
                _delay_ms(50);
24
                OCR1B = 1023;
25
                _delay_ms(50);
26
        }
27
}

Leider kann ich selbst mit "Ich erkenne an der LED am OCR1B durch die
Schleife eine deutliche Helligkeitsschwankung." nicht viel anfangen. Ist 
das gut oder schlecht?

Du schriebst: "die OC1A/B sind aber erst bei 100% wenn
ich 1023 in die Register schreibe, obwohl das Ganze doch 8 bit sein
sollte?."

Ich weiss ja nicht welchen Prozessor Du verwendest, aber bei den AVRs 
ist Timer 1, soweit ich weiss ein 16Bit Timer. Daher scheint es mir 
völlig verständlich, das nur bei 1023 die volle Helligkeit eintritt, da 
nur das die maximale PWM ergibt.
Gast
Zum ersten: Es ist schlecht, weil ich bei 8-bit bei 255 das Maximum 
erwarte.
Wie oben erwaehnt, ist ein Mega8, da ist Timer1 schon 16bit, klar.
Nur habe ich durch die WGM bits den in den 8-bit PWM-Modus gesetzt. Oder 
habe ich am Datenblatt was grundlegend falsch verstanden? Da steht fuer 
diesen Modus als Top "0x00FF".

@Naja: 8MHz. Die Schwankung ist hier zu Testzwecken beabsichtigt, ich 
wollte den Unterschied der beiden Visualisieren.
Gast
OK. Das mit dem ATMega8 habe ich überlesen. (Bitte Gross-Kleinschreibung 
beachten).

1. Die Clock-Select Bits CS01 in dem Steuerregister A von Timer 1 zu 
setzen gibt wahrscheinlich Murks.
2. Mit dem 8 Bit Modus hast Du eigentlich recht. Da aber in 255 und 1023 
alle 8 niederwertigen Bits gesetzt sind, dürfte das garkeine 
Helligkeitsveränderung geben. Merkwürdig.

Ändere mal das mit CS01 und probiere es nochmal. Poste den dann 
enstandenen Code (bitte ohne 0 << 109120912, das gibt sowieso nur 0)
Gast
Oh danke, das hatte ich ueberlesen dass das da nicht hingehoert.
Sieht gleich viel besser aus (== 255 ist volle Helligkeit).
Was rauskommt ist mir dann auch klar, CS01 ist als 1 definiert, also in 
dem
Fall setzt er dann WGM11 und WGM10, das gibt 10-bit PWM.
Hier trotzdem nochmal der funktionierende Code.
1
#include <stdlib.h>
2
#include <avr/io.h>
3
#include <inttypes.h>
4

5
#include <util/delay.h>
6

7
void init( void )
8
{
9
        DDRB = (1 << PB1) | (1 << PB2) | (1 << PB3);
10

11
        TCCR1A |= (1<<WGM10);
12
        TCCR1A |= (1<<COM1A1) | (1<<COM1B1);
13
        TCCR1B |= (1 << CS11);
14

15
}
16

17
int main(void)
18
{
19
        init();
20
        while ( 1 ){
21
                OCR1B = 255;
22
                _delay_ms(50);
23
                OCR1B = 1023;
24
                _delay_ms(50);
25
        }
26
}

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 16 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.