mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik 8 bit PWM steuert nicht voll aus / casting problem


Autor: cepheus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
hi,
ich habe 2 Probleme mit einem mega8.
1. Ich verwende 3 PWMs:
        TCCR1A |= (1 << CS01);
        TCCR1A |= (1<<WGM10);
        TCCR1A |= (1<<COM1A1) | (1<<COM1B1);
        TCCR1B |= (1 << CS11);
        TCCR2 |= (1 << WGM20) | (1 << COM21);
        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.
        if(mode_nmb > 4)  {
                uint8_t red = 0;
                red = (uint8_t)((uint16_t)value_current[0]*brightness[mode_nmb])/100;
                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.

Autor: Matthias Lipinsky (lippy)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
wie wäre es mit etwas mehr Quellcode?

Autor: cepheus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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).

Autor: Naja (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>Gerne, von was genau?

Für solche Fälle gilt folgendes:
Reduziere den Code auf das absolut notwendigste, so das der Fehler 
reproduzierbar ist.

Autor: cepheus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Okay, hier die kleine Version. Ich erkenne an der LED am OCR1B durch die 
Schleife eine deutliche Helligkeitsschwankung.
#include <stdlib.h>
#include <avr/io.h>
#include <inttypes.h>
#include <util/delay.h>

void init( void )
{

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

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

}

int main(void)
{
        init();
        while ( 1 ){
                OCR1B = 255;
                _delay_ms(50);
                OCR1B = 1023;
                _delay_ms(50);
        }
}

Autor: Naja (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Da Du in der Hauptschleife nur Timer 1 verwendest, ist der minimale 
Code:
#include <stdlib.h>
#include <avr/io.h>
#include <inttypes.h>
#include <util/delay.h>

void init( void )
{

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

        TCCR1A |= (1 << CS01;
        TCCR1A |= (1<<WGM10);
        TCCR1A |= (1<<COM1A1) | (1<<COM1B1);
        TCCR1B |= (1 << CS11);
}

int main(void)
{
        init();
        while ( 1 ){
                OCR1B = 255;
                _delay_ms(50);
                OCR1B = 1023;
                _delay_ms(50);
        }
}


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.

Autor: Naja (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Da Du zwischen 255 und 1023 wechselst, sollte auch eine 
Helligkeitsschwankung da sein.
Was ist Dein Takt?
Je nachdem sieht man die Schwankung auch.

Autor: Naja (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wahrscheinlich ein Fall von RTFM ;-)

Autor: cepheus (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Naja (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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)

Autor: Naja (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das fehlgeleitete CS01 stellt Dir eine 10-Bit PWM ein. Deswegen gibt es 
eine Änderung der Helligkeit zwischen 255 und 1023.

Autor: cepheus (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.
#include <stdlib.h>
#include <avr/io.h>
#include <inttypes.h>

#include <util/delay.h>

void init( void )
{
        DDRB = (1 << PB1) | (1 << PB2) | (1 << PB3);

        TCCR1A |= (1<<WGM10);
        TCCR1A |= (1<<COM1A1) | (1<<COM1B1);
        TCCR1B |= (1 << CS11);

}

int main(void)
{
        init();
        while ( 1 ){
                OCR1B = 255;
                _delay_ms(50);
                OCR1B = 1023;
                _delay_ms(50);
        }
}

Autor: Naja (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Na bestens.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.