mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Timer mit us Auflösung


Autor: Schnurzelpurzel (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich habe einen ATtiny25 und brauche einen Timer mit us Auflösung bei 
einer Verzögerungszeit von 1 Minute.
D.h. meine Verzögerungszeit ist ca 60000000us plus minus ein paar us
Dafür brauche ich doch einen 32 Bit Timer?

Was kann man machen?

Autor: S. T. (cmdrkeen)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
mit dem 16bit timer eine 16bit zahl hochzählen?

Autor: Falk Brunner (falk)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@  Schnurzelpurzel (Gast)

>Ich habe einen ATtiny25 und brauche einen Timer mit us Auflösung bei
>einer Verzögerungszeit von 1 Minute.

Was soll das werden?

>D.h. meine Verzögerungszeit ist ca 60000000us plus minus ein paar us
>Dafür brauche ich doch einen 32 Bit Timer?

Jain. Das kann man aber aufteilen in 16 Bit Hardwarezähler und 16 Bit 
Softwarezähler.

MFG
Falk

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Schnurzelpurzel schrieb:
> D.h. meine Verzögerungszeit ist ca 60000000us plus minus ein paar us

Dann hast Du bestimmt auch nen temperaturstabilen hochgenauen 
kalibrierten Quarzgenerator (oder Atomuhr) als Takt angeschlossen.
Ansonsten kannst Du nämlich Deine µs in der Pfeife rauchen.

Das Erweitern auf 32Bit ist dagenen ein leichtes:

Beitrag "AVR Timer mit 32 Bit"


Peter

Autor: Manu (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Da dies gerade verlinkt wurde, eine kleine Frage hierzu
u32 get_ticks( void )        // read T2 as 32 bit timer
{
  u32 val;
  u8 tifr;

  cli();
  val = t2_soft + TCNT2;
  tifr = TIFR;          // read interrupt flags
  sei();
  if( (tifr & 1<<TOV2) && !(val & 0x80) ) // overflow prior reading TCNT2 ?
    val += 256;          // then add overflow

  return val;
}

In dieser Zeile:
  if( (tifr & 1<<TOV2) && !(val & 0x80) ) // overflow prior reading TCNT2 ?
    val += 256;          // then add overflow
wird ja geprüft, ob ein OVF ansteht, wenn ja, und das 7 byte 0 ist, also 
der Wert klein und es somit zu dieser Messung gehört, addiert. Das ist 
auch richtig.
Aber, das Flag zum Ausführen des OVF Int. wird ja nicht gelöscht. Nach 
verlassen der Funktion get_ticks wird dann doch der OVF Int. ausgeführt 
und somit nochmal dazu gezählt.
Müsste man nicht das Flag löschen, wenn man das bereits addiert hat, 
also so:
  if( (tifr & 1<<TOV2) && !(val & 0x80) ) // overflow prior reading TCNT2 ?
    val += 256;          // then add overflow
    TIFR = (1 << TOV2);                   // Flag löschen (Schreiben einer 1)

Wenn ich falsch liege, erklärt mir bitte wieso :)

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Manu schrieb:
> Aber, das Flag zum Ausführen des OVF Int. wird ja nicht gelöscht. Nach
> verlassen der Funktion get_ticks wird dann doch der OVF Int. ausgeführt
> und somit nochmal dazu gezählt.

Du hast den Wert ausgelesen und dann wird da auch nichts mehr 
dazugezählt.
Eine Variable ändert sich ja nicht von selbst.

Aber der Interrupt muß auch seinen Counter mitzählen, sonst stimmt ja 
die nächste Auslesung nicht mehr.

Die Auslesefunktion und der Interrupt arbeiten auf 2 verschiedenen 
Variablen und daher müssen beide den Überlauf behandeln, sonst gibts 
Ärger.
Natürlich setzt nur der Interrupt auch das Flag zurück.


Peter

Autor: Manu (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Danke Peter, klar. Ich hatte wohl Tomaten auf den Augen, sind ja 2 
unterschiedliche Variablen.

Autor: Schnurzelpurzel (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Peter Dannegger schrieb:
> Das Erweitern auf 32Bit ist dagenen ein leichtes:
>
> Beitrag "AVR Timer mit 32 Bit"

Hallo Peter,
vielen Dank, habe ich mir angesehen, ist toll.
Wenn ich das richtig verstehe, kann der µC damit nachsehen *wie spät es 
ist*

Was ich brauche ist eine Routine um exakte Zeitverzögerungen zwischen 
setzen und löschen einer Portleitung zu haben.

>Dann hast Du bestimmt auch nen temperaturstabilen hochgenauen
>kalibrierten Quarzgenerator (oder Atomuhr) als Takt angeschlossen.
>Ansonsten kannst Du nämlich Deine µs in der Pfeife rauchen.

Ich bekomme ein 10MHz-Rubidium-Normal das der Vater von einem Freund 
hat, als Dauerleihgabe. Wir bauen uns ein 10MHz Verteilnetzwerk im 
ganzen Haus. Hihi  :-)

Autor: Falk Brunner (falk)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@  Schnurzelpurzel (Gast)

>Was ich brauche ist eine Routine um exakte Zeitverzögerungen zwischen
>setzen und löschen einer Portleitung zu haben.

Sag mal lieber, was das insgesamt werden soll.

Wenn es denn wirklich auf den Takt/die µs genau sein soll, muss man ggf. 
in Assembler was machen. Oder einen CPLD nutzen.

MFG
Falk

Autor: Schnurzelpurzel (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>Sag mal lieber, was das insgesamt werden soll.

>Wenn es denn wirklich auf den Takt/die µs genau sein soll, muss man ggf.
>in Assembler was machen. Oder einen CPLD nutzen.

Insgesamt soll es eine art TTL-Impulsgenerator werden, wo man die 
High-und Low-Zeit in 1-us Schrittweite getrennt einstellen kann.
Einstellbereich ist von 1ms bis 100s in 1us Schrittweite.

Was ich brauche ist eine Routine die eine Verzögerung macht.
Es ist wahrscheinlich blöd während einer Verzögerung zu warten und die 
CPU ist mit nur mit Zählen  beschäftigt, aber da die CPU sowieso nix 
anderes zu tun hat...

Die folgende Routine ist suboptimal, da je nachdem was sonst im 
Programm steht, der Compiler die unterschiedlich optimiert
//***********************************************
void my_Delay(volatile unsigned long int Zeit)
{
  for(;Zeit>0;Zeit--);
}
//***********************************************

Autor: Falk Brunner (falk)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Schnurzelpurzel (Gast)

>Insgesamt soll es eine art TTL-Impulsgenerator werden, wo man die
>High-und Low-Zeit in 1-us Schrittweite getrennt einstellen kann.
>Einstellbereich ist von 1ms bis 100s in 1us Schrittweite.

Willst du Agilent und TEK Konkurrenz machen? Da musst du aber sehr früh 
aufstehen ;-)

>Was ich brauche ist eine Routine die eine Verzögerung macht.

Gibt es, _delay_us() und delay_ms(). Das reicht aber nicht, weil das 
Problem etwas kniffliger ist.
Mit ASM und ne guten Idee sollte man das aber hinbekommen.
Ich würde einen CPLD nehmen.

>Die folgende Routine ist suboptimal, da je nachdem was sonst im
>Programm steht, der Compiler die unterschiedlich optimiert

>//***********************************************
>void my_Delay(volatile unsigned long int Zeit)
>{
>  for(;Zeit>0;Zeit--);
>}
>//***********************************************

Wenn du µs genauses Timing willst, ist C nicht wirklich das Mittel der 
Wahl. Und da der AVR sowieso nix weiter macht als LOW, Warten, High, 
Warten, ist ASM sehr zu empfehlen.

MFG
Falk

Autor: Peter (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Falk Brunner schrieb:
> Wenn du µs genauses Timing willst, ist C nicht wirklich das Mittel der
> Wahl. Und da der AVR sowieso nix weiter macht als LOW, Warten, High,
> Warten, ist ASM sehr zu empfehlen.

wenn man es über den Timer macht, sollte der overhead durch C nicht 
weiter stören. Das mit es mit C in so einer schleife nicht hinbekommt 
ist klar.

Autor: Schnurzelpurzel (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Falk Brunner schrieb:
> Willst du Agilent und TEK Konkurrenz machen? Da musst du aber sehr früh
> aufstehen ;-)

Nein nein, es soll nur ein kleines Ticky-tool sein. Überhaupt keine 
Konkurrenz zu Agilent.
Ist mit TEK Tektronix gemeint?


>Wenn du µs genauses Timing willst, ist C nicht wirklich das Mittel der
>Wahl. Und da der AVR sowieso nix weiter macht als LOW, Warten, High,
>Warten, ist ASM sehr zu empfehlen.

Naja, etwas mehr schon:
while(1)
{
   my_delay( Switch_board(0) );
   Port_an;
   my_delay( Switch_board(1) );
   Port_aus;
}
Ist mit ASM Assembler gemeint?
Wenn ja, kann man Assembler nicht auch in C einbinden?
Wie kann ich denn
//***********************************************
void my_Delay(volatile unsigned long int Zeit)
{
  for(;Zeit>0;Zeit--);
}
//***********************************************
in Assembler schreiben und dieser Routine auch noch eine
unsigned long int variable übergeben?

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.