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


von Michi-S (Gast)


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
1
#ifndef __AVR_AT90CAN128__
2
#define __AVR_AT90CAN128__
3
#endif
4
5
#include <avr/interrupt.h>
6
#include <avr/io.h>
7
#include <stdio.h>
8
9
unsigned long test = 0;
10
int test2= 0;
11
12
int main( void )
13
{
14
    sei();
15
16
  DDRB = 0x07;
17
  PORTB = 0x02;
18
19
  //125Hz
20
//  OCR0A = 0x7D; // 0x7D = 124 & Prescaler 1024 => 125Hz  
21
//  TCCR0A =  (1<<CS02) | (1<<CS00) | (1<<WGM01);
22
//  TIMSK0 |= (1<<OCIE0A);
23
24
  //500kHz
25
  OCR0A = 0x1F; // 0x1F = 31 bei Prescaler 1 => 500kHz  
26
  TCCR0A =   (1<<CS00) | (1<<WGM01);  
27
  TIMSK0 |= (1<<OCIE0A); 
28
29
  //500kHz
30
//  OCR0A = 0x03; // 0x03 = 03 bei Prescaler 8 => 500kHz   
31
//  TCCR0A =   (1<<CS01) | (1<<WGM01);
32
//  TIMSK0 |= (1<<OCIE0A); 
33
34
  while(1)
35
  {
36
  }
37
38
}
39
40
ISR(TIMER0_COMP_vect){
41
  
42
  if (test == 500000){
43
    if(test2){
44
      test2 = 0;
45
       PORTB |= (1<<PIN2);      //Led an
46
    }else{
47
      test2 = 1;
48
      PORTB &= ~(1<<PIN2);
49
    }
50
    test = 0;
51
  }
52
  test++;
53
54
}


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

von avr (Gast)


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

von Michi-S (Gast)


Lesenswert?

uff du meinst er braucht länger für die Ausführung von
1
  if (test == 500000){
2
    if(test2){
3
      test2 = 0;
4
       PORTB |= (1<<PIN2);      //Led an
5
    }else{
6
      test2 = 1;
7
      PORTB &= ~(1<<PIN2);
8
    }
9
    test = 0;
10
  }
11
  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)

von avr (Gast)


Lesenswert?

Simulator im Studio, Datenblatt und *.lst-Datei sind möglich.

Was brauchst du den mit 500 hHz?

avr

von Michi-S (Gast)


Lesenswert?

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

von Peter D. (peda)


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

von Michi-S (Gast)


Lesenswert?

ja so hier der link,

http://www.screenkeys.com/downloads/LC16.2%20ScreenKey%20Datasheet.pdf

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

von Benedikt K. (benedikt)


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.

von avr (Gast)


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 ;)

von Michi-S (Gast)


Lesenswert?

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

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Michi-S schrieb:

>
1
> #ifndef __AVR_AT90CAN128__
2
> #define __AVR_AT90CAN128__
3
> #endif
4
>

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)?

von Michi-S (Gast)


Angehängte Dateien:

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?

von Benedikt K. (benedikt)


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.

von Kasperle (Gast)


Lesenswert?

Tackt -> Takt.

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.