Hallo Leute,
leider bin ich aus der Suche im Forum bzw. im Netz allg. nicht so
richtig schlau geworden. Daher hier noch meine Frage:
Ich möchte mit einem ATTiny26 mit dem Timer0 eine bestimmte Frequenz am
Ausgang erzielen und bei diesem Signal das Tastverhältnis verstellen
können. Eigentlich eine relativ simple Sache ... dacht ich.
Mein Gedanke war der, dass jedesmal wenn ich den Ausgang toggle direkt
den Zähler (TCNT0) anpasse. Ich habe das mit einer if - else Abfrage in
der ISR erledigt. Möglicherweise ist das nicht das gelbe vom Ei... ist
aber erstmal egal.
Leider funktioniert das nicht so. Es stellt sich kein anderes
Tastverhältnis ein.
Irgendwie wird die Frequenz lediglich durch den Zählwert in dem
else-Teil definiert.
Könnt ihr mir sagen was ich für einen Fehler mache???
Danke
Hier mal der Code.:
1
#define F_CPU 1000000UL
2
#include</usr/local/avr/include/avr/io.h>
3
#include</usr/local/avr/include/util/delay.h>
4
#include</usr/local/avr/include/avr/interrupt.h>
5
6
7
volatiletot_overflow;//?
8
volatilepulse_ratio=1;//Variable Tastverhältnis
9
volatileratio_Ton=0;
10
volatileratio_Toff=0;
11
intmain(void)
12
{
13
#ifndef TIMER0_OVF_vect
14
#define TIMER0_OVF_vect TIMER0_OVF0_vect
15
#endif
16
init_OUT();// Initialisierungsmodul der HWAusgänge
Du scheinst überhaupt ein Problem mit Bit-Sachen zu haben.
Kannst du mal in einfachen Worten erklären, was du dir davon
1
TCNT0|=150;
erhoffst?
Im übrigen: Hat der Timer auf dem µC keinen CTC oder PWM-Modus mit
einstellbarer Obergrenze? CTC würde gehen, macht aber Ärger in der
Synchronisierung. PWM mit einstellbarer Obergrenze ist genau das, was du
eigentlich willst, wenn du sowohl Frequenz als auch Tastverhältnis
einstellbar haben willst.
Hi
>Im übrigen: Hat der Timer auf dem µC keinen CTC oder PWM-Modus mit>einstellbarer Obergrenze? CTC würde gehen, macht aber Ärger in der>Synchronisierung.
Hat der nicht. Die Nachfolger, ATTiny261/461/861, sind da besser
ausgestattet.
MfG Spess
spess53 schrieb:> Hat der nicht.
Oh je.
Ok, dann hat er Pech und muss das wirklich 'händisch' mittels
Timer-Vorladen in der ISR bewerkstelligen. Mit allen Nachteilen und/oder
Problemen, die sonst die Hardware erledigen würde. Geht nicht anders.
Karl Heinz schrieb:> spess53 schrieb:>>> Hat der nicht.>> Oh je.> Ok, dann hat er Pech und muss das wirklich 'händisch' mittels> Timer-Vorladen in der ISR bewerkstelligen. Mit allen Nachteilen und/oder> Problemen, die sonst die Hardware erledigen würde. Geht nicht anders.
Oder Timer1 nehmen.
mfg.
Vielen Dank erstmal für eure Antworten.
Ich fange mit dem Beantworten mal von unten an:
@thomase: Richtig, der ATtiny26 ist nicht gerade üppig ausgestattet was
die Timer betrifft. Da ich den Timer1 eventuell für eine komplexere
Aufgabe nehmen will, bleibt mir nix anderes übrig als es mit dem Timer0
händisch zu machen.
Nun zum eigentlichen Problem... den Bitmanipulationen.
Ich werd mir das ganz nochmal durcharbeiten müssen.
Die if Abfrage ist natürlich bei dem toggeln relativ sinnlos, da das
toggeln ja eigentlich nur invertiert.
@karlheinz
Mit dem Befehl:
TCNT0 |= 150;
hatte ich erhofft das er statt bei 0 gleich bei 150 anfängt zu zählen
und dadurch eher die IRS auslöst.
Dabei war mir noch so in Erinnerung, das der Compiler das auflöst.
Was ich aber übersehen habe ist die ODER verknüpfung (|).
Wobei ich mich nun frage... wann genau hat der TCNT0 den Wert 0?
Wenn der Fall eintritt 0 ODER 150 (bzw.:10010110) dann ergibt das doch
wieder 150 bzw:10010110.
Igendwie hab ich noch einige grobe Denkfehler darin.
Trotzdem Danke schonmal für die Hinweise
heinz schrieb:> Die if Abfrage ist natürlich bei dem toggeln relativ sinnlos, da das> toggeln ja eigentlich nur invertiert.
Wir bekritteln nicht die if-Abfrage an sich.
WEnn du das Tastverhältnis einstellen willst, dann musst du das
unterscheiden können und dazu brauchst du ein if.
Aber:
Das hier
1
if(PORTB,PB3==1)
macht ganz sicher nicht das, was du beabsichtigt hast!
Das ist zwar kein Syntaxfehler, und daher gibt es auch keinen Error vom
Compiler. Aber abgesehen davon ist das purer Nonsense.
UNd NB: genau das ist auch die Ursache, warum bei dir immer der else zu
Zug kommt. Denn 3 ist nun mal immer und ewig ungleich zu 1.
Denk mal über diesen letzten Satz nach und sieh in deinem C-Buch nach,
was denn eigentlich der Komma-Operator macht.
heinz schrieb:> Mit dem Befehl:> TCNT0 |= 150;> hatte ich erhofft das er statt bei 0 gleich bei 150 anfängt zu zählen
Dir ist klar, dass es einen Unterschied macht, ob man einem Register
einen Wert einfach als ganzes zuweist, oder ob man in dem Register zu
den bereits gesetztn Bits noch andere Bits mit dazusetzt?
> Was ich aber übersehen habe ist die ODER verknüpfung (|).> Wobei ich mich nun frage... wann genau hat der TCNT0 den Wert 0?> Wenn der Fall eintritt 0 ODER 150 (bzw.:10010110) dann ergibt das doch> wieder 150 bzw:10010110.
Du magst da sogar GLück haben. Sobald allerdings andere Interrupts ins
Spiel kommen und die Abarbeitung der ISR ein wenig warten muss, steht
dann eben nicht mehr 0 in TCNT0. Selbiges wenn der Timer mit einem
Prescaler von 1 operiert.
> Wobei ich mich nun frage... wann genau hat der TCNT0 den Wert 0?
Der genaue Zeitpunkt ist: Exakt zu dem Zeitpunkt an dem das Interrupt
Flag gesetzt wird. Das iat aber nicht der Zeitpunkt, an dem die ISR zu
laufen beginnt und es ist auch nicht der Zeitpunkt an dem diese
Anweisung ausgeführt wird. Je nach Prescaler kann der Timer da schon
wieder weiter gezählt haben.
> Igendwie hab ich noch einige grobe Denkfehler darin.
Karl Heinz schrieb:> Der genaue Zeitpunkt ist: Exakt zu dem Zeitpunkt an dem das Interrupt> Flag gesetzt wird. Das iat aber nicht der Zeitpunkt, an dem die ISR zu> laufen beginnt und es ist auch nicht der Zeitpunkt an dem diese> Anweisung ausgeführt wird. Je nach Prescaler kann der Timer da schon> wieder weiter gezählt haben.>>> Igendwie hab ich noch einige grobe Denkfehler darin.>>
if(PORTB & (1 <<PB3))
{
}
else
{
}
klappt hervorragend.
Was macht das PORTB,PB3 eigentlich?
Habe das nur bei den Makrofunktionen gefunden (jetzt eben erst)
Ich kann aber auch nicht mehr sagen wie das reingeraten ist.
...
Vielen vielen Dank.
heinz schrieb:> Was macht das PORTB,PB3 eigentlich?
if(PORTB,PB3 == 1)
{
...
}
else...
Der Kommaoperator sorgt dafür, daß zwei(oder mehrere) Ausdrücke
ausgeFÜHRT werden. Statt üblicherweise nur einem.
AusgeWERTET wird aber nur der letzte!
Da der Ausdruck "PORTB" nichts hergibt, wird gar nichts gemacht, da PB3
eine Konstante mit dem Wert 3 ist, wird auch die Bedingung, die
eigentlich ausgewertet werden soll, nie erfüllt. Also ist das vollkommen
sinnlos. Selbst wenn PB3 1 wäre, wäre das sinnlos, da die Bedingung dann
immer erfüllt wäre.
mfg.