Forum: Digitale Signalverarbeitung / DSP / Machine Learning Flankenerkennung ohne Interrupts


von Martin W. (mortn)


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

von Gast (Gast)


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?

von Detlef _. (detlef_a)


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

von Martin W. (mortn)


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

von Gast (Gast)


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

von Winne (Gast)


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

von Winne (Gast)


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

von mortn (Gast)


Lesenswert?

Jo, läuft, Danke!!!

von Gast (Gast)


Lesenswert?

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

von mortn (Gast)


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

von Keine Ahnung (Gast)


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

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.