Flankenerkennung ohne Interrupts

OP #709950
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
Gast #709973
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?
#710014
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
OP #710198
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
Gast #710205
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;
}
Gast #710236
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
Gast #714867
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
Gast #3256516
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

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren