Hallo Leute,
ich bin relativ neu im Mikrokontroller Bereich und bräuchte euere Hilfe.
Es geht darum eine Bitsequenz einzulesen.
Dazu habe ich mir überlegt, dass ganze über einen externen Interrupt zu
steuern. Sobald eine Flanke fällt, muss 250µs gewartet werden und dann
das Bit ausgelesen werden. Fällt wieder eine Flanke, muss wiederum 250µs
gewartet werden, und das Bit ausgelesen werden.
Mein Problem ist bisher nur, dass mir das GCC Tutorial nicht "verraten"
konnte, wie ich erst nach dem Interrupt einen Timer starte, und nach den
250µs wieder anhalte. Ich weiß bisher nur, wie ich einen Timer einfach
konfigurieren kann und laufen lassen kann. Aber wie ich ihn erst bei
einer fallenden Flanke starten kann, ist mir ein Rätzel. Ich hoffe
jemand hat einen Tipp für mich.
Danke,
mfG
David
Sehe ich das richtig im Datenblatt, dass das nicht möglich ist?
ich hab mir gerade überlegt, dass ich ja den Timer auf 0 zurücksetzen
kann, und dann abwarte bis etwas passiert. Aber Bits tatsächlich nur
auslese wenn die flanke gefallen ist. Solange kann der Timer ja machen
was er will, der beeinflusst ja eigentlich nichts. Sehe ich das richtig
so?
David schrieb:
> Sehe ich das richtig im Datenblatt, dass das nicht möglich ist?
Das könnten wir beantworten wenn wir wüssten in welches Datenblatt Du
schaust.
im Flankeninterrupt Timer aktivieren, sprich den Prescaler der Clock in
seinem TCCR ungleich 0 setzen, dann läuft der Timer.
Z.B. über einen Compare Match Interrupt kannste dann nach 250 us nen
weiteren Interrupt generieren lassen. In diesem setzt du den
Clockprescaler wieder auf 0 (Timer stopped). Wert im TCNT nicht
vergessen zurückzusetzen, da das nicht automatisch passiert, außer du
stellst CTC ein (geht nicht bei allen Timern).
So das war allgemein, für genauere Infos müssteste dann deine
Schaltung/verwendeten Prozessor mitteilen ;-)
Jetz wäre nur noch die Frage, wie ich genau 251,77µs bei 12Mhz
hinbekomme.
Aber dazu muss ich CTC verwenden.
Mit Prescaler 64 und Vergleichswert 47 bekomme ich aber 250,666667µs
hin, und das ist auserhalb von meinen 0,5% Toleranz die ich habe... :/
Zudem habe ich schon eine Lösung wie es auch ohne Starten und Stoppen
des Timers geht.
Ich lasse einfach einen Wert hochzählen (da ich auch ab und ein
vielfaches von 251,77µs brauche)
Danke
Nur aus Neugier.
Was ist denn das für eine Anwendung, bei der man eine Leitung exakt
251,77 µs nach einer Flanke abfragen muss? 1µs davor bzw. 1µs danach
liefert ein falsches Ergebnis.
Das vom Auftreten der Flanke bis zum Abarbeiten der ISR bis dann in der
ISR der Vorteiler für den Timer gesetzt wird auch Zeit vergeht hast du
berücksichtigt?
Dass von der Endemeldung des Timers bis zum tatsächlichen Auslesen des
Pins ebenfalls Zeit vergeht, hast du ebenfalls berücksichtigt?
Das sich dein ganzes Timing mit der nächsten Compilerversion (die ev.
beim Eintritt in die ISR ein Register mehr/weniger pusht) minimal
verschieben kann, hast du berücksichtigt?
Hallo,
es geht darum, eine Datenleitung für ein Display auszulesen.
Das Signal hat 32 Bit (also 32 verschiedene Leuchtelemente auf der
Displaytafel)
Das Signal baut sich so auf.
Erst wird ca. 11ms eine Pause abgewartet (Signal High). Fällt die
Flanke, kommt nach 241,77µs das erste bit. Dann muss man warten bis das
Signal nach ein paar µs wieder auf High geht und erneut fällt. Dann
wiederum muss 241,77µs auf das nächste Bit gewartet werden, etc.
Hab den Code soweit fertig, nur was ich nicht verstehe ist:
Wenn eine Fallende Flanke da ist, will ich den Timer zurücksetzen.
Ich habe angenommen das ich einfach OCR2 = 1 sagen kann, und er dann
egal bei welchem Wert er gerade ist, ein Interrupt macht und im Zähler
selbst setze ich ihn wieder auf 61. Das hat sich aber als völliger
Blödsinn rausgestellt.
Ich möchte nur, das bei einer Flanke, der Timer wieder bei 0 zu zählen
anfängt (also sich resettet).
Hier habe ich mal den Code soweit:
1
volatileuint8_tpause;
2
volatileuint8_tflanke;
3
volatileuint8_tread;
4
volatileuint8_tcount;
5
6
///INT0 Interrupt
7
ISR(INT0_vect)
8
{
9
flanke=1;
10
pause=0;
11
count=0;
12
///Timer mit Flanke syncronisieren
13
OCR2=1;
14
}
15
16
17
///252µs Timer
18
ISR(TIMER2_COMP_vect)
19
{
20
///Timer ca 252µs laufen lassen +1 vom INT0 Interrupt
21
OCR2=61;
22
count++;
23
if(count>10)
24
{
25
count=9;
26
}
27
28
}
29
30
31
///Pause Timer
32
ISR(TIMER1_COMPA_vect)
33
{
34
pause++;
35
if(pause>250){pause=249;}
36
37
}
38
39
uint32_tlesen(void){
40
41
uint8_ti;
42
uint32_tdaten=0x00;
43
44
45
for(i=1;i<33;i++)
46
{
47
///Solange keine Flanke, warten
48
while(flanke!=1);
49
///Wenn Flanke erkannt, auf 0 zurücksetzen
50
if(flanke==1)
51
{
52
flanke=0;
53
}
54
///Warten bis Timer 252µs gezählt hat
55
while(count!=1);
56
///wenn 252µs erreicht
57
if(count==1)
58
{
59
///Pin auf High, Bit setzen, sonst auf 0 lassen.
60
if(PIND&(1<<1))
61
{
62
daten|=(1<<i);
63
64
}
65
}
66
67
}
68
///Daten zurückgeben
69
returndaten;
70
71
}
72
73
intmain(void)
74
{
75
uint32_tdisplay;
76
charbuffer[31];
77
pause=0;
78
flanke=0;
79
read=0;
80
81
TCCR1B=(1<<CS11)|(1<<WGM12);///Prescaler auf 1024 und CTC
82
OCR1A=124;///Comparematch 86 -> 125 µs, also 88 mal für pause
83
84
85
TCCR2=(1<<CS20)|(1<<CS21)|(1<<WGM21);///Prescaler 32 Takt 8Mhz und CTC
David schrieb:
> Das Signal hat 32 Bit (also 32 verschiedene Leuchtelemente auf der> Displaytafel)>> Das Signal baut sich so auf.>> Erst wird ca. 11ms eine Pause abgewartet (Signal High). Fällt die> Flanke, kommt nach 241,77µs das erste bit. Dann muss man warten bis das> Signal nach ein paar µs wieder auf High geht und erneut fällt. Dann> wiederum muss 241,77µs auf das nächste Bit gewartet werden, etc.
Sei mir nicht böse und wahrscheinlich kannst du nichts dafür.
Aber wer denkt sich denn so einen Schwachsinn aus?
In diesem Protokoll wird haufenwweise gewartet. Zuerst 11ms, dann 241µs.
Nur in der 'heißen' Phase, wenn es darum geht den Zustand zu samplen,
muss alles plötzlich auf 1µs genau sein?
Demjenigen der sich das ausgedacht hat (wenn du die
Protokollbeschreibung richtig hast), sollte man mit einem nassen Fetzen
erschlagen. Der ist nicht zufällig BWL-er?
Was heißt den da haufenweiße warten????
Das ist ein ganz normales Protokoll???
Da is ne Pause, und danach kommen die Daten. Und damit man weiß welches
Bit kommt, wartet man eine Flanke ab, und dann nach den paar µs kommt
dann das Bit?
Das is doch absolut simpel.
und ob es auf eine 1µs wirklich ankommt weiß ich nicht. Da steht ne
Tabelle, bei welcher Zeit welches Bit kommt, und obendrüber +- 0.5 %
Und daran will ich mich nur halten.
Gruß
Zusätzlich habe ich nen Fehler gefunden, und zwar wird der
Interrupthandeler vom INT0 solange aufgerufen, solang nach der
gefallenen Flanke, das Signal auf low bleibt. Konnte ich aber auch nur
mim Logicanalyzer feststellen...
>Zusätzlich habe ich nen Fehler gefunden, und zwar wird der>Interrupthandeler vom INT0 solange aufgerufen, solang nach der>gefallenen Flanke, das Signal auf low bleibt. Konnte ich aber auch nur>mim Logicanalyzer feststellen...
Manche Interrupt-Flags muss man von Hand zurücksetzen...
Hey,
Also es funktionier alles, ich hab einfach jedesmal die Timer usw.
gestoppt, so dass sie sich nicht gegenseitig beeinflussen.
Jetz läuft alles 1 a!