Hallo!
Ja, das Thema gabs schon öfter ;-)
Ich hab diverse Threads durch und auch das LED-Dimmen laut Artikel läuft
auf dem dort auch verwendeten Mega8.
Ich habe mittlerweile aus dem Vorhaben, einen RGB-LED Controller zu
bauen, eins gemacht, erstmal nur eine LED irgendwie zu faden und die PWM
zum laufen zu bringen. Quasi ein Minimal-Programm:
1
#include<avr/io.h>
2
#include<util/delay.h>
3
4
intmain(void)
5
{
6
PORTB=(1<<PB0);
7
TCCR0A=(1<<COM0A1)|(1<<WGM01)|(1<<WGM00);//fast-pwm, non inverted OC0A
8
TCCR0B=(1<<CS02)|(1<<CS00);//Prescaler 1/1024
9
OCR0A=0;
10
//Hauptschleife
11
while(1)
12
{
13
OCR0A=OCR0A+1;
14
if(OCR0A==255)OCR0A=0;
15
_delay_ms(100);
16
17
}
18
}
Das programm soll auf einem ATTiny25 laufen, die Fuses stehen auf
Standard (8Mhz interner Oszillator, CKDIV/8 programmiert, also 1Mhz
Takt).
Keine logarithmische Kurve/Tabelle, nichts, die LED sollte einfach nur
irgendwie heller werden und dann von vorne anfangen.
Was habe ich vergessen??? Das Ding macht mich seit wochen bescheuert...
EDIT: Mit diesem Programm leuchtet die LED ganz schwach mit einer
Helligkeit durch. Kein Flackern, nichts. Oszilloskop habe ich leider
nicht, um zu gucken, was wirklich rauskommt.
Danke für die hilfe im Voraus!
LG, Björn
Ich weiß grad nicht auswendig wie das war. Aber eventuell musst du noch
das Data Direction Bit für den Pin setzen. Das schwache Glimmen könnte
vom Pull-Up kommen.
MfG
Marius
Scheisse wie peinlich...hab PORTB anstatt DDRB geschrieben...wird sofort
getestet...
In den Programmen vorher war dann viellciht was anderes falsch, also
nicht dass einer denkt ich verzweifel seit wochen an den 3 zeilen wegen
dem ddr...
Danke schonmal!
LG, Björn
Hi
>Was habe ich vergessen??? Das Ding macht mich seit wochen bescheuert...
Timer0 des ATMega8 hat keine Hardware-PWM! Wenn schon 8-Bit, dann
musst du Timer2 nehmen.
>Vielleicht das Datadirection-Register?
Quatsch. Die Funktion des OCR-Pins wird mit den COM-Bits
Hi
Dummerweise auf Absenden gedrückt.
>Quatsch. Die Funktion des OCR-Pins wird mit den COM-Bits
im TCC-Register eingestellt. Wenn das PIN mit der Compareeinhet
verbunden ist kannst du in DDR einstellen, was du willst.
MfG Spess
Es ging um den Tiny25, nicht um den Mega8!
Und, Zitat aus dem Datenblatt:
>>The COM0A1:0 and COM0B1:0 bits control the behaviour of Output Compare >>pins
OC0A and
>>OC0B, respectively. If any of the COM0A1:0 bits are set, the OC0A output >>overrides the normal>>port functionality of the I/O pin it is connected to. Similarly, if any of >>the
COM0B1:0 bits are set,
>>the OC0B output overrides the normal port functionality of the I/O pin it >>is
connected to. How-
>>ever, note that the Data Direction Register (DDR) bit corresponding to the >>OC0A and OC0B pins>>must be set in order to enable the output driver.
Das DDR war der Fehler. Außerdem war die PWM-Frequenz wesentlich zu
niedrig.
So funktioniert es jetzt:
1
#include<avr/io.h>
2
#include<util/delay.h>
3
4
intmain(void)
5
{
6
DDRB=(1<<PB0);
7
TCCR0A=(1<<COM0A1)|(1<<WGM01)|(1<<WGM00);//fast-pwm, non inverted OC0A
8
TCCR0B=(1<<CS01)|(1<<CS00);//Prescaler 1/64
9
OCR0A=0;
10
//Hauptschleife
11
while(1)
12
{
13
OCR0A=OCR0A+1;
14
if(OCR0A==255)OCR0A=0;
15
_delay_ms(20);
16
17
}
18
}
nur für die, die es interessiert.
Jetzt kann ich die logarithmische Tabelle einbauen und dann das ganze
verdreifachen....
Danke nochmals für die Hilfe!
LG, Björn
Hi
Kommando zurück. Soll ja ATTiny25 sein.
Trotzdem musst du in TCCR0A mit COM0A1 und COM0A0 dem Timer sagen, was
er mit dem Pin machen soll. Wie gesagt, DDR ist egal.
MfG Spess
>Timer0 des ATMega8 hat keine Hardware-PWM! Wenn schon 8-Bit, dann>musst du Timer2 nehmen.
Den Mega8 habe ich überlesen. Der Tiny25 hat allerdings die gewünschte
Funktion.
>Wenn das PIN mit der Compareeinhet>verbunden ist kannst du in DDR einstellen, was du willst.
Ist beim Tiny45 nicht der Fall. (Figure 11-6; Text nicht gelesen, nur
Bild beguckt...).
spess53 schrieb:
> Trotzdem musst du in TCCR0A mit COM0A1 und COM0A0 dem Timer sagen, was> er mit dem Pin machen soll.
Hatte ich bereits von Anfang an..
>Wie gesagt, DDR ist egal.
Eben nicht...siehe mein Zitat aus dem Datenblatt oben.
Trotzdem danke für die Hilfe!
LG, Björn
TCCR0A=(1<<COM0A1)|(1<<WGM01)|(1<<WGM00);//fast-pwm, non inverted OC0A
15
TCCR0B=(1<<CS01)|(1<<CS00);//Prescaler 1/64
16
OCR0A=0;
17
uint8_ti=0;
18
//Hauptschleife
19
while(1)
20
{
21
22
for(i=0;i<32;i++)
23
{
24
OCR0A=pgm_read_byte(&pwmtable[i]);
25
_delay_ms(100);
26
}
27
for(i=31;i>=0;i--)
28
{
29
OCR0A=pgm_read_byte(&pwmtable[i]);
30
_delay_ms(100);
31
}
32
33
34
}
35
}
Die LED fadet jetzt einmal hoch und einmal runter wie sie soll, was dank
der Wertetabelle echt gut aussieht. Danach scheint das Programm aber den
Programmspeicher zu lesen anstelle der Tabelle. Die LED blinkt wild
herum, irgendwann fadet sie wieder von ganz hell nach dunkel, dann
wiederholt sich das Spiel. Irgendwas scheint also mit i nicht zu stimmen
bzw. mit meinen for-Schleifen...
LG, Björn
@ Björn R. (sushi)
>wiederholt sich das Spiel. Irgendwas scheint also mit i nicht zu stimmen
Stimmt genau! ;-)
Mach mal aus deinem i mal ein int8_t ohne u und staune ;-)
>bzw. mit meinen for-Schleifen...
Schau dir mal die zweite Schleife an.
MFG
Falk
Danke, Falk! Da wäre ich so schnell nicht drauf gekommen. Auch nachdem
ich es ausprobiert hatte und es auf einmal funktionierte, hat es die
Zahnräder im Hirn etwas drehen müssen, bis der Groschen gefallen ist...
Spitze!
LG, Björn
So, das RGB-faden funktioniert jetzt auch. Allerdings hat es mit der
exponentiellen Kennlinie nicht so gut funktioniert, da waren dann
hauptsächlich die grundfarben zu sehen und die Mischfarben nur sehr
kurz. Ich habe dann mit mehreren anderen Kennlinien experimentiert,
wobei sich herausstellte, dass es mit einer linearen doch am Besten
klappt. Ich vermute, die Kennlinie meiner RGB-LED ist dahingehend
angepasst, dass man mit einer linearen PWM da schön faden kann. Leider
habe ich dafür keine Beweise, da ich kein Datenblatt dazu habe.
Überhaupt habe ich da wohl am falschen Ende gespart, die 3 Chips
strahlen nicht in die gleiche Richtung. man hat also immer Ränder in den
beteiligten Grundfarben mit dabei. Im Anhang die kennlinien, die ich
ausprobiert habe(naja die braune nicht mehr, da war es schon klar),
bevor ich das feature rausgenommen und einfach von 0 bis 255
durchgelaufen bin. Das Programm sieht jetzt so aus:
1
#include<avr/io.h>
2
#include<util/delay.h>
3
4
intmain(void)
5
{
6
DDRB=(1<<PB0)|(1<<PB1)|(1<<PB4);
7
//Timer 0(R,G)
8
TCCR0A=(1<<COM0A1)|(1<<COM0B1)|(1<<WGM01)|(1<<WGM00);//fast-pwm, non inverted, OC0A, OC0B
Das sind nicht zufällig die Flux-LEDs ausm Ebay-Shop "shop4leds" oder?
Da ist mir das mit den Farbrändern auch schon unangenehm aufgefallen.
Wenn du besseren Ersatz findest (schön hell sind sie a schon), oder
jemand bessere helle RGB-LEDs kennt, teilt das mal bitte mit.
Du solltest lieber HSB statt RGB Codierung nutzen wenn du die Farben
durchgehen möchtest.
In der Codesammlung hat mal jemand einen entsprechenden Konverter
vorgestellt.