-         

Ergebnis 1 bis 4 von 4

Thema: LED-Steuerung und Kamera-Triggerung mit dem Mega32

  1. #1

    LED-Steuerung und Kamera-Triggerung mit dem Mega32

    Anzeige

    Moin!
    Ich bin recht neu in der µC Welt und bräuchte mal einen Ratschlag:

    Ich möchte nach dem Empfang eines Zeichens über RS232 hin für eine Bestimmte Zeit eine LED mit einem PWM-Signal(niedrig) ansteuern und danach für die gleiche Dauer mit einem zweiten PWM-Signal. Außerdem soll jeweils für die Zeit ein Pin auf "1" gesetzt werden.

    Die "Teilaufgaben" habe ich bis auf die Dauer schon gelöst, dh ich kann über das Hyperterminal Werte für die PWM an den Controller schicken und den Wert für die PWM ändern. Nun ist die Frage, wie ich am Besten die "Verzögerung" realisiere.

    Meine Idee ist es in main auf den "Befehl" zu warten. Wenn der "Befehl" kommt möchte ich den ersten PWM-Wert laden, den Kameratrigger setzen und einen Timer starten. Wenn der Timer "überläuft" stoppe setze ich das Triggersignal auf 0, setze den zweiten PWM-Wert und ein Flag. Dann setze ich das Triggersignal wieder und starte den Timer erneut. Wenn der Timer diesmal überläuft, wird er nicht neu gestartet, das Flag zurückgesetzt und die PWM-gestoppt und das Triggersignal wird auf "0" gesetzt.

    Kann jemand einen Fehler in der Logik oder dem Stil erkennen oder hat gar eine bessere Lösung?

    Danke im Voraus!

    P.S.: Falls es von Belang ist, ich benutze das Pollin Evaluation Board 2.0

  2. #2
    Moin!

    Ich habe schonmal etwas Code zusammengebastelt, kann ihn aber noch nicht "in der Praxis" testen.

    Wäre nett, wenn ihn sich jemand anschauen würde und mich auf Fehler hinweisen bzw Verbesserungsvorschläge abgeben könnte.

    Ach ja, das Triggersignal soll an PortD.6 ausgegeben werden und das pwm-Signal erscheint an PortB.1 (Soll es zumindest).

    [php:1:2054a8c87f]#include <avr/interrupt.h>

    #define BAUD 9600
    #define F_CPU 16000000
    #define UBRR_BAUD ((F_CPU/(16UL*BAUD))-1)

    volatile int brightness = 10;
    volatile int oldBrightness = 10;
    volatile int flash1 = 0;
    volatile int flash2 = 0;
    volatile int flashLevel = 0;

    void uart_init(void)
    {
    // Baudrate einstellen ( Normaler Modus )
    UBRRH = (unsigned char) (UBRR_BAUD>>;
    UBRRL = (unsigned char) UBRR_BAUD;

    // Aktivieren von Receiver und Transmitter
    UCSRB = (1<<RXEN)|(1<<TXEN);

    // Einstellen des Datenformats: 8 Datenbits, 1 Stoppbit, keine Parität
    UCSRC = (1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0);
    }

    int write_char (unsigned char *buffer)
    {
    // Warten bis der Sendepuffer frei ist
    while ( !( UCSRA & (1<<UDRE)) );

    // Daten in den Puffer schreiben und damit senden
    UDR = *buffer;

    // Nach Linefeed ein Return senden
    if (*buffer == 10)
    {
    while ( !( UCSRA & (1<<UDRE)) );
    UDR = 13;
    }

    // Nach Return ein Linfeed senden
    if (*buffer == 13)
    {
    while ( !( UCSRA & (1<<UDRE)) );
    UDR = 10;
    }

    return 0;
    }

    int write_string(unsigned char *string)
    {
    while (*string != 0)
    {
    write_char(string);
    string++;
    };

    return 0;
    }


    int read_char(unsigned char *buffer)
    {
    int rec;

    // testen ob Daten empfangen wurden
    rec = (UCSRA & (1<<RXC));

    if (rec)
    {
    // Empfangsregister auslesen
    *buffer = UDR;
    }

    return rec;
    }

    /************************************************** **
    * Timer-Interruptroutine für die Belichtungszeit (330ms)
    ************************************************** ***/
    ISR(TIMER1_OVF_vect)
    {
    if(flashLevel == 1)
    {
    //Kamera-Trigger ausschalten
    Kamera_Trigger &= ~(1 << 6);
    |= (1 << 6);
    _CLI();
    //flag für Blitzstufe erhöhen
    flashLevel = 2;

    //PWM-Wert für die Zweite Blitzstufe setzen
    OCR0A = flash2;
    sei();
    //Kamera-Trigger einschalten
    Kamera_Trigger |= (1 << 6);

    }
    else if(flashLevel == 2)
    {
    _CLI();
    //Kamera-Trigger ausschalten
    Kamera_Trigger &= ~(1 << 6);

    //flag für Blitzstufe
    flashLevel = 0;
    sei();
    //PWM-Wert für die Beleuchtung setzen
    OCR0A = brightness;
    }
    }
    /************************************************** **
    * Hauptprogramm
    ************************************************** ***/
    int main()
    {
    //===========================================
    // Konfigurationen
    //===========================================
    //Buffer für Eingaben
    unsigned char buffer;
    // Port D 5 (LED1)wird als Ausgang bestimmt.
    DDRD |= _BV(PD5);

    // Port D 2 (Taster1) wird als Input festgelegt.
    DDRD &= ~_BV(PD2);
    uart_init();TCCR1B = (1<<CS10);

    //Timer0 als PWM einstellen PortB3
    TCCR0 = (1<<WGM01)|(1<<WGM00)|(1<<COM01);
    //Prescaler von 256 für 62,5kHz
    TCCR0 = (1<<CS02);
    //Startwert für die Helligkeit initialisieren
    OCR0 = brightness;


    //Timer1 als Timer schalten
    TCCR1 = (1<<C12); // Prescaler von 1 | CTC-Modus (siehe unten für Beschreibung)
    TCNT1 = 44911; // Vergleichswert um nun 330ms zu Zählen


    DDRD = (1<<6);
    //Timer 0 (PWM) starten
    TIMSK = (1<<OCIE0);
    //Interrupts freigeben
    sei();

    //Startmeldung ausgeben
    write_string("Controller gestartet...\n");


    //===========================================
    // Hauptprogramm
    //===========================================
    while(1)
    {
    // RS232 abfragen
    if(read_char(&buffer))
    {
    int controlWord = (int)buffer & 192;
    int data = (int)buffer & 63;
    switch(controlWord)
    {
    //Helligkeit ausgeben
    case 0: buffer = (char)brightness; write_string(&buffer);break;
    //Helligkeit setzen
    case 128:
    {
    if(data < 10)
    {
    brightness = data << 1;
    _CLI();
    OCR0A = brightness;
    sei();
    }
    }; break;
    //blitzstufe setzen und aufnahme starten
    case 192:
    {
    if(data < 16)
    {
    flash1 = data;
    flash2 = (data << 4);
    _CLI();
    OCR0A = flash1;
    flashLevel = 1;
    //Kamera-Trigger einschalten
    Kamera_Trigger |= (1 << 6);
    //Timer1 Starten
    TIMSK |= (1<<OCIE1A);
    sei();
    }
    }; break;
    }
    }
    }
    return 0;
    }[/php:1:2054a8c87f]

  3. #3
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    21.10.2005
    Ort
    Erde
    Alter
    50
    Beiträge
    1.195
    In der TIMER1_OVF_vect cli() und sei() jeweils vor bzw. nach den ifs.

    Ich weiss nicht, ob die _BV Makros in den neuen versionen des avr_gcc noch verwendet werden. Aber Du solltest die auf jeden fall einheitlich benutzen (mal hast Du _BV verwendet, ein anderes mal verwendest Du normale shifts).

  4. #4
    Danke für die Antwort!

    Ich habe aber das Problem in der Zwischenzeit anders gelöst. Ich habe mir nun mit _delay_ms() meine Verzögerungen gebastelt und schalte so nach gewissen Zeiten den Trigger und die PWM für die LED um. Heute habe ich den Spaß mal ausprobiert und es scheint gut zu funktionieren.

    Schönes Wochenende!

Berechtigungen

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