Forum: Mikrocontroller und Digitale Elektronik Hilfe! Timer!


von mr-unbekannt (Gast)


Lesenswert?

Hallo!

Gestern und heute habe ich nur verbracht, um gute Tutorials für Timer zu 
finden (In C). Habe aber nichts gefunden.

Mein Projekt wäre, mit einem Tiny2313 (4Mhz) in C ein Programm zu 
schreiben, das Frequenzen mithilfe des Timers ausgibt.

Ich verstehe überhaupt nicht wie das Funktionieren soll?!?

muss ich den Prescaler auf 1024 stellen?
und was muss ich vorladen?

bitte um Hilfe
DAnke

von let (Gast)


Lesenswert?

Was für Frequenzen? Rechteck? Sinus? In welchem Frequenzbereich?

 - Michael

von guru (Gast)


Lesenswert?

Für Rechteck, also PWM, kannst du ja die PWM Funktionen des Timers 
nutzen.

Um einfach nur einen Takt zubekommen, den du weiterverarbeiten kannst, 
Prescaler einstellen und Timeroverflow Interrupt aktivieren bzw. 
generell die Interrupts. Was du mit vorladen meinst, ist glaube ich das 
beschreiben des TCNT0, damit der Zähler mit weniger Schritten als 256 
überläuft, also der Takt schneller wird.

von mr-unbekannt (Gast)


Lesenswert?

Also, das Signal braucht nur ein Rechteck sein (Ein Pin soll toggeln)

Die Frequenzen sollen im Hörbereich sein, ich hänge dann einfach einen 
Lautsprechen an den Ausgang.

vielen dank

von fnah (Gast)


Lesenswert?

>Gestern und heute habe ich nur verbracht, um gute Tutorials für Timer zu
>finden (In C). Habe aber nichts gefunden.
>...
>muss ich den Prescaler auf 1024 stellen?
>und was muss ich vorladen?

timer haben mit C rein gar nichts zu tun. die informationen, die du 
suchst, findest du im datenblatt zum controller.

wie man das dann in C umsetzt findet sich hier:
http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial#Programmieren_mit_Interrupts

von Karl H. (kbuchegg)


Lesenswert?

fnah wrote:
>>Gestern und heute habe ich nur verbracht, um gute Tutorials für Timer zu
>>finden (In C). Habe aber nichts gefunden.
>>...
>>muss ich den Prescaler auf 1024 stellen?
>>und was muss ich vorladen?
>
> timer haben mit C rein gar nichts zu tun.

Und da das so ist, ist auch ein Blick hier rein hilfreich
http://www.mikrocontroller.net/articles/AVR-Tutorial:_Timer#Wie_schnell_schaltet_denn_jetzt_der_Port.3F


von let (Gast)


Lesenswert?

Dann siehe dir mal insbesondere den Abschnitt zum
'Output compare match' (Timer 1) an.

Kurz: Timer1 in den CTC Modus, Compare Output mode auf
'Toggle OC1A', gewünschten Wert für die Ausgabefrequenz
in das Compare Match Register (OCR1A) und den Prescaler auf 1.

Nur den Lautsprecher bitte nicht ohne Vorwiderstand an den
Controller.

 - Michael

von mr-unbekannt (Gast)


Lesenswert?

Und wie würde das diskret lauten?

ich versuchs mal:
1
#ifndef F_CPU
2
#define F_CPU 4000000UL     /* Quarz mit 4 Mhz  */
3
#endif
4
#include <util/delay.h> // Wartefunktionen
5
#include <avr/io.h>     // IO Definitionen
6
7
int main(void)
8
{
9
10
DDRD = 0x00;
11
DDRB = 0xFF;         
12
PORTD = 0xFF;
13
TCCR1A = (1<<COM1A0) | (1<<CS00);   // Toggeln und Prescaler auf 1
14
OCR1A = 0x125;            // im Dezimalen 293 Hz
15
16
17
   
18
while(1)
19
  {   
20
  
21
  }
22
return 0; 
23
}

stimmt das?

Danke

von johnny.m (Gast)


Lesenswert?

> TCCR1A = (1<<COM1A0) | (1<<CS00);   // Toggeln und Prescaler auf 1
> OCR1A = 0x125;            // im Dezimalen 293 Hz
Wie kommst Du da auf 293 Hz??? 4 MHz / 293 = 13652 Hz! Das ist ein 
bisschen mehr als das was Du vermutlich willst...

von Karl H. (kbuchegg)


Lesenswert?

johnny.m wrote:
>> TCCR1A = (1<<COM1A0) | (1<<CS00);   // Toggeln und Prescaler auf 1
>> OCR1A = 0x125;            // im Dezimalen 293 Hz
> Wie kommst Du da auf 293 Hz??? 4 MHz / 293 = 13652 Hz! Das ist ein
> bisschen mehr als das was Du vermutlich willst...

Genau genommen

  4000000  293  2 = 6825 Hz

/ 2 deshalb, weil der den Pin ja toggelt und für einen kompletten
Wellenzug sind 2 Toggle-Vorgänge notwendig.

6kHz sind aber immer noch ziemlich hoch.

Aber das ganze Setup des Times stimmt nicht. Was da
programmiert wurde, ist ein Timer der mit vollen
4 Mhz jeweils bis 65536 zählt. Und wenn der Timerwert
den Wert 293 erreicht hat, dann wird das OC1A Bit
getoggelt.

