das programm ist meiner meinung nach fehlerfrei, hast du mal ausprobiert obs funktioniert wenn du den controller extern resetest? vielleicht ist er ja kaputt. du benutzt ja schon einen spannungsteiler, also den poti und noch 2 widerstände oder?
Bin so langsam am verzweifeln. Sitze hier nun Stunden bei und kann den fehler nicht finden.
Das ist das Programm. In der Mega8 Doku steht:"When the voltage on the positive pin AIN0 is higher than the voltage onCode:;-------Analog Comparator Test---------------------------- .include "m8def.inc" ;Definitionsdatei einbinden rjmp reset ; Reset Handler reti ; IRQ0 Handler reti ; IRQ1 Handler reti ; Timer1 Capture Handler reti ; Timer1 compare Handler reti ; Timer1 Overflow Handler reti ; Timer0 Overflow Handler reti ; SPI Transfer Complete Handler reti ; UART RX Complete Handler : RXCIE reti ; UDR Empty Handler reti ; UART TX Complete Handler reti ; ADC Conversion Complete Interrupt Handler reti ; EEPROM Ready Handler ;rjmp comparator ; Analog Comparator Handler reset: ; sbi ACSR, ACIS1 ; sbi ACSR, ACIS0 ; sbi ACSR, ACIE ; sei ldi r16, 0xFF out DDRC, r16 ldi r16, 0x00 out PORTC, r16 ;LED aus ldi r17, ACSR SBRS r17, 5 ;5=ACO Bitabfrage wenn Comparator schaltet rjmp reset ledan: ldi r16, 0xFF ;LED an out PORTC, r16 ldi r17, ACSR SBRC r17, 5 ;5=ACO Bitabfrage wenn Comparator schaltet rjmp ledan rjmp reset ;comparator: ; ldi r16, 0x00 ;LED an ; out PORTC, r16 ;reti
the negative pin AIN1, the Analog Comparator Output, ACO, is set." Es muß also auch ohne Interrupt gehen. Habe also mal den Interruptteil auskommentiert.
Das Programm läuft in so weit, dass die richtige LED bei einem vollen Potianschlag leuchtet wenn ich das Programm überspielt habe. Drehe ich den Poti zum anderen Anschlag ist die LED immernoch an. Überspiele ich das Programm erneut bei dem gleichen Potianschlag, so geht die LED aus. Und das kann man wieder anders herum wiederholen. Kann es mir irgendwie nicht mehr erklären. Der Comparator scheint also zu funktionieren, aber nur wenn das Programm überspielt wird. Während der Laufzeit funktioniert es nicht.
Woran liegt es?
das programm ist meiner meinung nach fehlerfrei, hast du mal ausprobiert obs funktioniert wenn du den controller extern resetest? vielleicht ist er ja kaputt. du benutzt ja schon einen spannungsteiler, also den poti und noch 2 widerstände oder?
ja genau, sieht ungefähr so aus.
programmiere mit dem AVR studio 4 .11 und uppe mit ponyprog.Code:VCC------------1,1k------------Poti 2,5k-------------GND | | AIN0 (0-3,36V) VCC------------1,1k------------ 1,1k-------------GND | | AIN1 ( 2,45V)
habe den internen Takt laufen ( glaube 1MHz), müßte doch reichen oder brauch man für den AC mehr?
habe eigentlich mehrere rätzelhafte Probleme. Timer funktionieren nicht sobald ein Prescaler größer 256 drin ist.
so einfach Programme wie.... funktionieren
main:
ldi r16, 0xFF
out DDRC, r16
ldi r16, 0x00
out PORTC, r16
rjmp main
sobald ich aber ne Endlosschleife wie unten programmiere nicht mehr.
ldi r16, 0xFF
out DDRC, r16
ldi r16, 0x00
out PORTC, r16
main:
rjmp main
(in beiden Beispielen habe ich mal den Def-, Interrupttabellen- und Stackpointerbereich weggelassen.)
habe auch schon die IC's ausgetauscht aber habe immer solche Probleme.
War schon am überlegen ob ich nicht testweise auf ein anderes Programm umsteige. WinAVR oder so.
Also wenn ihr der Meinung seid, dass die Beschaltung und das Programm stimmen, dann werde ich es mal mit einem anderen Programm testen denn so langsam wird es echt frustrierend wenn sich solche unerklärlichen Probleme auftun.
Hallo,
Ich vermisse in deinem Codebeispiel zum Analog-Comparator dieBin so langsam am verzweifeln. Sitze hier nun Stunden...
Initialisierung des Comparators.
Seh dir doch mal im Handbuch den entsprechenden Abschnitt und
insbesondere die Funktion der Register SFIOR und ACSR an.
Das An-und Abschalten sämtlicher Bits des Port C,
kann zu dem von dir beschriebenen Verhalten führen,
wenn z.B. eines dieser Bits auch per
AINx als Comparator-Eingang geschaltet ist.
Der Comparotor hat zwei Eingänge.
Du hättest dann so eine Art Schmitt-Trigger-Verhalten "gebastelt":
Gruß Jan
Weiss nicht ob eine Initialisierung nötig ist, wenn ich nicht die AC Interrupts nutzen möchte. Im Handbuch steht unter ACSR das der Initial Value von Bit 7 ACD=0 was EIN bedeutet. Muß also wohl nicht extra gestartet werden.
SFIOR ist doch zum Einschalten des Analog Comparator Multiplexer und den brauch ich doch auch nicht, oder doch?
Die Bits von Port C sind ja von AINx getrennt. Und die AINx Pins gehören laut Handbuch zu Port D, falls du das meinst.
Also im Simulator passieren auch merkwürdige Dinge und wenn es selbst dort nicht klappt....
Also bei dem Punkt
ldi r17, ACSR
läd er den Wert 0x08 in r17. woher nimmt er den. ACSR hat den Wert 0x00 und nicht 0x08.
Wenn ich den AD Output (ACO) mit dem Bit5 von ACSR simuliere dann hat ACSR 0x20 aber das Programm ldi't immernoch 0x08 ins r17. völlig unverständlich sowas.
Würde mein Windows so ein verhalten zeigen, dann würde ich glatt auf einen Virus tippen, aber beim AVR Studio gehe ich nicht davon aus
HAllo,Ja, Stimmt. Ich meinte die ADCx-Pins.Die Bits von Port C sind ja von AINx getrennt. Und die AINx Pins gehören laut Handbuch zu Port D, falls du das meinst.
Auf den Simulator kann man sich nicht immer verlassen.
Der Mega-8 funktioniert jedenfalls so wie im Datenblatt beschrieben.
Bei mir war es bis jetzt immer so, dass der Fehler
letztendlich vor dem Monitor sass, und nicht im Chip.
Wie hast du denn den posiven Comparator Input beschaltet ?
Wenn du den Comparatot nicht initialisierst, ist die
Bandgap-Referenz ja nicht zugeschaltet .
Gruß Jan
Habe oben die "Skizze".
Wie initialisiert man denn den Comparator? Der AC wird doch mit Bit7 von ACSR eingeschaltet (ADC) und das ist er auch.
Den Multiplexer (SFIOR) benötige ich nicht, da ich AIN0 und AIN1 benutze.
Bandgap Referenz wird doch durch AIN1 erzeugt, welcher den Sollwert darstellt und dieser wird mit AIN0 verglichen. Wenn AIN0 größer als AIN1 ist, dann wird Bit 5 (ACO) in ACSR gesetzt, welchen ich abfragen kann. So habe ich es mir zumindest gedacht.
kann mir nicht jemand weiterhelfen? Funktionierender Code der AIN1 und 0 benutzt wäre schon hilfreich.
Also es geht darum, dass ich einen NTC Widerstand mit einem einstellbaren Sollwiderstand vergleichen will. Wenn NTC Widerstand niedrieger ist, als der Sollwiderstand, dann soll ein Transistor angesteuert werden, mit dem ich ein Relais schalten möchte.
Dieses Simple muß nicht unbedingt mit einem uC gelöst werden. Habe es nur ausprobiert, weil es mit einen Comparator IC auch nicht gut geklappt hat. (LM 311). Über google und in diesem Forum konnte ich leider auch nichts finden was weiterhilft. Vielleicht hat ja jemand schon so ein Problem gelöst.
Wäre schön könnte mir jemand weiterhelfen.
Vielleicht bekommst du aus folgendem Code ne Anregung. Ist zwar C (AT90S2313), sollte aber zu verstehen sein. Ich hatte den AC nicht direkt benutzt um eine IRQ auszulösen, sondern zur Zeitmessung via InputCapture von Timer1 (Kapazitätsmessung).
Für deinen Fall einfach den AC-IRQ aktivieren und die gewünschte Flanke einstellen, sollte dann gehen.
-------------------------------------------------------Code:#include "use.h" #include <AVR.h> #include "ports.h" #include "capacity.h" //#include "morse.h" extern void ioinit(); extern void wait_10ms (const byte); #include <math.h> // Multiplikator: // k = (ny * R * ln 2)^{-1} // mit ny = 8MHz und R = 10k: // k = 18pF / Einheit word measure_time (byte loadTime) { // Load capacity via AIN+ push-pull SET (PORT_AIN_POS); MAKE_OUT (PORT_AIN_POS); wait_10ms (loadTime); // disable all interrupts cli(); // stop timer1 TCCR1B = 0; // enable AC (ACD = 0) // AC Input Capture on -> connect to Input Capture of Timer/Counter1 // AC Interrupt on Falling Output Edge ACSR = _BV(ACIC) | _BV (ACIS1); // disconnect timer1 from output pin OC, no PWM TCCR1A = 0; // reset timer1 to 0 TCNT1 = 0; // clear Timer1 OVerflow and Input Capture Flag TIFR |= _BV (TOV1) | _BV (ICF1); // start timer 1 at full speed // no clear on compare match // no noise cancel // input capture edge = falling TCCR1B = _BV (CS10); // here we go! // start discharging via external resistor // AIN+ to high Z MAKE_IN (PORT_AIN_POS); CLR (PORT_AIN_POS); byte flag; do { flag = TIFR & (_BV (TOV1) | _BV (ICF1)); } while (flag == 0); if (flag & _BV (TOV1)) return 0xffff; // if (flag & _BV (ICF1)) return (word) ICR1; // restore status of machine // ioinit(); // morse (_O_); // if (flag & _BV (ICF1)) // morse_dec (capture-4); // morse (_FRAGE_); }
Als Temperaturdifferenzschaltung hatte ich mal die Schaltung unten gebastelt. Mit µC schien mit da mit Spatzen auf Kanonen geschossen, ausserdem lässt sich eine µC-Schaltung nicht so simpel über Potis nachtrimmen.
- Komparator D schaltet, wenn T_innen > T_aussen ist.
- Komparator A schaltet, wenn T_aussen > T_const (zB T_const über Frostgrenze).
- Komparator B funktioniert als Und-Glied
- danach ein Zeitglied und Komparator C als Schmitt-Trigger
Die T-Abhängigen Widerstände sind NTCs.
Disclaimer: none. Sue me.
Hallo,
Die Bandgap-Referenz liegt nicht an Ain1 sondern an Ain0 !
aber nur wenn ACBG (Bit6) im Register ACSR auf 1 gesetzt ist.
Den Analogwert muss du dann an Ain1 anschliessen.
ACO (Bit5) von ACSR schaltet dann auf 0, wenn die Spannung an Ain1
gößer ist als die Bandgap-Referenz von ca. 1,2V.
Bit 7 in ACSR auf 1 schaltet den Comparator nicht ein, sondern aus.
Gruß Jan
Lesezeichen