mikrocontroller.net

Forum: Digitale Signalverarbeitung / DSP Flankenerkennung ohne Interrupts


Autor: Martin Wagner (mortn)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Zusammen,

ich würde gerne eine Flanke abfragen, aber keine Interrupts benutzen, da 
die Interrupt-Routine zu langsam ist. Es handelt sich um ein dauerhaft 
anliegendes  Takt-Signal (2 MHz). Davon würde ich gerne jede rising edge 
abfragen.
Ich benutze einen TMS320F2808 von TI.
Wenn ich mit einer If-Schleife die GPIO-Leitung abfragen, geht das nur 
auf das HIGH-level und eben nicht auf die Flanke, und ich bekomme so 
keine vernünftige Synchronisation hin.
Wenn ich es über ein Interrupt versuche, dann braucht die Interrupt 
Service Routine zu lange, um die nächste Taktflanke zu erkennen bzw. 
erkennt diese zu spät.
Gibt es eine Möglichkeit Flanken besonders schnell ohne Interrupts zu 
erkennen?

Vielen Dank schonmal,
mortn

Autor: Gast (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hardware würde ich sagen.

Oder eine IRQ-Routine in Assembler und nur die notwendigsten
Register retten. Dann dürfte die Latenzzeit
nicht so lang sein und er müßte es schaffen. Aber Du hast
eigentlich eh keine Verarbeitungszeit, eben nur 500nsec.

Was willst Du denn in nur 500nsec machen? In so kurzer Zeit
kannst Du evtl. Impulse zählen.
Wofür ist das Ganze gut?

Autor: Detlef _a (detlef_a)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>>Wenn ich mit einer If-Schleife die GPIO-Leitung abfragen, geht das nur
>>auf das HIGH-level und eben nicht auf die Flanke, und ich bekomme so
>>keine vernünftige Synchronisation hin.

yo, aber wenn vorher low war und jetzt high, dann is das doch ne 
steigende Flanke, oda nich?

Kenne den Prozessor nicht, aber bei nem Mega128 mit 16Mhz getaktet 
sollte das Flankenzählen@2Mhz gerade mal so hinhauen.

ISR: die machen gerne mal fetten Overhead wg. Register sichern. Bei AVR 
gcc läßt sich das mit 'naked' pragma umschiffen.

Cheers
Detlef

Autor: Martin Wagner (mortn)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi,

der DSP erzeugt einen takt, der auf einen adresscounter für ein sram. 
danach soll das sram ausgelesen werden, allerdings mit einem takt, der 
nicht vom dsp erzeugt wird, nämlich die 2 MHz.
wenn jetzt eine Flanke kommt, dann soll die GPIO-Leitung, die mit dem 
adresszähler verbunden ist einmal high und dann direkt wieder low 
gesetzt werden, um die adressen hochzuzählen.
Das einfachste wäre wahrscheinlich, jetzt den externen Takt auf ein 
oder-gatter zu geben und dann von da aus auf den counter. Somit würde 
dann sowohl der vom dsp erzeugte takt als auch der externe den 
adresszähler hochzählen....
...vermute ich zumindest.

Leider müsste ich dazu mein gesamtes Layout umkempeln, und wollte 
deswegen mal fragen, ob es dazu eine Möglichkeit gibt.

ich werde mal der sache nachgehen, die routine in asm zu schreiben und 
versuchen so wenig register wie möglich zu retten....

@ detlef: auf diese weise könnte ich zwar die flanke erkennen, aber es 
könnte passieren, dass ich innerhalb einer high-phase zweimal auf das 
high-level abfrage, und das wäre einmal zu viel... oder der umgekehrte 
fall, dass ich eine komplette high-phase überspringe. oder irre ich mich 
da jetzt?!?

greetz
mortn

Autor: Gast (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>>könnte passieren, dass ich innerhalb einer high-phase zweimal auf das
>>high-level abfrage, und das wäre einmal zu viel... oder der umgekehrte

Nein, Du mußt dir den level merken. erst wenn du wieder lowlevel
erkannt hast, dann darfst Du wieder bei highlevel deine Aktion
starten.

In C z.B:

void function( void )
{
  static char old_level = 0;
  char new_level;

  new_level = (port_pin != 0);
  if( !old_level && new_level )
  {
    // steigende flanke erkannt, mach was
  }
  old_level = new_level;
}

Autor: Winne (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Arbeiten DSP und MC im selben Gerät?


In diesem Fall würde einen externen Taktgenerator mit z.B. 16MHz (besser 
32MHz das schafft)werkeln lassen und damit den µC direkt Takten den 
DSP-Takt würde ich durch Herunterteilen erzeugen. Somit wäre für 
Synchronität gesorgt.
Jetzt ist es am ASM Programmierer das Programm so zu gestalten, daß alle 
X(8/16) Takte ein Zähler in(de)crementiert oder getoggelt wird.
Klar dazwischen geht nicht wirklich nicht. Aber man könnte den Zähler 
gleichzeitig als PseudoProgramcounter(bzw. geilch diesen manipulieren 
oder) verwenden und zwichenzeitlich einzelne Instruktionen abarbeiten. 
Somit währe die Zählloop=main und das eigentliche Programm würde als 
Einzelinstruktionssubs abzuarbeiten.

Mfg

Autor: Winne (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich sehe gerade der TMS320F2808 schafft 100Mhz man sollte ihn daher auf 
64(96) Mhz laufen lassen, um gut runterteilen zu können und trotzdem 
genug Zeit für anderes zu haben.

MfG Winne

Autor: mortn (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Jo, läuft, Danke!!!

Autor: Gast (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Und wie hast es nun gelöst? Ist auch immer interassant zu wissen.

Autor: mortn (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
so:


>>void function( void )
>>{
>>  static char old_level = 0;
>>  char new_level;

>>  new_level = (port_pin != 0);
>>  if( !old_level && new_level )
>>  {
>>    // steigende flanke erkannt, mach was
>>  }
>>  old_level = new_level;
>>}


Schönes WE,
Martin

Autor: Keine Ahnung (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Guten Abend

Stimmt mein Code Flankenerkennung ohne Interrupts? Möchte gerne mit 
Flankenerkennung eine Led zum Leuchten bringen, als erstes einmal.




#include <avr/io.h>  //attiny13a//

void Flankenerkennung (void){
  PORTB |=(1<<PB1);  //led//
  PORTB |=(1<<PB0);  //Signal//
}

int main(void){
  DDRB |=(1<<PB1); //led//
  DDRB &=(1<<PB0); //flankenschaltung//
  PORTB |=(1<<PB0); //pull up//

  while(1){
        static char old_level = 0;
        char new_level;

        new_level = (PB0 != 0);
        if( !old_level && new_level )
        {
          if (!(PINB & (1<<PB0))) //Ist Flanke gestiegen = PB0High//
          {
      PORTB |= 1<<PB1;    // LED PB1 leuchtet//
        }

        }
        old_level = new_level;
    }
return 0;
}

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.