-
        

Ergebnis 1 bis 8 von 8

Thema: Interrupts & Asuro

  1. #1
    Benutzer Stammmitglied
    Registriert seit
    10.08.2005
    Beiträge
    32

    Interrupts & Asuro

    Anzeige

    habe ich das Tutorial von microcontroller.net soweit richtig verstanden, dass es nur eine beschränkte Zahl an interrupts gibt und diese auch automatisch ausgelöst werden - ich mich also auf die Implementierung dieser konzentrieren kann?

    Ich möchte gerne die Änderung der Licht/ Tastsensoren über Interrupts überwachen - leider sagen mir die kryptischen Registerkonstanten nichts.

    Könnte mir vielleicht jemand ein Beispielscript zur verfügung stellen bzw. sagen welche Signals ich wofür abfangen soll?

    Genaugesagt geht es hier um die beiden Odometriesensoren, die Lichtsensoren unten und die Tastensensoren des Asuro.

  2. #2
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    09.06.2004
    Ort
    Aachen
    Beiträge
    2.674
    Es gibt nur für bestimmte Ereignisse Interrupts, du kannst nicht bei einer Änderung eines Wertes eine Interruptsroutine auslösen. Da sowohl die Taster als auch die Lichtsensoren über den Analog-Digital-Wandler laufen, steht dir nur ein Interrupt zur verfügung, wenn er eingschaltet ist springt er in eine Routine wenn eine ADC-Messung komplett ist. Ein weiterer ist der Analog-Comparator. Andere AD-Wandler-interrupts gibt es beim Mega8 mMn nicht.

  3. #3
    Benutzer Stammmitglied
    Registriert seit
    10.08.2005
    Beiträge
    32
    in der Routine könnte ich den Wert ja dann abfragen und für die main Schleife einen Statuswert setzen....

    der mega8 war praktischerweise bei microcontroller.net das Beispiel:
    Code:
    #define SIG_INTERRUPT0		_VECTOR(1)
    #define SIG_INTERRUPT1		_VECTOR(2)
    #define SIG_OUTPUT_COMPARE2	_VECTOR(3)
    #define SIG_OVERFLOW2		_VECTOR(4)
    #define SIG_INPUT_CAPTURE1	_VECTOR(5)
    #define SIG_OUTPUT_COMPARE1A	_VECTOR(6)
    #define SIG_OUTPUT_COMPARE1B	_VECTOR(7)
    #define SIG_OVERFLOW1		_VECTOR(8)
    #define SIG_OVERFLOW0		_VECTOR(9)
    #define SIG_SPI			_VECTOR(10)
    #define SIG_UART_RECV		_VECTOR(11)
    #define SIG_UART_DATA		_VECTOR(12)
    #define SIG_UART_TRANS		_VECTOR(13)
    #define SIG_ADC			_VECTOR(14)
    #define SIG_EEPROM_READY	_VECTOR(15)
    #define SIG_COMPARATOR		_VECTOR(16)
    #define SIG_2WIRE_SERIAL	_VECTOR(17)
    #define SIG_SPM_READY		_VECTOR(18)
    demnach wäre SIG_ADC mein Signal?

    Und was hat es mit dem Analog-Comparator auf sich? (SIG_COMPARATOR wahrscheinlich)

    Achja, danke schonmal!

  4. #4
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    09.06.2004
    Ort
    Aachen
    Beiträge
    2.674
    Yepp! So ganz einfach sit das ganze jetzt allerdings nicht:

    1. Du musst irgendwo die Kanäle des ADCs umschalten, du hast zwar mehrere Kanäle, wo dann die Taster, oder die Lichtsensoren dranhängen, aber nur einen AD-Wandler. Du kannst also immer nur eine Sach zur gleichen Zeit messen.

    2. Die Messung muss irgendwie gestertet werden, entweder du lässt sie "free", dann misst er ununterbrochen, oder du sagst im, wann er starten soll mit einer! Messung.

    Die Interruptvektoren sind übrigens bei allen AVRs gleich. Außer natürlich denen, die kein UART oder ADC oder so haben.

    mikrocontroller.net ist auf jeden Fall ne gute Adresse!

  5. #5
    Benutzer Stammmitglied
    Registriert seit
    10.08.2005
    Beiträge
    32
    das macht die Sache natürlich etwas komplizierter...

    Im Prinzip wollte ich folgendes aus Java nachbauen:

    X SensorListner(Thread)
    1 MotorController(Thread)

    der MotorController startet mit niedriger Priorität und wird von den SensorListnern unterbrochen, wenn sie die Überschreitung eines Schwellwertes festgestellt haben.
    Sie setzen ebenfalls die Status-variable.

    Unter C würde das dann wohl so aussehen:

    main:
    - irgendwas abfragen, was den ADC Wandler braucht
    - Endlosschleife: Status abfragen => behandeln

    SIGNAL(SIG_ADC):
    - wert prüfen & ggf. status setzen
    - nächsten Sensor abfragen (z.B. LineData() aufrufen)

    beim letzten unkt bin ich mir aber noch unsicher, ob das nicht in einer endlosen Rekursion endet und den Haupt-thread blockiert...

  6. #6
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    09.06.2004
    Ort
    Aachen
    Beiträge
    2.674
    Ich würde es etwas anders machen:

    Main:
    *Endlosschleife start
    - Wähle ADC-Channel
    - Starte Messung
    - Tue was nicht zeitkritisches (irgendwas)
    *Endlosschleife stop

    ADC-Interruptroutine
    - Checken, was der ADC-Wert bedeutet (Licht oder Taster oder Odometrie)
    - Deutung, Anpassung...

    Taster-Interrupt
    - Wähle ADC-Channel Taster
    - Stoppe Motoren (evtl.)

    Also bei den Tastern hat man den Vorteil, dass man nicht permanent die Werte überwachen muss, sondern ein zusätzlicher Interrupt an INT1 ausgelöst (SIG_INTERRUPT1; VECTOR(2)) wird. Das ist wichtig, um den Motor möglichst schnell stoppen zu können. Es muss dann halt über ne ADC-Messung der Taster festgestellt werden welcher der 6 Taster (oder welche) gedrückt sind und entsprechend reagiert werden.

    Der ADC arbeitet übrigens nach Auswahl des Kanals und dem Start vollkommen im Hintergrund und wird nur durchd en Interrupt unterbrochen.

    Noch Fragen ?

  7. #7
    Benutzer Stammmitglied
    Registriert seit
    10.08.2005
    Beiträge
    32
    dazu muss ich wahrscheinlich die Messfunktionen etwas umschreiben, sprich $data = ADCL + (ADCH << in die SIG_ADC routine verlagern.
    Um zu gucken was ich gerade gemessen habe, kann ich ADMUX lesen?

    Die Anpassung würe ich jedoch in der main lassen, da man ggf. auf eine Zweite Änderung warten muss, bis man den in den Ursprungszustand zurückgeht denn so wie ich es verstanden habe blockieren SIGNAL Routinen das Hauptprogramm.

    Dann noch was zu den Tastern:
    was spuckt der AD-Wandler eigentlich aus, dass man "es" mit dieser komplizierten Formel erst umwandeln muss?

    angenommen ich nehme aus den Lese Methoden von asuro.c das eigentlich lesen des AD Wandlers aus, würde mein Code etwa so aussehen:

    [php:1:cbaae07140]#include "asuro.h"
    #define INITIAL 0
    #define BLOCKED 1

    unsigned char status = INITIAL;

    int main(void)
    {
    Init();
    StartSwitch();

    while(TRUE) {
    switch (status) {
    case BLOCKED:
    // zurücksetzen, z.B. LineData lesen
    break;
    //...
    default:
    LineData(IR_LEFT); // auch leicht abgewandelt
    // der Rest
    break;
    }
    }

    return 0;
    }

    SIGNAL(SIG_ADC) {
    unsigned int data = ADCL + (ADCH << ;

    switch (ADMUX) {
    case (1 << REFS0) | SWITCH:
    status = BLOCKED;
    break;

    case (1 << REFS0) | IR_LEFT:
    if(status == BLOCKED) {
    status = was_anderes
    }
    //data speichern, vergleichen, status setzen
    break;
    }

    }

    SIGNAL(SIG_INTERRUPT1) {
    MotorSpeed(0,0);
    PollSwitch();
    }[/php:1:cbaae07140]

    kommt das hin?

  8. #8
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    09.06.2004
    Ort
    Aachen
    Beiträge
    2.674
    Also...

    was spuckt der AD-Wandler eigentlich aus, dass man "es" mit dieser komplizierten Formel erst umwandeln muss?
    Wenn ich mich nicht verrechnet habe, müsste es ungefähr so sein. Links der ADC-Wert, rechts der Wert von Pollswitch() nach der Rechnung.

    678-682 --> 32
    812-821 --> 16
    903-915 --> 8
    956-970 --> 4
    985-1000 --> 2
    1001-1015 --> 1

    Durch den geschickten Einsatz von fließkomma und nicht fließkomma Zahlen kann man so runden.

    Code:
    return  ((unsigned char) ((( 1024.0/(float)i - 1.0)) * 63.0 + 0.5));
    Zum Code, ich muss zugeben, dass ich da nciht ganz durchgestiegen bin, aber müsste so eingeltich funktionieren. Wenn ich das richtig sehe, überprüfst du, was in ADMUX gesetzt ist und führst dann entsprechend aus (sinnvoll!). In der Hauptroutine prüfst du dann, ob noch irgendwas gemacht werden soll, oder "bocrmaler Code" laufen kann.

    Was meint status=blocked?

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •