Hallo,
ich würde gerne am Pin B1 (OC1A) einen Takt von 204,8 kHz ausgeben (10
Bit * 200 Hz ; für einen TLC5940).
Dazu habe ich folgenden C-Code auf den Atmega48 programmiert:
1
#include<avr/io.h>
2
#include<avr/interrupt.h>
3
4
#define sleep() asm volatile ("nop")
5
6
7
volatileuint8_tdata[10];
8
9
intmain(void)
10
{
11
12
// --- TIMER1_COMPA irq ---
13
// selected time = 204800 Hz (78 ticks)
14
// prescaler = 1 (1 ticks ... 4.096 ms)
15
TCCR1B=(1<<WGM12)|(1<<CS10);
16
OCR1AH=255;
17
OCR1AL=178;
18
TIMSK1|=(1<<OCIE1A);
19
20
// --- main loop ---
21
sei();
22
23
for(;;)sleep();
24
25
return0;
26
}
Nur wenn ich jetzt mit dem Oszi messe, tut sich an Pin B1 gar nichts.
Laut Datenblatt sollte das aber doch funktionieren!?
Der Atmega48 läuft mit einem 16Mhz Quarz und funktioniert auch korrekt
(also LED blinken geht und Frequenz stimmt auch).
Könntet ihr mir da evtl. weiterhelfen, ich steht irgendwie auf dem
Schlauch oder bin noch zu sehr dem Atmega8 gewöhent...
Viele Grüße
Julian
Hi
>ich steht irgendwie auf dem Schlauch oder bin noch zu sehr dem Atmega8
gewöhent...
Auch beim ATMega8 muss man das Pin auf Ausgang schalten.
MfG Spess
Hi,
DDRB &= ~(1<<PB1); //Richtung laut datasheet erst nach TCNT und OCRx
setzen
TCNT1 = 0x00; //clear
OCR1A = (F_CPU / (2*n*frequency)) - 1; //Register laden, vorsicht n = 1
!!!
DDRB |= (1<<PB1); //Richtungsregister darf jetzt gesetzt werden
TCCR1A |= (1<<COM1A0); //CTC Mode, mit Toggle PB1
TCCR1B |= (1<<CS10) | (1<<WGM12); //no prescaler, siehe oben, deswegen n
= 1
und auf keinen TIMSK1 |= (1<<OCIE1A) setzen, ohne eine Interrupt
Routine, da läuft dir das dingen ins Nirvana !
Gruß und hoffe das stimmt, nur auf die schnelle zusammen gesucht ausm
DataS.
>Nur wenn ich jetzt mit dem Oszi messe, tut sich an Pin B1 gar nichts.
Logisch, du hast es nicht als Ausgang geschaltet.
>Könntet ihr mir da evtl. weiterhelfen, ich steht irgendwie auf dem>Schlauch oder bin noch zu sehr dem Atmega8 gewöhent...
Was wäre die Welt ohne dumme Ausreden. Der Timer 1 funktioniert in ALLEN
AVRs gleich!
RTFM.
MFG
Falk
So funktionierst, muss ich mich halt geschlagen geben ;)
Noch 'ne andere Frage:
Ist es auch möglich, dass ganze in einem Interrupt abzufangen.
Eigentlich wäre für mich nur ein Interrupt alle 1024 Interrupts (10 Bit
eben) interessant, aber notfalls muss ich halt per Software hochzählen,
der μC hat eh nicht viel zu tun ;)
Was willst du denn da abfagen? Der Timer is ne eigenständige Einheit.
Du kannst die aber im CTC-Modus Zeitintervalle generieren, die halt noch
nebenbei laufen.
Gruß Knut
@ Julian W. (julian-w) Benutzerseite
>Ist es auch möglich, dass ganze in einem Interrupt abzufangen.
Jain, ist hier aber nicht sinnvoll.
>Eigentlich wäre für mich nur ein Interrupt alle 1024 Interrupts (10 Bit>eben) interessant, aber notfalls muss ich halt per Software hochzählen,>der μC hat eh nicht viel zu tun ;)
Dann nimm Timer 0 und lass den dein Multiplexingintervall generieren.
Fettig.
MFG
Falk
Nunja, das ganze hat folgenden Hintergrund:
die 204,8 kHz sind der Takt einer 10 Bit PWM. Nach 1024 Takte ist die
PWM also einmal durchgelaufen. Dieses "Ereignis" würde ich gerne
abfangen.
Wie kann ich dass den am besten anstellen?
Ach, Falk, sehe gerade, du hast ja schon was gepostet, während ich noch
schieb.
Also du würdest mir empfehlen, Timer0 einfach mit 200Hz laufen zu
lassen. Hört sich gar nicht so dumm an, hört sich sogar richtig gut an.
Werd ich gleich mal testen...
Julian W. schrieb:> Nunja, das ganze hat folgenden Hintergrund:> die 204,8 kHz sind der Takt einer 10 Bit PWM. Nach 1024 Takte ist die> PWM also einmal durchgelaufen.
Ich versteh nicht ganz was du meinst?
Julian W. schrieb:> lso du würdest mir empfehlen, Timer0 einfach mit 200Hz laufen zu> lassen. Hört sich gar nicht so dumm an, hört sich sogar richtig gut an.> Werd ich gleich mal testen...
CTC-Modus halt...
Gruß Knut
Ingo L. schrieb:> Julian W. schrieb:>> Nunja, das ganze hat folgenden Hintergrund:>> die 204,8 kHz sind der Takt einer 10 Bit PWM. Nach 1024 Takte ist die>> PWM also einmal durchgelaufen.>> Ich versteh nicht ganz was du meinst?
Ganz einfach: Ich nutze den TLC5940, diesem muss ich einen PWM-Takt
seperat einspeißen. Das sind die 204,8 kHz (10bit = 1024; 200Hz PWM-FRQ
=> 1024 * 200 = 204800). D.h., wenn der Timer1 1024 mal ausgelöst hat,
ist eine PWM-Phase vorbei. Und dieses Ereignis würde ich gerne in
Software abfangen.
@ Julian W. (julian-w) Benutzerseite
>ist eine PWM-Phase vorbei. Und dieses Ereignis würde ich gerne in>Software abfangen.
Mit Timer 0 im Overflow Interrupt. Dort kann man, wenn man will,
einfach per
Falk Brunner schrieb:> Mit Timer 0 im Overflow Interrupt
Ist nicht ein Compare-Match besser geeignet als ein Timeroverflow?
Nicht das deine Lösung nicht funktionieren würde...
Gruß Knut
@ Ingo L. (knutinator)
>> Mit Timer 0 im Overflow Interrupt>Ist nicht ein Compare-Match besser geeignet als ein Timeroverflow?
Ja, damit kann man die Interruptfrequenz viel genauer einstellen. Wenn
das wirklich entscheidend ist.
MFG
Falk
Moin und Mahlzeit,
ich habe zu fast der gleichen Anwendung auch eine "Frage". Ich möchte
eben auch einen Takt für einen TLC5940 generieren. Das könnte ich ja.
z.B. mit Timer0 im fast PWM mode und OVF-Interrupt machen.
Jetzt muß ich ja aber beim "normalen" Grayscale-Mode des 5940 immer nach
4095 Zählschritten (oder was ich auch immer für eine Auflösung haben
will) den BLANK-Pin einmal toggeln.
Ich müßte also nach jedem PWM-Takt abfragen, ob das denn jetzt der
4095ste war, oder nicht.
Da war meine Idee, ob ich den PWM-Pin nicht zusätzlich an den
Capture-Pin von Timer1 anklemmen könnte. Da stelle ich den
Vergleichswert dann auf 4095 und kann mir dann die Abfragen sparen, weil
ich ja weiß, daß genau die gewünschte Anzahl von Takten durch ist.
Wäre das gut oder gibt es etwas schwerwiegendes, was dagegen spricht?
Gruß