Forum: Mikrocontroller und Digitale Elektronik Frequenz ausgeben


von ChristianS (Gast)


Lesenswert?

Hallo,
ich möchte gerne ein Frequenz mit meinem AVR (Tiny2313) ausgeben,
benutze dazu den 16Bit-Timer, leider funktioniert das überhaupt nicht.
Währe echt super, wenn mir jemand weiterhelfen kann.

Programm:
#include <inttypes.h>
#include <avr/interrupt.h>
#include <avr/signal.h>
#include <avr/io.h>
#include <avr/sleep.h>

#ifndef F_CPU
   #define F_CPU 4000000           /* Oszillator-Frequenz in Hz */
#endif



/* Hauptprogramm */
/*****************/

int main(void)
{
   /* TIMER2 initialisieren */
   TCCR1A &= ~( (1 << COM1A1) | (1 << WGM11) | (1<<WGM10));
   TCCR1A |= (1 << COM1A0);
   TCCR1B  |= (1 << WGM12) | (1 << CS10);
   TCCR1B &= ~( (1 << CS12) | (1 << CS11));
   OCR1H = 0;
   OCR1L = 53;

   do
   {
   }while(1);
}

von ruepel (Gast)


Lesenswert?

a) Du muß noch den lokalen Timerinterrupt (in TIMSK, heißt OCIE2A oder
so ähnlich) sowie den globalen Interrupt "sei();" in main setzen.
b) Dann mußt ans Ende von main noch ein "return(0);", weil es eine
Funktion ist.
c) "do {}while(1);" kannst Du auch einfach durch "while(1);"
ersetzen.

Die ISR für den OC2 würde ich auch noch dazuschreiben.
Kenne die Register für den Tiny nicht auswendig, aber so ungefähr
heißen die.

von ruepel (Gast)


Lesenswert?

Falsch. Sorry. Vergiß Punkt a) und die Interruptgeschichte, da hab ich
mich von meinen Routinen verleiten lassen ;)

von Magnus Müller (Gast)


Lesenswert?

@ChristianS:

Du hast den Timer nicht wirklich gestartet... die Zeile

"TCCR1B &= ~( (1 << CS12) | (1 << CS11));"

ist nichts Anderes als

"TCCR1B = TCCR1B & 0xF9;" (0xF9 == 11111001 binär)

Nach dem Reset hat das Register TCCR1B den Wert 00000000 (0x00). Wenn
man diesen Wert mit 0xF9 und-verknüpft kommt wieder 00000000 raus ->
der Timer steht immer noch!

von ChristianS (Gast)


Lesenswert?

@Magnetus:
OK, und wie müsste es dann aussehen?

von Hannes L. (hannes)


Lesenswert?

vermutlich mit OR statt AND...

...

von Magnus Müller (Gast)


Lesenswert?

Ups.... eine Zeile darüber hast Du ja noch
   TCCR1B  |= (1 << WGM12) | (1 << CS10);
gehabt.... hab ich wohl noch übersehen schäm

wie wärs damit...

int main(void)
{
   /* TIMER2 initialisieren */
   TCCR1A &= 0x30; // Alle Parameter für Timer1 auf '0' setzen
   TCCR1A |= (1<<COM1A0); // Toggle On Compare Match
   TCCR1B &= 0xE0; // Alle Parameter für Timer1 auf '0' setzen
   TCCR1B |= ((1<<WGM12)|(1<<CS10)); // clk = fcpu
                                     // Clear Timer on Compare Match
   OCR1H = 0;   // OCR1 = 53 ergibt ca. 37KHz(!)
   OCR1L = 53;

   do
   {
   }while(1);
}

von Magnus Müller (Gast)


Lesenswert?

...kann es sein, dass Du dieses Signal auf einem Lautsprecher ausgeben
willst? 37KHz dürftest Du wahrscheinlich nicht mehr akustisch
wahrnehmen können ;)

von ChristianS (Gast)


Lesenswert?

@magnus:
ne, ich messe mit einem Oszi.
Es ging mir nur mal so Prinzipiel darum eine Frequenz auszugeben, die
unbeeinflusst von meinem Programm ist.
Werde nachher mal ausprobieren, ob es jetzt tut. Danke schon mal für
deine Hilfe!

von Hannes L. (hannes)


Lesenswert?


von ChristianS (Gast)


Lesenswert?

Was ich aber dann nicht verstehe, was habe ich denn da genau
falschgemacht?

von Christian S (Gast)


Lesenswert?

@HanneS:
habe mich bei meinem Programm an deinem Medodiegenerator orientiert
(ist mir sehr schwehr gefallen mich in deinen AssemblerCode
einzudenken), habe dann das Tutoriel G-CC verwendet

@Magnetus:
Habe es genau so gemacht wie du geschrieben hast,funktioniert leider
immer noch nicht

von Magnus Müller (Magnetus) (Gast)


Lesenswert?

@Christian S:

Kann es sein, dass du in deinem "echten" Programm noch irgendwas mit
dem anderen Timer anstellst (z.B. in einer ISR) und dort versehentlich
die Bits von Timer1 verbiegst?

Ich kann den Code momentan leider nicht auf meinem Rechner compilieren,
da mein WinAVR den ATtiny2313 noch nicht kennt. Muss wohl doch mal ein
Update machen grins

von Hannes L. (hannes)


Lesenswert?

> (ist mir sehr schwehr gefallen mich in deinen AssemblerCode
> einzudenken)

Und dabei ist dieser Code besonders gut kommentiert, da ich damit
BASCOMmer überzeugen wollte.

...

von Magnus Müller (Gast)


Lesenswert?

OH MANN... SIND WIR DOOOOOOF...!!!!

Wer (Datenblätter) lesen kann, ist klar im Vorteil ggg

ATtiny2313 Datasheet Page 93:

"However, the OC1x pin
direction (input or output) is still controlled by the Data Direction
Register (DDR) for the
port pin. The Data Direction Register bit for the OC1x pin (DDR_OC1x)
must be set as
output before the OC1x value is visible on the pin."

Sprich: es fehlt nur noch die Zeile

DDRB |= (1<<PB3);

Viel Spass noch ;)

von ChristianS (Gast)


Lesenswert?

Oh Mann, da bin auch absolut nicht drauf gekommen.
Vielen Dank für Deine Hilfe, hast mich echt weiter gebracht.

von ChristianS (Gast)


Lesenswert?

@HanneS:
Sorry, sollte keine Kritik an Dir sein, aber ich finde Assembler das
unübersichtlichste was es gibt (außer Maschienen-Code, das ist noch
unübersichtlicher) ;-)

von Hannes L. (hannes)


Lesenswert?

> aber ich finde Assembler das
> unübersichtlichste was es gibt

Das ist Ansichtsache. Ich halte ASM für besonders
einfach/übersichtlich, weil man die Übersicht über die Reccourcen
behält. Jeder AVR hat andere Features (Hardwareausstattung), da sind
Hochsprachenprogramme nur bedingt oder garnicht portabel, es sei denn,
man verzichtet auf die speziellen Features.

Aber wie gesagt, das ist Ansichtsache bzw. Gewohnheitssache.

...

von Christian S (Gast)


Lesenswert?

Es geeeeeeht!

Es funktioniert sogar mein ursprünglicher Code, lag echt nur an dem DDR

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.