www.mikrocontroller.net

Forum: Compiler & IDEs Timer läuft seht ungenau bei hohen Tacktraten


Autor: Michi-S (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

ich brauche einen 500kHz Tackt um damit ein Display anzusteuern.

Nachdem das ganze nicht funktioniert hat, hab ich das Programm mal 
zerpflückt (restliche Programmteile entfernt) und etwas komisches beim 
Timer festgestellt.


Ich hab nen At90CAN128 mit 16MHz
#ifndef __AVR_AT90CAN128__
#define __AVR_AT90CAN128__
#endif

#include <avr/interrupt.h>
#include <avr/io.h>
#include <stdio.h>

unsigned long test = 0;
int test2= 0;

int main( void )
{
    sei();

  DDRB = 0x07;
  PORTB = 0x02;

  //125Hz
//  OCR0A = 0x7D; // 0x7D = 124 & Prescaler 1024 => 125Hz  
//  TCCR0A =  (1<<CS02) | (1<<CS00) | (1<<WGM01);
//  TIMSK0 |= (1<<OCIE0A);

  //500kHz
  OCR0A = 0x1F; // 0x1F = 31 bei Prescaler 1 => 500kHz  
  TCCR0A =   (1<<CS00) | (1<<WGM01);  
  TIMSK0 |= (1<<OCIE0A); 

  //500kHz
//  OCR0A = 0x03; // 0x03 = 03 bei Prescaler 8 => 500kHz   
//  TCCR0A =   (1<<CS01) | (1<<WGM01);
//  TIMSK0 |= (1<<OCIE0A); 

  while(1)
  {
  }

}

ISR(TIMER0_COMP_vect){
  
  if (test == 500000){
    if(test2){
      test2 = 0;
       PORTB |= (1<<PIN2);      //Led an
    }else{
      test2 = 1;
      PORTB &= ~(1<<PIN2);
    }
    test = 0;
  }
  test++;

}


verwende ich ihn mit 125Hz und lasse test nur bis 125 zählen, dann 
leuchted die LED, für eine Sekunde - so weit so gut.

stelle ich aber wie im Code auf 500kHz dann leuchted sie fast 3 sek.

kann mir das jemand erklären?

ach ja welche der beiden 500kHz varianten würdet ihr bevorzugen (ändert 
nichts an meinem Problem)?

Danke,
Michi

Autor: avr (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Dein Interrupt bei 500 kHz soll alle 32 Taktzyklen aufgerufen
werden. Ist auch so eingestellt.

Aber wieviele Taktzyklen braucht die Interruprroutine?

Schreib doch mal die Antwort auf meine Frage und du hast die
Antwort auf deine Frage!

avr

Autor: Michi-S (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
uff du meinst er braucht länger für die Ausführung von
  if (test == 500000){
    if(test2){
      test2 = 0;
       PORTB |= (1<<PIN2);      //Led an
    }else{
      test2 = 1;
      PORTB &= ~(1<<PIN2);
    }
    test = 0;
  }
  test++;

länger als 32 taktzyklen...

hmmm, dann wird des echt schwer, da was ordentliches auf die beine zu 
stellen....

wie finde ich denn dann raus, welche operationen wieviele tacktzyklen 
brauchen? (hab leider nicht viel ahnung von Assembler)

Autor: avr (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Simulator im Studio, Datenblatt und *.lst-Datei sind möglich.

Was brauchst du den mit 500 hHz?

avr

Autor: Michi-S (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ein display ansteuern, dazu reichen mir auch ca. 65kHz, aber der code 
ist auch länger...

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Michi-S schrieb:
> ein display ansteuern, dazu reichen mir auch ca. 65kHz, aber der code
> ist auch länger...

Es wäre sinnvoller, mal einen Link auf das Datenblatt des LCD zu posten.

Ein LCD ohne eigenen Controller anzusteuern, ist schon recht tricky, da 
brauchts Assembler. In der Codesammlung ist was dazu.


Peter

Autor: Michi-S (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ja so hier der link,

http://www.screenkeys.com/downloads/LC16.2%20Scree...

wenn ich es mit kleinster Tacktrate (50kHz) betreiben will, muss ich 
aber alle 25kHz den timer auslösen lassen, weil ich ja die clock leitung 
togglen muss. mir bleiben also 160 takte um das bit um das jeweilige bit 
zu setzen

Autor: Benedikt K. (benedikt) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Die Ansteuerung ist ja echt bescheuert...
Du könntest dir die Arbeit mit einem Trick aber stark vereinfachen:
Den Takt erzeugst du mit einem Timer im CTC Modus.
Die Daten werden synchron zu dem Takt übertragen, aber davon abgesehen 
in dem Stil wie normale UART Daten. Falls du also noch den UART frei 
hast, stell den so ein, dass er den externen Takt verwendet, und sende 
einfach die Daten per UART, das erspart einiges an Rechenleistung.

Autor: avr (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Michi-S,

da hilft nur das Datenblatt (aber das richtig).

Es ist eine normale synchrone serielle Übertragung.

Startbit, 8 Datenbit, Parity, 2xStop (Datenblatt Figur 17.4)

Die Clockeinstellung und Flanke ist auch kein Problem
Table 17.1 und Abschnitt 17.4.4

Dann läuft es alles in Hardware mit UDRx als Daten.

gruß avr

Hoffe, du hast noch eine der beiden USART frei ;)

Autor: Michi-S (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ahh das hört sich doch vielversprechend an, dann werd ich da mal schaun 
ob ich das hinbekomm

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Michi-S schrieb:

>
> #ifndef __AVR_AT90CAN128__
> #define __AVR_AT90CAN128__
> #endif
> 

Wenn du sowas brauchst, stimmt bei dir irgendwas nicht.  Kein Wunder,
dass der Rest dann nicht funktioniert.

Hast du überall -mmcu=at90can128 in deinem Makefile drin (beim
Compilieren und beim Linken)?

Autor: Michi-S (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
FERTIG!!!

@dl8dtl
jetzt wo dus sagst, keine Ahnung warum das da noch drin ist, kommt davon 
wenn man alten Code schnell noch mal hernimmt zum testen ^^

aber -mmcu=at90can128 ist natürlich überall drin.

@benedikt
habs genau so gemacht wie du gesagt hast, hat priema funktioniert! 
MERCI!
Werd aber bei gelegenheit noch mal probieren ob ich den Tackt nicht 
irgendwie schöner hinbekomme (würde des auch mit der Baudrate Ausgabe 
auf XCK funktionieren oder ist dann nur beim senden Tackt da?)

Ich hab das funktionierende Programm mal in den Anhang, falls noch 
jemand auf die Idee kommt sowas zu machen.

Nur schade dass man nen uart braucht, hätte gerne die dinger mit nem 
kleinen atmel (Tiny oder so) als Treiber verwendet. So dass man dem 
Treiber entweder Daten seriell (uart dens nicht mehr gibt) oder per I2C 
schickt und der die Daten dann an die einzelnen Taster verteilt. So hätt 
ich das ganze vom PC und vom uC einfach steuern können.

Was ist denn der kleinste/billigste Atmel mit 2 Uarts?

Autor: Benedikt K. (benedikt) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Michi-S schrieb:

> Werd aber bei gelegenheit noch mal probieren ob ich den Tackt nicht
> irgendwie schöner hinbekomme (würde des auch mit der Baudrate Ausgabe
> auf XCK funktionieren oder ist dann nur beim senden Tackt da?)

Musst du mal ausprobieren. Dem Diagramm im Datenblatt nach könnte es so 
sein, aber eine echte Bestätigung habe ich beim Überfliegen des Textes 
nicht finden können.

Autor: Kasperle (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Tackt -> Takt.

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.