-         

Ergebnis 1 bis 7 von 7

Thema: Analoge Ports ansteuern

  1. #1
    Neuer Benutzer Öfters hier
    Registriert seit
    14.01.2005
    Beiträge
    27

    Analoge Ports ansteuern

    Anzeige

    Hi

    Ich benutze das Board von Robtikhardware Mega32....
    Dazu habe ich 2 Getriebemotoren, welche einen Umdrehungssensor (Lichtschranke haben)
    Nun möchte ich eine funktion, welche die Umdrehungen der Räder misst...
    Wenn eine gewisse Anzahl umdrehungen erreicht ist, soll die Funktion eine Rückmeldung geben. Wie realisiere ich dies?

  2. #2
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    08.08.2004
    Ort
    Zwolle
    Alter
    61
    Beiträge
    531
    Angenommen die Lichtschranke liefern ein digitalse signal '0' und '1'.

    die einfachste (nicht schonsten) losung:

    1. Lichtschrank an einem eingang anschliessen
    2. eingang continuierlich abfragen ob eingang '0' ist, wenn '1', weitergehen
    3. dann ein timer starten
    4. eingang continuierlich abfragen ob eingang '1' ist, wenn '0', weitergehen

    5. timer auslesen
    6. wieder bei 2. anfangen

    die timerwert ist ein mass fur die geswindigkeit


    wie wurde ich dass machen?

    Ich verbinde die lichtschrank mit einem mikrokontroller interrupt eingang.
    Jedes mahl dass die lichtschrank von '0' nach '1' oder umgekehrt schaltet wird die interrupt function angerufen. In die interrupt function erhohe ich ein zahler variabele A.

    ich configuriere ein timer so dass er 1 sekunde braucht um von einen voher betimmten startwert bis zum maxwert (beim hochzahlen) oder minwert (beim zuruckzahlen) ein interrupt generiert. In die interrupt software wird dan die startwert aufsneu geschrieben fur die nachtste sekunde. In die interrupt function lese ich die zahler variabele A (ein mass fur die geswindigkeit) und mache etwas damit und mache A wieder 0.

    nur so einige ideen, bin uberzeugt gibts fast noch eine menge andere

    gruss

    Henk

  3. #3
    Neuer Benutzer Öfters hier
    Registriert seit
    14.01.2005
    Beiträge
    27
    Ich möchte eine interrupt-Funktion schreiben, aber ich habe eben keine Ahnung, wie dies funktioniert, aus diesem Grund währe ein Beispiel sehr praktisch...

    das 2. Problem ist, dass die Lichtschranke nicht immer einen gleichen Spannungswert liefert (aus diesem Grund kann ich keinen Digitalen Port brauchen) Wie lesen ich aber einen Port aus? (wenn ich die Adresse weiss)????

    3. Wie programmiere ich einen Timer ein?

    Wenn ich je ein Beispiel haben könnte, zu den drei Problemen, würde ich den Rest scho irgendwie hinkriegen....

    Vielen Dank!

  4. #4
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    07.02.2005
    Ort
    Wels
    Alter
    55
    Beiträge
    512
    @ Arexx-Henk:

    cool, danke!
    so stell ich mir antworten vor!
    man braucht ja nicht immer einen code, es geht ja viel öfter einfach nur um die vorgehensweise...
    danke, hat zwar jetzt nicht mit dem thema zu tun, aber mir hilfts weiter
    mfg knacki

  5. #5
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    08.08.2004
    Ort
    Zwolle
    Alter
    61
    Beiträge
    531
    @addict

    wass betrift interrupts, ein beispiel fur eingang INT0/PD2/pin16


    //algemeine interrupt einschalten (sonst lauft uerhaupt kein einziges interrupt)
    SREG|=(1<<7);

    //speziales interrupt fur eingang INT0/PD2/pin16 einschalten
    GICR|=(1<<INT0);

    //interrupt soll entstehen wenn eingang INT0/PD2/pin16 von hoch zu niedrich geht
    MCUCR|=(1<<ISC01) | (1<<ISC00);

    //dazu sollte man INT0/PD2/pin16 als eingang schalten
    DDRD&=^(1<<PD2);

    //diese function, wenn so geschrieben, wird vollautomatisch, jedesmahl ausgefuhrt, so oft wie die eingang INT0/PD2/pin16 niedrich geht
    SIGNAL SIG_INTERRUPT0
    {
    //mache etwas, ein LED an/aus
    }


    Da gibts so 15 verschiedene art von interrupts die sind alle definiert in die datei iom32.h irgendwo auf deinem computer.
    z.B. ein interrupt, immer wenn timer0 hoch zahlt und dann von 0xFF nach 0x00 weiter zahlt.

    Ein interrupt wird automatisch ein laufendes program unterbrechen, die interrupt function wird ausgefuhrt, und wenn die interrupt function fertig ist, geht das laufende program wieder weiter wo es geblieben war gerade vor dem interrupt unterbrechung.

    gruss

    Henk

  6. #6
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    08.08.2004
    Ort
    Zwolle
    Alter
    61
    Beiträge
    531
    @addict

    Wie lesen ich aber einen Port aus? (wenn ich die Adresse weiss)????

    Mit 'C' ein port auslesen zb PortB auf adress 0x16


    #define PINB _SFR_IO8(0x16)
    #define DDRB _SFR_IO8(0x17)
    #define PORTB _SFR_IO8(0x1


    //wenn PB0/XCK/T0/pin1 hoch ist,
    if ( PINB & 0x01 )
    {
    //mach etwas
    }



    oder


    unsigned char MeinWert ;
    MeinWert = PINB ;
    if ( MeinWert & 0x01 )
    {
    //mach etwas
    }



    PortB sieht so aus
    Code:
    bit7 bit6 bit5 bit4 bit3 bit2 bit1 bit0
    PB7  PB6  PB5  PB4  PB3  PB2  PB1  PB0
    pin8 pin7 pin6 pin5 pin4 pin3 pin2 pin 1
    Ports lassen sich bytewise/bitwise lesen/schreiben.
    Pas mahl auf! Data schreibt man nach PORTB und data liest man von PINB.
    Wenn mann PORTB lehst, lehst mann nur die weggeschriebene wert wieder zuruck und nicht die elektrischen pin-status
    (hat mich schon manche Stunde gekostet)


    #define PINB _SFR_IO8(0x16) usw
    brauch mann nicht selber zu definieren, diese definitionen bevinden sich im datei iom32.h


    gruss

    Henk

  7. #7
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    08.08.2004
    Ort
    Zwolle
    Alter
    61
    Beiträge
    531
    @addict
    2. Problem ist, dass die Lichtschranke nicht immer einen gleichen Spannungswert liefert (aus diesem Grund kann ich keinen Digitalen Port brauchen)
    analogue port benutzen


    3. Wie programmiere ich einen Timer ein?
    Die Atmega32.pdf studieren.

    beispiel timer0
    Timer0 zahlt hoch bis 255 (0xFF) und fangt dan wieder bei 0 an.

    //prescaler (Getriebegehause) /256 nutzen, macht die taktfrequenz vom timer0: 8Mhz (externen oszillator) / 256 = 31,250KHz. TCCR0 |= (1<<CS02);

    Jetzt fangt die timer0 an zu laufen.


    timer0 zahlt bis 255, so angesteurt mit 31,250KHz mach 1/31250 = 32us pro schritt.
    256 (0 bis 255) schritte mahl 32us = 8192us = 8,192ms so lange daurt jeden 'rundgang'.

    Jetzt kan mann register TCNT0 auslesen und wird immer ein anderen Wert bekommen. TCNT0 ist die aktuellen timer wert.

    //Da blinkt die LED an jedes mahl wenn timer0 64 ist und blinkt aus wenn timer0 186 ist.
    //so jeden 8,192ms geht die LED mahl an und aus, (mit die augen nicht zu sehen, sollte nur etwas weniger hell leuchten.
    while(1){
    if(TCNT0==64)
    {
    //mach LED an
    }
    if(TCNT0==186)
    {
    //mach LED aus
    }
    }

    Die timer0 lauft hardwaremassig unabhangig vom programablauf.

    Mann kann beliebig die aktuellen timerwert andern, zb mit TCNT0=33;, da fangt die timer direkt an weiter zu zahlen ab 33.

    mit dem prescaler (Getriebegehause) kann mann die timer anhalten.
    Bit 0,1 und2 niedrich machen.
    TCCR0 &= ~((1<<CS02)|(1<<CS01)|(1<<CS00));

    Dass auslesen vom TCNT0 liefert jetz immer dieselben wert.

    gruss

    Henk

Berechtigungen

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