D.h. das Bit toggeln wird mit einer Frequenz von
knapp 30Hz durchgeführt.

4000000  65536  2 = 30.5

Noch mal: Der CTC Modus ist dafür bestens geeignet.
Nur muss man den aber auch einschalten.

von johnny.m (Gast)


Lesenswert?

@Karl Heinz:
Richtig. Aber da er den Timer nicht im CTC-Modus betreibt, stimmt auch 
das nicht. So wie es oben konfiguriert ist, tritt das Compare-Ereignis 
mit 61,04 Hz auf, da der Timer beim Compare-Ereignis nicht zurückgesetzt 
wird... Hatte ich grad übersehen.

@mr-unbekannt:
Du musst, wenn Du ein vernünftiges Signal haben willst, schon den 
CTC-Modus des Timers aktivieren, indem Du die WGM-Bits in den 
Steuerregistern entsprechend setzt.

von Karl H. (kbuchegg)


Lesenswert?

johnny.m wrote:
> @Karl Heinz:
> Richtig. Aber da er den Timer nicht im CTC-Modus betreibt, stimmt auch
> das nicht. So wie es oben konfiguriert ist, tritt das Compare-Ereignis
> mit 61,04 Hz auf, da der Timer beim Compare-Ereignis nicht zurückgesetzt
> wird... Hatte ich grad übersehen.
>
> @mr-unbekannt:
> Du musst, wenn Du ein vernünftiges Signal haben willst, schon den
> CTC-Modus des Timers aktivieren, indem Du die WGM-Bits in den
> Steuerregistern entsprechend setzt.

Da haben sich unsere Korrekturen überschnitten :-)

Ich hab kein Datenblatt vom Tiny2313 da:
Den OC1A Pin auf Ausgang setzen nicht vergessen.
Im Datenblatt nachsehen, welcher Pin das ist.

von mr-unbekannt (Gast)


Lesenswert?

ich habe ja alle PORTB auf Ausgang gesetzt:

so der (hoffentlich richtige) code:
1
DDRD = 0x00;
2
DDRB = 0xFF;         
3
PORTD = 0xFF;
4
TCCR1A = (1<<WGM12) | (1<<COM1A0) | (1<<CS00); // CTC-Mode + Toggeln und Prescaler auf 1
5
OCR1A = 0x1AAA;      // im Dezimalen 6826

danke

von johnny.m (Gast)


Lesenswert?

> TCCR1A = (1<<WGM12) | (1<<COM1A0) | (1<<CS00);
Das stimmt so nicht! WGM12 ist im TCCR1B...

von Branko Golubovic (Gast)


Lesenswert?

johnny.m wrote:
> TCCR1A = (1<<COM1A0) | (1<<CS00);   // Toggeln und Prescaler auf 1
? CS00 ist Prescaler-bit für Timer0 und befindet sich nicht ins TCCR1A.
TCCR1A hat:
Bit7    Bit6   Bit5   Bit4  - - Bit1   Bit0
COM1A1 COM1A0 COM1B1 COM1B0 – – WGM11 WGM10
und
TCCR1B:
Bit7   Bit6 -  Bit4 Bit3  Bit2 Bit1 Bit0
ICNC1 ICES1 – WGM13 WGM12 CS12 CS11 CS10

Also richtig ist:
1
TCCR1A = (1<<COM1A0);  // Toggeln(Datenblatt, Seite 108)
2
TCCR1B = (1<<CS10);    //Timer1 Prescaler auf 1 (Datenblatt, Seite 111)
3
// WGM Modus setzen
4
//z.B. Mode-10,PWM Phase-Correct (Datenblatt, Seite 110)
5
TCCR1B|=(1<<WGM13);
6
TCCR1A|=(1<<WGM11);
7
// ICR1 Register mit TOP-Wert laden
8
ICR1=2000; //TOP-Wert
9
// PWM-Frequenz=F_CPU/(2*Prescaler*TOP)->1000Hz(Datenblatt Seite 103)
10
OC1A=1000; // PWM-50-50%

Branko

von johnny.m (Gast)


Lesenswert?

Upps, da hatte ich auch nicht richtig hingesehen... Danke, Branko!

von mr-unbekannt (Gast)


Lesenswert?

So, danke für die Antworten!

Ich will eigentlich nur den OCR1A Ausgang (PB3) toggeln lassen, dass ich 
eine Frequenz von 293 Hz bekomme.

Ich gehe in den CTC -Mode, Lade OCR1A0 mit dem Wert 6826d vor, daraus 
ergibt sich die Frequenz = F_CPU/(2*Prescaler*OCR1A0)

So, der Code
1
int main(void)
2
{
3
4
DDRD = 0x00;
5
DDRB = 0xFF;         
6
PORTD = 0xFF;
7
TCCR1A |= (1<<COM1A0);  // Toggeln(Datenblatt, Seite 108)
8
TCCR1B |= (1<<CS10);    // Timer1 Prescaler auf 1 (Datenblatt, Seite 111)
9
TCCR1B |= (1<<WGM12);   // CTC Modus setzen
10
OCR1A = 6826;        // Frequenz=F_CPU/(2*Prescaler*OCR1A)
11
12
   
13
while(1)
14
  {   
15
  
16
  }
17
return 0; 
18
}

der code muss aber stimmen ;-)

danke

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.