mikrocontroller.net

Forum: Compiler & IDEs wie kann ich Flanken detektieren


Autor: Andre Fischer (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi,

ich moechte folgendes erreichen:

Wenn an einem Port eine steigende UND eine fallende Flanke erkannt
wurde (also ein wechsel von 0 zu 1 und zurueck stattgefunden hat) soll
ein anderer Port auf High gehen (zum Beispiel eine LED anschalten)

Das ganze soll mit 7 Ports geschehen. Wie koennte ich das moeglichst
einfach realisieren?

Autor: johnny.m (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
1.: Port != Portpin
2.: Welcher µC, welche Sprache?
3.: Datenblatt und Tutorial schon gelesen?

Autor: Wolfgang Horn (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi, Andre,

die simplen Möglichkeiten, den Port mit den Sensoren periodisch
abzutasten und an den PED-Port schneller zu kopieren, als das Auge
gucken kann, das wirst Du schon verworfen haben.

Wenn's also schnell gehen soll, dann nimm einen Prozessor wie den
Atmega48, Atmega88, Atmega168 und benutze die "Pin Change
Interrupt"s.

Ciao
Wolfgang Horn

Autor: Karl heinz Buchegger (kbucheg)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wie schnell sind die Signale an den Pins?

Autor: Rolf (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wenn Atmega (alle), dann "logic change" Interrupt aktivieren.
Funktioniert aber nur an INT0 und INT1 Pins.

>Das ganze soll mit 7 Ports geschehen.
Du meinst sicherlich 7 PINs.

Wenn du das softwäremäßig lösen willst:

Beispiel für Port B Pin 0 (8 Abfragen) und PORT C (8 LED):
#include <avr/io.h>

int main(void)
{
PORTB = 0;
DDRB  = 0;

PORTC = 0;
DDRC  = 0xFF;

unsigned char temp;
unsigned int i;
while (1)
{
temp = PINB;

//do somethin else
//...
//

if (temp != PINB) //wenn Änderung
 {
 for (i = 0x01; i <= 0x80; i = i << 1)
   {
   if ((temp & i) ^ (PINB & i))  //wenn Unterschied
    {
    if(PINB & i)    //wenn H-Input
     PORTC |= i;    //dann H-Output
    else
     PORTC &= ~i;    //L-Output
    }
   }
 }

}
return 0;
}

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Dazu gibts ne schnuckelige Lösung in der Codesammlung:

http://www.mikrocontroller.net/forum/read-4-310276.html#new


Peter

Autor: Andre Fischer (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi,

ich hab nicht immer Zugang zum Netz deswegen kann ich jetzt erst
schreiben.

Also:

Ich hatte an einen ATMEGA8 gedacht.

Programmieren wuerde ich das ganze gern in c mit gcc und dem AVR
Studio.

Das Signal ist einige 100 (200 - 400 schaetze ich jetzt mal) kHz
schnell. (ich will eigentlich nichts anderes als testen ob das clock
pin [und diverse andere pins] wirklich etwas "rausbringen", das board
was ich testen will, also funktioniert. Mit dem µC will ich mir es
sparen immer erst einen oszi oder logic analyser anzuschliessen, da es
in dem Fall nicht darum geht zu sehen WAS raus kommt sondern nur OB
etwas rauskommt [wenn ja geh ich dann davon aus das es das richtige
ist.] Und da dachte ich eben ich versuche [eine] fallende und steigende
Flanke(n) zu erkennen)

Danke erstmal fuer die Antworten ich werde bei der naechsten
Gelegenheit anfangen rumzuprobieren.

Autor: Karl heinz Buchegger (kbucheg)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Würde ich so machen:

Ich benutze den externen Interrupt Eingang und konfiguriere
den auf steigende Flanke.

Wann immer ein Interrupt auftritt wird eine LED eingeschaltet.

Dann kommt da noch ein Timer ins Spiel, der in
regelmäßigen Intervallen die LED einfach wieder ausschaltet.

Fertig.
Ein kleiner 8-pin Tiny kann das wunderbar machen.
Je nach Typ, müsste man den eventuell in Assembler
programmieren. Ist aber kein Beinbruch, da die vorgeschlagene
Vorgehensweise in einem Programm mit deutlich weniger als
30 Anweisungen resultiert (da gehen je nach Typ mehr als die
Hälfte für den Aufbau der Interrupttabelle drauf).

Autor: johnny.m (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Naja, Andre schreibt ja ganz oben was von '7 Ports', wobei ich davon
ausgehe (was ich oben ja auch schon zum Ausdruck gebracht habe), dass
Andre Ports und Portpins durcheinanderbringt. Also vermutlich 7
Portpins. Und da wirds mit nem 8-Pin-Tiny eng... Eher nen Tiny2313
(oder eben nen Mega8, an den Andre ja nach eigenem Bekunden auch schon
gedacht hat) und mit den Pin Change Interrupts rumspielen. Dann klappts
auch mit den 7 Signalen... Und ansonsten wie von Karl Heinz beschrieben:
Pin Change Interrupt schaltet ne LED ein und nach einer bestimmten Zeit
(lange genug, um durch das Auge wahrgenommen zu werden) wird sie wieder
ausgeschaltet.

Autor: Karl heinz Buchegger (kbucheg)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> '7 Ports'

Ooops. Diese Anforderung hatte ich schon verdrängt.
Dann wirds natürlich nichts mit nem 8-pinner.

Autor: Andre Fischer (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Also erstmal JA ich meine 7 Portpins nicht Ports (sorry fuer dei
Verwechslung).

Das mit dem Pin change interrupts klingt auch ziemlich gut aber kann
ich das mit dem Mega8 macehn? (ich find im Datenblatt von dem kein
pcint). Also wenn ich mich nicht zu dumm anstelle (was ja aber gut sein
kann) dann bietet der Mega8 das nicht an.

Welcher AVR bietet ungefaehr das gleiche wie der Mega8 aber zusaetzlich
mindestens 7 Pins mit pin change interrupt?

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

Bewertung
0 lesenswert
nicht lesenswert
> Das mit dem Pin change interrupts klingt auch ziemlich gut aber
> kann ich das mit dem Mega8 macehn?

Nein, du brauchst seinen Nachfolger ATmega88 bzw. dessen Derivate
ATmega48 oder ATmega168.

Autor: Andre Fischer (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich hab mir die Datenblaetter/das Datenblatt mal angesehn und da ist mir
aufgefallen das es nur 3 PCINT gibt, man kann zwar pin 0..7 zum beispiel
dem PCINT0 zuordnen aber dann wird der Interrupt ausgeloest wenn einer
der Pins ne Flanke hatte.

Wie kann ich aber an 7 Pins ueberpruefen ob es eine Flanke gab oder
nicht? (So wie es aussieht seh ich ja nur ab es an irgend einem Pin
zwischen 0..7 zum Beispiel eine Flanke gab, da weiss ich ja aber noch
nicht, an welchem und ob auch an mehreren oder nur einem...)

Autor: johnny.m (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Dann musst Du in der ISR die entsprechenden Pins einlesen und abfragen,
welcher es war. Wichtig ist (bei den von Dir genannten
Signalfrequenzen), dass diese Abfrage direkt am Anfang der ISR
stattfindet, damit der tatsächliche Ist-Zustand wiedergegeben wird. Die
Taktfrequenz des µCs sollte möglichst hoch gewählt werden, damit der
Interrupt schnellstmöglich bearbeitet wird (dran denken: Vom Auftreten
eines Interrupt-Ereignisses bis zur Ausführung der ISR vergehen
mindestens 4 Taktzyklen!). Nach dem Einlesen der betreffenden Pins
einen Vergleich mit dem letzten Stand durchführen (es kann ja auch
passieren, dass mehrere Pins sich quasi zeitgleich ändern) und dann die
entsprechenden LEDs setzen. Am besten alles in Assembler programmieren,
da hast Du am ehesten den Überblick über die zeitkritischen Vorgänge.

Autor: Andre Fischer (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi,

momentan hab ich nicht viel Zeit rumzuprobieren aber fuer den Fall das
ich wieder dazu komme...

Wo kann ich mehr Informationen ueber das Timing finden (ich meine woher
weiss ich das es mindestens 4 Taktzyklen sind bis die ISR abgearbeitet
wird)

Wenn ich also 8 Pins abfrage am Anfang der ISR nach wieviel Taktzyklen
habe ich auch den letzten Port abgefragt? (4 Taktzyklen bis zum starten
der ISR dann brauch ja jedes Abfragen der Pins x Taktzyklen, also sind
wir bei 4+x+x+x+x+x+x+x Taktzyklen bevor der letzte [also achte] Pin
abgefragt wird)

Wenn ich also weiss welcher Vorgang wieviel Taktzyklen braucht kann ich
mir ausrechnen mit Welchem Quartz ich das ganze bei welchen Frequenzen
betreiben kann.

Waere super wenn mir jemand etwas dazu sagen koennte oder einen Link
geben wo ich das ganze genauer nachlesen kann.

Danke

Andre

Autor: johnny.m (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Wo kann ich mehr Informationen ueber das Timing finden ...

Steht alles im Datenblatt.

> Wenn ich also 8 Pins abfrage am Anfang der ISR nach wieviel
> Taktzyklen habe ich auch den letzten Port abgefragt?

Da die abzufragenden Pins sinnvollerweise alle an einem Port sein
sollten, geht das Einlesen in einem einzigen Taktzyklus. Dann einfach
ein Vergleich mit dem vorherigen Zustand (bei der letzten Abfrage) und
an allen Pins, an denen sich was geändert hat, die entsprechende LED
einschalten. Im Hintergrund könntest Du einen Timer laufen lassen, der
z.B. alle 10ms einen Überlauf oder ein Compare Match macht. Wenn Du
dann jeder LED ein Zählregister zuordnest, kannst Du es jeweils bei
einem Wechsel am dazugehörigen Pin auf einen bestimmten Wert setzen
(bei den 10 ms oben würde z.B. eine 50 eine Leuchtdauer von 500ms
bedeuten) und bei jedem Timer-Ereignis werden alle Register um eins
dekrementiert. Erreicht ein Register den Wert '0' (d.h. es ist in den
letzten 500 ms kein Wechsel am Pin aufgetreten), wird die entsprechende
LED ausgeschaltet. Das Flag vom Timer sollte vielleicht (anstatt mit
einem Interrupt) im Hauptprogramm im Polling-Verfahren abgefragt
werden, damit kein Interrupt-Ereignis verloren geht.

Das nur als Idee...

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.