8 bit PWM steuert nicht voll aus / casting problem

Gast #1476645
Lesenswert?

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 #1476685
Lesenswert?

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 #1476688
Lesenswert?

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 #1476697
Lesenswert?

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 #1476706
Lesenswert?

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 #1476720
Lesenswert?

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

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