www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Hysterese bei AVR (ACO oder ICP)


Autor: Robert B. (robertb)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo!

Ich suche eine Möglichkeit dem internen Komparator des AVRs eine 
Hysterese zu verpassen. Hat das schon mal jemand gemacht?

Konkret geht es um die Aufbereitung des in diesem Thread gezeigten 
Signals: Beitrag "Impulsaufbereitung für Moped-Zündung (Pickup-Spule)"

Momentan nehme ich den positiven Anteil des Signals (normale 1N4148), 
danach "schneide" ich mit einer Z-Diode und Widerstand gegen Masse 
weitere 10V weg und gehe dann per Vorwiderstand auf eine 4,7V Z-Diode 
(als Schutz) und einen Kerko (Tiefpass).
>>---1N4148----ZF10----*--1k--*--*------ AIN0
                       |      |  |
                       |      Z  1
                       1      F  0
                       k      4  n
                       |      .  F
                       |      7  |
                       |      |  |
>>---------------------*------*--*------ GND

Wenn ich das Signal mit einem regelbaren Netzteil simuliere erhalte ich 
manchmal auch beim Runterregeln ein Interrupt. Gleiches passiert 
seltsamerweise sogar auch wenn ich den Eingang mit z.B. +17V verbinde 
und dann wieder trenne.

Momentan ist der eingesetzte AVR ein AT90S2313 (Resteverwertung), kann 
aber auch einen mega168 oder mega8 nehmen (oder bestelle mir was).

: Verschoben durch Moderator
Autor: Ganymed (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Du führst die zu messende Spannung über
einen Spannungsteiler (R1 R2)mit Tiefpasswirkung (C1)
auf den nichtinvertierenden Eingang den
Comparators. Wenn ACO High ist, schaltet
ein Ausgang über einen Widerstand den AIN(+)
etwas positiver.
                       |-------------Ein Ausgang
                       |
                       R3
                       |
                       |
>>---1N4148----R1------*-----*------- AIN0
                       |     |
                       |     |
                       R2    C1
                       |     |
                       |     |
>>---------------------*-----*--------- GND

Autor: Robert B. (robertb)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Ganymed,

vielen Dank für deine Antwort.

Allerdings bin ich immer noch etwas am grübeln ob das so gut 
funktionieren kann.

Beispiel:

AIN0 = 2,6V, AIN1 = 2,5V -> ACO wird high

ACO-Interrupt:
Um jetzt die Hysterese zu erzeugen senke ich die Referenzspannung an 
AIN1 ab (z.B. um 0,5V) -> AIN0 = 2,0V

Die Spannung an AIN0 fällt auf 1,999V -> ACO-Interrupt

im Interrupt müsste man nun die Referenzspannung wieder auf 2,5V setzen 
um die Hysterese für die steigende Flanke zu gewährleisten. Problem: 
Wird in dieser Zeit das Signal nur kurz 2,0001V wird wieder ein 
Interrupt ausgelöst. Und die Zeit bis das Interrupt auslöst und die 
Referenzspannung umgestellt hat ist in den Maßstäben eines unsauberen 
Eingangssignal warscheinlich recht lang.

Wahrscheinlich ist dass der Nachteil das ganze nicht mit einem eigenen 
OP-Amp zu machen. Oder habe ich etwas wesentliches übersehen?

Grüße
Robert

Autor: Benedikt K. (benedikt) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Bei einem ATtiny261 kann man beim Komparator eine Hysterese zuschalten, 
das würde die ganze Sache stark vereinfachen.

Autor: Robert B. (robertb)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo!

Habe das ganze jetzt so gelöst:

An AIN0 liegt das Signal an. An AIN1 ist ein Spannungteiler mit 47k Poti 
der 2,5V liefert. Über einen 47k Widerstand kann man über PB6 die 
Spannung auf 2V (PB6 low) oder auf 3V (PB6 high) ändern. Gleichzeitig 
kann man gratis noch ne Kontrollled anschließen.

Codemäßig verwende ich sowohl den ICP-Int des Timers 1 (daran wird dann 
auch die Periode gemessen) bei falling edge (Signal größer Referenz) und 
den AC-Int bei rising edge (Signal kleiner Referenz).

Initialisierung:
void timer_init(void)
{
  /*
   * init timer1
   * ICNC1: Input Capture1 Noise Canceler (4 CKs)
   * ICES1: Input Capture1 Edge Select (0 = falling edge / 1 = rising edge)
   * prescaler
   */
  TCCR1B = (1<<ICNC1) | (0<<ICES1) | T1presc64;
  /*
   * interrupts
   * TICIE1: Timer/Counter1 Input Capture Interrupt Enable
   * TOIE0: Timer/Counter0 Overflow Interrupt Enable
   */
  TIMSK = (1<<TICIE1) | (1<<TOIE1);  // Input Capture und Overflow T1 und Output Compare Match T1 aktivieren
}

void aco_init(void)
{
  /*
   * init analog comparator
   * ACIE: Analog Comparator Interrupt Enable
   * ACIC: Analog Comparator Input Capture Enable
   * ACIS1/ACIS0: (1 0) - Comparator Interrupt on Falling Output Edge
   *              (1 1) - Comparator Interrupt on Rising Output Edge
   */
  ACSR = (1<<ACIE) | (1<<ACIC) | (1<<ACIS1) | (1<<ACIS0);
}

Interrupts:
ISR(TIMER1_CAPT1_vect)
{
  if (ACSR & (1<<ACO))
    return;

  // lower ref-voltage on AIN1 for hysteresis
  PORTD &= ~(1<<6);
  // clear pending aco-interrupt that might occured due to non-hysteresis
  ACSR |= (1<<ACI);

  // hier wird gearbeitet
}

ISR(ANA_COMP_vect) {
  if (!(ACSR & (1<<ACO)))
    return;

  // raise ref-voltage on AIN1 for hysteresis
  PORTD |= (1<<6);
  // clear pending icp-interrupt that might occured due to non-hysteresis
  TIFR |= (1<<ICF1);
}

Direkt zu Beginn der Interrupts wird geprüft ob die Bedingung noch 
vorliegt. Quasi ein Tiefpass. Danach wird sofort die Referenzspannung 
umgeschaltet. Sollte in der Zwischenzeit aufgrund der nicht-vorhandene 
Hystherese das komplementäre Interrupt ausgelöst worden sein wird dieses 
gelöscht. Zusammen mit der Abfrage zu Beginn scheint das etwas 
doppelt-gemoppelt zu sein aber so das Aufrufen des komplementären Ints 
vermieden und evtl. hab ich noch eine Konstellation nicht bedacht.

Vielleicht hilft dieser Code anderen die ein ähnliches Problem haben. 
Zudem würde ich mich über Anmerkungen sehr freuen falls ich doch nen 
Fehler gemacht habe.

Grüße
Robert

Autor: A. K. (prx)
Datum:

Bewertung
0 lesenswert
nicht lesenswert

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.