www.mikrocontroller.net

Forum: Compiler & IDEs INT0 und Timer2 - kann die Impulslänge nicht messen...


Autor: Stanislav Struminski (lau)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo liebe Community,

ich versuche mit einem atmega162 die Tastendrücke, die ein VW-Radio an 
CD-Wechsler meldet, auszuwerten. Laut Protocol-Beschreibung (und das 
sehe ich auch mit dem LA) kommt erst 9 ms-langer high-Impuls, dass 4,5 
ms low, und dann kommen 32 bits von Command, die als (0,550 ms high + 
0,550ms low) für 0 und (0,550 ms high + 1,7 ms low) für 1 kodiert sind. 
Stimmt alles, abgeguckt mit LA direkt am Pin 12 des atmega's; Pegeln vom 
Radio sind 0V-5V, Ausgang des Radios ist über zwei 74HC14-Elemente an 
INT0 angeschlossen.
Als erstes wollte ich einfach die Längen der Impulse zwischen steigender 
und fallender Flanken messen, mit denen ein Array von 32 Stellen füllen 
und das Ergebnis mit UART auszugeben nur irgendwie klappt es bei mir 
nicht. Device reagiert auf die Sendung vom Radio und gibt das Array über 
UART aus, nur die gemessenen Längen stimmen überhaupt nicht: alle Werte 
im Array sind dann entwender 00 oder 01 :(

Was mache ich event. falsch in dem untenstehenden Code? (kompiliert mit 
der letzten WinAVR-Version) :

void main(void) {
  SBI(MCUCR, ISC01);SBI(MCUCR, ISC00); //rising edge by start
  while (1) {
  }
}

void start_T2() {
  TCNT2 = 0x00;
  //clock period = 128 us
  SBI(TCCR2, CS22);SBI(TCCR2, CS21);SBI(TCCR2, CS20);
}
void stop_T2() {
  CBI(TCCR2, CS22);CBI(TCCR2, CS21);CBI(TCCR2, CS20);//clear bits
}
volatile int   count = 0;
volatile int   state = 0;
volatile uint8 lengthes[32];

SIGNAL(SIG_INTERRUPT0) {
  if (state==0) {
    //set from rising to falling edge
    SBI(MCUCR, ISC01);CBI(MCUCR, ISC00);
    start_T2();
    state = 1;
  }
  if (state==1) {
    //set back to rising edge
    SBI(MCUCR, ISC01);SBI(MCUCR, ISC00);
    lengthes[count]  = TCNT2;
    stop_T2();
    state = 0;
    ++count;
    if (count>31) {
      for (int i=0;i<32;++i) {
        UART_Printfu08(lengthes[i]);
        EOL();
      }
      count = 0;
    }
  }

}

Autor: johnny.m (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
SIGNAL, SBI, CBI... sind längst veraltet (und was CBI und SBI angeht, 
die werden afaik gar nicht mehr unterstützt). Du müsstest eigentlich 
beim Compilieren eine ganze Latte Warnungen und Fehlermeldungen 
bekommen... Außerdem: Der obige Code ist mit Sicherheit unvollständig. 
Warum schickst Du kein vollständiges Programm?
Und noch was: Impulslängenmessung macht man mit Input Capture und nicht 
über externe Interrupts.
Und: Serielle Ausgaben haben in Interrupt-Handlern nichts verloren. Da 
brauchste Dich nicht zu wundern, wenn es Timing-Probleme gibt.

Autor: Stanislav Struminski (lau)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Der Compiler bringt keine Warnungen aus, ausser
cdc.c:30: warning: function declaration isn't a prototype
cdc.c:34: warning: function declaration isn't a prototype

SBI/CBI/SIGNAL benutze ich an anderen Stellen des Projektes und die 
funktionieren einwandfrei; wegen serieller Ausgabe hast du formal Recht, 
das ist aber nur ein Versuch, die Längen zu messen; die Ausgabe erfolgt 
erst nachdem die ersten 32 Impulse gemessen sind und damit dürfte 
keinerlei Timing-Probleme zumindest für die ersten 32 Messungen 
herrvorrufen; ich habe schon versucht das Array beim Empfangen eines 
bestimmten Charakters mit SIGNAL(SIG_USART0_RECV) in uart.c auszugeben - 
mit gleichem Endergebnis; der Unterschied zu ICP liegt m.E. nur daran, 
dass ich da Noise unterdrucken kann  :/ - nur ich habe hier keinen 
Noise, sonst würde INTO auch beim Noise ausgelöst.

Den Quellcode komplett poste ich gleich.

Autor: johnny.m (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Tja, mit den Warnungen kann man herzlich wenig anfangen, wenn man nicht 
weiß, auf was sich die Zeilennummern beziehen...

Autor: Stanislav Struminski (lau)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
anbei das Projekt

Autor: Stanislav Struminski (lau)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
habe gestern dem Rat von johny.m gefolgt und ICP benutzt - mit dem geht 
es auf einmal :)
Code:

int count = 0;
u08 lengthes[32];
u16 lengthes_16[72];

void cdc_init(void)
{
  SBI(TCCR1B, ICNC1);
  CBI(TCCR1B, ICES1); //falling
  SBI(TIMSK , TICIE1);
  SBI(TCCR1B, CS12);CBI(TCCR1B, CS11);CBI(TCCR1B, CS10);
}

SIGNAL(SIG_INPUT_CAPTURE1) {
  uint16 length = ICR1;
  lengthes_16[count] = length;
  TCNT1 = 0x0000;
  ++count;
  if (count>71) count = 0;

}
void printL() {
  for (int i=0;i<72;++i) {
   UART_Printfu16(lengthes_16[i]);
   EOL();
   lengthes_16[i] = 0x0000;
        }
}

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

Bewertung
0 lesenswert
nicht lesenswert
Wenn du jetzt noch SIGNAL durch ISR ersetzt und TIMER1_CAPT_vect für
den Namen des Vektors, bist du auf dem aktuellen Stand.

Außerdem ist deine Benutzung der CBI- und SBI-Makros der beste
Beweis, warum man solche Makros wirklich nicht haben will.  All deine
umständlichen und codeintensiven Aktionen (die noch dazu kurzzeitig
den Timer mit einem nicht gewollten Prescaler betreiben) lassen sich
einfach durch:
TCCR1B = _BV(ICNC1) | _BV(CS12);
ersetzen.

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.