Forum: Mikrocontroller und Digitale Elektronik Port mit 8MHz toggeln


von Mac Volt (Gast)


Lesenswert?

Ich brauche zum Testen der Geschwindigkeit von Optokopplern eine 
Schaltung die mir verschiedene Frequenzen macht:
8kHz
80kHz
800kHz
8MHz

Anstelle eines Quarzosszillators und eine paar TTL 7490 Teiler durch 10 
überlege ich das mal mit einem ATtiny25 zu machen.
Ich würde das gerne mal in C programmieren. Leider bin ich mit den 
Timer-Registern des ATtiny25 nicht recht schlau.
Wie kann ich das programmieren?
Habe dieses Blinkprogramm:
1
#include <avr/io.h>
2
#include <avr/interrupt.h>
3
4
#define Led_gelb_toggle PINB = (1 << PIN4);
5
6
void Port_init(void);
7
8
int main(void)
9
{
10
  Port_init();
11
  while(1)
12
  {
13
    /*
14
    Portleitungen abfragen
15
    Geschwindigkeit einstellen
16
    */
17
  }
18
}
19
//***********************************************
20
void Port_init(void)
21
{
22
  DDRB = (1 << DDB4);  // PB4 als Output der  Led_gelb
23
  PORTB =  0;
24
25
  TCCR1 = 0b00001110;  // Prescaler = CK / 8192
26
  TIMSK |= (1 << TOIE1);  // Timer1 Overflow Interrupt Enable
27
  sei();        // Enable Interrrupt
28
}
29
//***********************************************
30
ISR(TIMER1_OVF_vect)
31
{
32
  Led_gelb_toggle // Led an PB4 toggeln
33
}
34
//***********************************************
Das blinkt schön mit 2Hz.
Wie aber kann ich jetzt auf 8MHz kommen?
Ist da ein PIC eventuel die bessere Wahl?

von Michael U. (amiga)


Lesenswert?

Hallo,

der schnellste Umschalttakt per Timer im CTC-Mode ist Clock/2 mit 
Prescaler auf 1 und Comparewert auf 0. Dann den Ausgang festlegen und 
die Hardware das erledigen lassen.

Muß also mit 16MHz Takt laufen damit 8MHz rauskommen.
Bei einigen AVR kann man auch den Systemtakt auf einem Pin ausgeben 
lassen.

Gruß aus Berlin
Michael

von Helmut -. (dc3yc)


Lesenswert?

Welche Quarzfrequenz für den Takt benutzt denn dein ATtiny? Wenn es 
weniger als 8MHz sind, wie soll der da eine höhere Frequenz draus 
machen? Er braucht ja auch ein paar Takte, um die Befehle abzuarbeiten.

von CTC (Gast)


Lesenswert?

Entweder arbeitest du im CTC Modus oder mit der Harsware PWM.
Im 16 Bit CTC Modus berechnet sich die Frequenz zu:
f = (Taktfrequenz des µC)/(Prescaler*(1+OCR0A))

je nachdem wie du nun OCR0A einstellst kannst du deine Frequenz 
variieren und in der ISR des Pin toggeln. Aber nehmen wir mal an du 
stellst Prescaler auf 1 und OCR0A ebenfalls auf 1 --> f=8Mhz. Da du aber 
den Pin toggelst, hast du effektiv auch nur 4MHz. Ich weiss jetzt nicht 
ob ein Wert von OCR0A=0 zulässig ist, aber wenn ja, dann hast du deine 
8Mhz. Den Rest musst natürlich noch selber ausrechnen. Wie alles 
eingestellt wird steht im Datenblatt oder hier im Forum im GCC Tutorial.

von (prx) A. K. (prx)


Lesenswert?

Sachte, der Tiny25 hat einen Highspeed-Timer, mit dem auch bei langsamem 
CPU-Takt über eine PLL bis zu 32MHz Pinfrequenz fabrizieren kann.

von Mac Volt (Gast)


Lesenswert?

A. K. schrieb:
> Sachte, der Tiny25 hat einen Highspeed-Timer, mit dem auch bei langsamem
> CPU-Takt über eine PLL bis zu 32MHz Pinfrequenz fabrizieren kann.

Brauche mal ein paar Code-Schnipsel, drehe im Moment ziemlich am Rad.

Ächz keuch stöhn!

von Michael U. (amiga)


Lesenswert?

Hallo,

CTC schrieb:
> je nachdem wie du nun OCR0A einstellst kannst du deine Frequenz
> variieren und in der ISR des Pin toggeln. Aber nehmen wir mal an du
> stellst Prescaler auf 1 und OCR0A ebenfalls auf 1 --> f=8Mhz. Da du aber
> den Pin toggelst, hast du effektiv auch nur 4MHz. Ich weiss jetzt nicht
> ob ein Wert von OCR0A=0 zulässig ist, aber wenn ja, dann hast du deine
> 8Mhz. Den Rest musst natürlich noch selber ausrechnen. Wie alles
> eingestellt wird steht im Datenblatt oder hier im Forum im GCC Tutorial.

Ja, Comparewert 0 im CTC-Mode ist zulässig und erzeugt Clock/2.
Ist in den Datenblättern nicht überall direkt erwähnt, wenn man sich 
aber das Timingdiagramm des CTC-Mode genauer anschaut, sieht man, warum 
es so funktioniert.

Gruß aus Berlin
Michael

von (prx) A. K. (prx)


Angehängte Dateien:

Lesenswert?

Ich habe mit einem solchen Teil mal einen Taktgenerator gebaut, der über 
ein Poti und dem Kalibrierregister des Oszillators durchstimmbar ist, 
Code anbei.

von Mac Volt (Gast)


Lesenswert?

A. K. schrieb:
> Ich habe mit einem solchen Teil mal einen Taktgenerator gebaut, der über
> ein Poti und dem Kalibrierregister des Oszillators durchstimmbar ist,
> Code anbei.

Bin dabei das durchzuarbeiten. Vielen lieben Dank, ist ganz toll!

von Mac Volt (Gast)


Lesenswert?

Bin im Programm *32MHz.c* über dieses gestolpert:
1
loop_until_bit_is_set(PLLCSR, PLOCK);  // wait until PLL locked

@ A. K. (prx):
ob ich diese Funktion mal sehen dürfte?

von Karl H. (kbuchegg)


Lesenswert?

Ich greif A.K. mal vor (scheint schon weg zu sein)
1
#define loop_until_bit_is_set(p,b)   { while( !( (p) & (1<<(b)) ) ) ; }

einfach eine while-Schleife, die das Bit PLOCK im Register PLLCSR 
abfrägt und solange looped, solange es nicht gesetzt ist. Allerdings aus 
Makro ausgeführt, damit es keine Probleme bei der Parameterübergabe 
gibt.

Ohne das Makro hätte man einfach geschrieben
1
   while( ! ( PLLCSR & (1<<PLOCK) ) )
2
     ;

von Mac Volt (Gast)


Lesenswert?

Die Funktion:

loop_until_bit_is_set(bla, blub);

scheint recht universell zu sein, es werden anscheinend zwei Werte 
übergeben,
die Adresse des Registers und die Bitposition.
Finde es so etwas besser lesbar, die Übergabe der Parameter kostet 
natürlich Resourcen...
Habe mich nur gewundert, das die Funktion im Programm 32MHz.c nirgendwo 
deklariert noch definiert ist.
Würde diese Definition halt gern mal sehen.

von (prx) A. K. (prx)


Lesenswert?


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.