Forum: Mikrocontroller und Digitale Elektronik Flankenerkennung mit Attiny


von Wolfran (Gast)


Lesenswert?

Hallo Zusammen,
ich habe folgendes Problem. Vielleicht kann mir ja jemand helfen.
Ich möchte mit einem AtTINY2313 auf internem RC-Oszillator (Takt 
8MHz)auf 8 * IO-Kanälen Impulse erkennen.
Hier das Datenblatt:
http://www.atmel.com/dyn/resources/prod_documents/doc2543.PDF
Mein Problem ist, dass die Impulse <=0.5us lang sind.
Wenn ich jetzt einen 8-Bit Port in einer Schleife einlese, dauert das 
schon ca 3 us, mit dem Effekt ich erkenne nicht alle eingehenden Pulse?
Kann man auf 8 IOs eine Art Flankenerkennung o.ä. auf dem AVR Typ 
realisieren ?
Was für Möglichkeiten habe ich ?
Vielen Dank

von Floh (Gast)


Lesenswert?

Wolfran schrieb:
> Was für Möglichkeiten habe ich ?

1. schneller takten
2. Assemblerprogramm, dafür reichen dann 8 MHz
3. externe Monoflops (z.B. ne555), um die Impulsdauer zu verlängern
4. externe Kondensatoren und Dioden

  In ---|>|----o----- uC-Pin
               |
              ---
              --- C
               |
             --o---

Bei Flanke wird C geladen. Nun hat der uC Zeit fürs Erkennen. Zum 
Löschen zieht der uC den Pin kurz auf Low (Ausgang).

Allerdings beschreib doch mal was du vor hast, vlt bietet sich noch was 
besseres. :-)

von Spess53 (Gast)


Lesenswert?

Hi

>Was für Möglichkeiten habe ich ?

Pin-Change-Interrupt.

MfG Spess

von Wolfram (Gast)


Lesenswert?

Hallo Floh u.a.,
Floh schrieb:
> Allerdings beschreib doch mal was du vor hast, vlt bietet sich noch was
> besseres. :-)
OK ich empfange aus einer externen Bus-Empfängerschaltung Pulse, wenn 
neue Daten anliegen. Diese Daten werden innerhalb der Empfängerschaltung 
in Echtzeit weiterverarbeitet. Dies gleichzeitig auf 8 Leitungen.
Die Impulse sind jedoch sehr kurz wie gesagt 300-400ns.

Ich möchte jetzt mit einem ATTINY quasi 8 Monoflops realisieren, die die 
Impulse verlängern(z.B. 10-50ms) um angeschlossene LEDS ansteuern. Diese 
sollen in Echtzeit anzeigen wenn Daten einlaufen. Das direkte ansteuern 
der LEDs geht in die Hose weil die Pulse zum Teil so kurz sind, dass die 
LEDs kaum leuchten. Klar - wenn jetzt viele Impulse hintereinander 
eingehen, dann leuchten die LEDs halt immer. Wenn aber keine 
Eingangsimpulse mehr kommen, dann gehen die LEDs nach 25ms wieder aus. 
Das wäre mein Wunschszenario.

Diskret mit 555 und Co wollte ichs extra nicht machen, weil es erheblich 
mehr Platz benötigt (der attiny ist im kleinsten Gehäuse nur ca. 4*4mm) 
und ich auch noch nicht weiss wie der visuelle Eindruck bei 
unterschiedlichen Monoflopzeiten ist.

von Floh (Gast)


Lesenswert?

Wolfram schrieb:
> Die Impulse sind jedoch sehr kurz wie gesagt 300-400ns.

Wie schnell kommen die Impulse wieder?

von Peter D. (peda)


Lesenswert?

Wolfran schrieb:
> Kann man auf 8 IOs eine Art Flankenerkennung o.ä. auf dem AVR Typ
> realisieren ?

Mal sehen:
INT0
INT1
PCINT0
PCINT1
PCINT2
TIMER1 CAPT
ANALOG COMP
TIMER0 OVF

sind genau 8, geht also.
Bei 8MHz müssen die Pulse >125ns sein.


Peter

von Wolfram (Gast)


Lesenswert?

Floh schrieb:
> Wie schnell kommen die Impulse wieder?

Nun die Impulse werden von Transceiver-Chips ausgegeben wenn der 
Eingangspuffer Daten enthält, die noch nicht weiterverarbeitet wurden. 
Dass heißt das kann sehr undeterministisch sein.
Habs noch nicht genau ausgemessen, da mir bisher die Erkennung nicht 
sicher genug war.
Ich denke minimal alle 1us, maximal vielleicht alle 2-3us.

von Floh (Gast)


Lesenswert?

Wolfram schrieb:
> Ich denke minimal alle 1us, maximal vielleicht alle 2-3us.

Dann wird das nix mit Monoflop durch den tiny ersetzen. Du willst auf 8 
Kanälen Flanken von < 400ns erkennen und noch verlängert an einem 
anderen Port wider ausgeben. Das geht softwaretechnisch schon wegen der 
begrenzten Rechenzeit nicht, bis neue Pulse ankommen.

Würd ich eher über RC-Glied und Schmitttrigger zu lösen probieren, das 
wären dann pro Kanal 1 R 1 C und ein Trigger.

von Peter D. (peda)


Lesenswert?

Floh schrieb:
> Dann wird das nix mit Monoflop durch den tiny ersetzen. Du willst auf 8
> Kanälen Flanken von < 400ns erkennen und noch verlängert an einem
> anderen Port wider ausgeben. Das geht softwaretechnisch schon wegen der
> begrenzten Rechenzeit nicht, bis neue Pulse ankommen.

Das ist Quatsch.
Natürlich kann man Pulse in den 25ms Verlängerung nicht anzeigen.
Anner als an geht die LED nunmal nicht.
Du mußt also erst nach 25ms wieder bereit sein, d.h. der ATtiny gähnt 
vor Langeweile.

Wichtig ist eben nur, daß jeder Eingang seinen eigenen Vector erhält. 
Denn zum Ausklamüsern des Pins reichen die 300ns nicht.


Peter

von Wolfram (Gast)


Lesenswert?

Ihr seid ja echt fix.

Peter Dannegger schrieb:
> Du mußt also erst nach 25ms wieder bereit sein, d.h. der ATtiny gähnt
> vor Langeweile.

Ja aber nur für den einen Kanal, auf den anderen IOs kanns ja schon 
wieder nötig sein zu reagieren...
>Anner als an geht die LED nun mal nicht.
Das stimmt allerdings ;-)

von Peter D. (peda)


Lesenswert?

Wolfram schrieb:
> Ja aber nur für den einen Kanal, auf den anderen IOs kanns ja schon
> wieder nötig sein zu reagieren...

Und wo ist das Problem?
Ist eine LED an, schaltest Du deren Interrupt-Enable aus. Somit haben 
auch alle nieder priorisierten Interrupts 25ms Zeit, ihren Handler 
auszuführen.

Ein gesetztes Interrupt-Pending-Flag geht ja nicht verloren. Es wartet, 
bis der Handler ausgeführt wird.


Peter

von blaubart (Gast)


Lesenswert?

was mir dazu einfällt. externes parity ic, das die binäre quersumme 
aller bits an den interrupt eingang des tiny weitergibt. dann muss mit 
dem ersten befehl nach auslösen des interrupt der port eingelesen 
werden.

von blaubart (Gast)


Lesenswert?


von avr (Gast)


Lesenswert?

Beim 2313 ist doch der kpl. PortB als PinChange verwendbar.

Und wenn der µC sonst nichts macht, kann man das Flag in der
Main abfragen (ohne Interruptroutine).

avr

von Peter D. (peda)


Lesenswert?

Folgende Pins sind die Eingänge:
Pin: Vector:
------------
PD2: INT0
PD3: INT1
PB0: PCINT0
PA0: PCINT1
PD5: PCINT2
PD6: TIMER1 CAPT
PB1: ANALOG COMP
PD4: TIMER0 OVF


Peter

von wolfram (Gast)


Lesenswert?

@Peter
Peter Dannegger schrieb:
> PD2: INT0
> PD3: INT1
> PB0: PCINT0
> PA0: PCINT1
> PD5: PCINT2
> PD6: TIMER1 CAPT
> PB1: ANALOG COMP
> PD4: TIMER0 OVF

Hallo Peter,
danke für die Liste, aber wie Programmier ich das denn jetzt ? Da ist ja 
leider nix mit "...ich les den Port mal mal ein und guck ob sich was 
getan hat...". Könntest Du mir da helfen ?


@avr
>Beim 2313 ist doch der kpl. PortB als PinChange verwendbar.
Ne leider nur ein teil und dann auch nur als "Sammel Pin Change", dann 
muss man immer noch rausklamüseren welcher es denn war.

mfg wolfram

von Karl H. (kbuchegg)


Lesenswert?

wolfram schrieb:
> @Peter
> Peter Dannegger schrieb:
>> PD2: INT0
>> PD3: INT1
>> PB0: PCINT0
>> PA0: PCINT1
>> PD5: PCINT2
>> PD6: TIMER1 CAPT
>> PB1: ANALOG COMP
>> PD4: TIMER0 OVF
>
> Hallo Peter,
> danke für die Liste, aber wie Programmier ich das denn jetzt ? Da ist ja
> leider nix mit "...ich les den Port mal mal ein und guck ob sich was
> getan hat...". Könntest Du mir da helfen ?

Genau darum gehts.
Bei deinen Zeitvorgaben hast du dir Zeit dazu nicht, dass dein Programm 
gemütlich die Ports abklappert.
Da müssen die Signale schon Interrupts auslösen, damit du keinen Puls 
übersiehst. Das erkennen der Pulse muss dir die Hardware machen!

von Peter D. (peda)


Lesenswert?

wolfram schrieb:
> Da ist ja
> leider nix mit "...ich les den Port mal mal ein und guck ob sich was
> getan hat...".

Das macht ja die Hardware für Dich, die erkennt die Flanke und setzt das 
Interruptflag.

Die PCINTx reagieren auf beide Flanken, sollte für Deine Anwendung aber 
nicht stören. Und Du maskierst sie für nur einen Pin, damit brauchst Du 
nicht zu testen, welcher Pin es war.

Der TIMER0 wird auf extern Zählen gesetzt und auf 0xFF, damit er mit der 
Flanke überläuft (und danach wieder auf 0xFF).

Als Schaltschwelle für den Komparator nimmst Du den Brownout (1,1V).

Jede LED kriegt nen Zähler, der mit T1 jede ms weiterzählt, um die 25ms 
Leuchtzeit zu machen.

Fertig.

Pseudocode je LED:
1
if( Interuptflag == 1)
2
{
3
  Interruptflag = 1; // setzen = löschen !
4
  zähler = 25;       // 25ms
5
  LED = an;
6
}
7
jede ms:
8
if( --zähler == 0 )
9
  LED = aus;


Peter

von Wolfram (Gast)


Lesenswert?

@Peter, Karl-Heinz et al.
Hallo Zusammen,
ich hatte vergessen mich zu bedanken, da ich noch mit anderen Arbeiten 
beschäftigt war. Jetzt geht es wieder weiter.
Problem war auch dass ich auf neue PCB Versionen warten musste um 
weiterzumachen.
Schönen Gruß
Wolfram

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.