- 3D-Druck Einstieg und Tipps         
Seite 1 von 2 12 LetzteLetzte
Ergebnis 1 bis 10 von 11

Thema: UART mit INTERRUPT in C

  1. #1
    Neuer Benutzer Öfters hier
    Registriert seit
    08.08.2004
    Ort
    61169 Friedberg
    Alter
    40
    Beiträge
    7

    UART mit INTERRUPT in C

    Anzeige

    LiFePo4 Akku selber bauen - Video
    Hi,

    ich habe ein echtes Problem mit dem UART. Ich möchte Daten zwischen meinem PC und dem Atmega 32 austauschen.

    Da ich nicht möchte das der Atmega 32 in der schleife fest steckt bis er etwas über die Comport Leitung vom PC empfängt. Dachte ich mir das ich das mit einem Interrupt versuche.

    Ich kann den Interrupt jedoch nicht aktivieren/einstellen.
    Hab schon alles mögliche versucht aber nix ging.

    Hab dann auch etwas auf der roboternetz Seite gefunden das einem zeigt wie genau mann vor zu gehen hat. Um mit dem UART-Interrupt arbeiten zu können.

    Das soll dann so fuktionieren:
    1) Konfiguriere Interrupt
    2) generell Interrupts zulassen
    3) schalte speziell den InterruptXXX ein
    4) verzweige bei InterruptXXX zu SprungXXX

    Das ganze ist hier zu finden:
    https://www.roboternetz.de/wissen/in...com_Interrupts

    Mit den Punkten 1 und 3 komme ich nicht zurecht hab keine ahnung wie mann das macht.
    Mein Programm sieht etwa so aus:

    Code:
    #include <avr/io.h>
    #include <avr/interrupt.h>
    #define USART_RXC_vect	         _VECTOR(14)
    
    #include <avr/delay.h>
    	            
    /* USART-Init beim ATmega16 */
    #ifndef F_CPU
    #define F_CPU 16000000           /* Oszillator-Frequenz in Hz */
    #endif
    // Hilfsmakro zur UBRR-Berechnung ("Formel" laut Datenblatt)
    #define UART_UBRR_CALC(BAUD_,FREQ_) ((16000000)/((19200)*16L)-1)
    #define UART_BAUD_RATE 19200
    
    
    char c = 97;
    int main(void)
    {
    ///////////////////////////////////////////interrupt für UART einstellen
    /*1*/
    /*2*/sei();
    /*3*/
    /*4*///steht oben
    ////////////////////////////////////////////
    
    ///////////////////////////////////////////UART einstellungen
        UCSRB |= (1<<TXEN);                // UART TX einschalten
        UCSRC |= (1<<URSEL)|(3<<UCSZ0);    // Asynchron 8N1 
        UBRRH = (uint8_t)( UART_UBRR_CALC( UART_BAUD_RATE, F_CPU ) >> 8 );
        UBRRL = (uint8_t)UART_UBRR_CALC( UART_BAUD_RATE, F_CPU );
    //////////////////////////////////////////////////  
    
     while(c != 300)
    {
      UCSRB |= (1<<TXEN);         // UART TX einschalten
      UDR = c;
      _delay_ms(200); 
    }
    }
    
    ISR(USART_RXC_vect) /* veraltet: SIGNAL(SIG_UART_RECV) */
    {
       while (!(UCSRA & (1<<RXC)))   // warten bis Zeichen verfuegbar
       c = UDR;
    }
    Zum Code(so soll es sein):
    Ich schicke zu beginn ein kleines a vom controller zum PC (welches ich auch ohne Probleme am PC empfangen kann), danach sende ich ein irgent ein zeichen z.b. ein x vom PC zum Controller. Dieses Zeichen soll der Controller dann mit hilfe des Interrupts aufnehmen(damit er nicht in der Schleife für das Daten Empfangen fest hängt) und dann wieder zum PC zurück schicken.

    Das einziegste was der Controller macht, ist mir immer nur das a zu schicken.

    Ich hoffe es kann mir jemand dabei helf damit es richtig funktioniert.

    Gruß Nemesis

  2. #2
    Benutzer Stammmitglied
    Registriert seit
    03.10.2007
    Beiträge
    68
    Hallo nemesis,

    hier ist eine gute Anleitung zum Compiler und zum AVR:
    http://www.mikrocontroller.net/artic...R-GCC-Tutorial

    Grüße

  3. #3
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    08.05.2005
    Ort
    Issum
    Alter
    52
    Beiträge
    2.236
    Hallo,
    wie willst Du was empfangen, wenn Du den Empfänger nicht einschaltest

    das geht so,
    Code:
     UCSRB = (1<<RXEN)|(1<<TXEN)|(1<<RXCIE);
    Jetzt kannst Du senden,empfangen und der Interrupt ist eingescheltet, der für den Empfang zuständigt ist.
    Im einfachstem Fall machst Du ein Echo:
    Code:
     ISR (USART_RXC_vect) {
      uint8_t tmp = UDR;
      UDR = tmp;
    }
    Du brauchst hier auf nichts zu warten, weil das Zeichen schon da ist
    Wichtig ist nur, das UDR auch ausgelesen wird!
    willst Du aus dem Hauptprogramm was senden, mußt Du UDRE testen:
    Code:
    while(!(UCSRA & (1<<UDRE)));
          UDR = 'a';
    Gruß sebastian
    Software is like s e x: its better when its free.
    Linus Torvald

  4. #4
    Neuer Benutzer Öfters hier
    Registriert seit
    08.08.2004
    Ort
    61169 Friedberg
    Alter
    40
    Beiträge
    7
    Hallo Sebastian,

    hab eben ausprobiert was du geschrieben hast und nun funktioniert es.
    Da rauf wäre ich so schnell wohl nicht gekommen, vielen dank.

    Allerdings gibt es noch ein kleines problem. Und zwar habe ich eine globale Variable "char c = 'a'; ". Wenn der Interrupt ausgelöst wird, wird das Hauptprogramm gestopt und der Controller sprinkt in die Funktion vom Interrupt.
    In dieser Funktion lasse ich mir dann das Zeichen welches ich vom PC gesendet habe (z.b. x) zurück zum PC schicken. Wie schon gesagt das klappt jetzt bestens. Aber ich möchte das das x nun das a in der Variablen c ersetzt. Das funktioniert jedoch nicht und ich hab keine ahnung warum nicht.

    Vielleich hat dafür jemand ne Lösung.

    Gruß Nemesis

  5. #5
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    06.02.2005
    Ort
    Hamburg
    Alter
    38
    Beiträge
    4.255
    Ist c als volatile deklariert?

  6. #6
    Neuer Benutzer Öfters hier
    Registriert seit
    08.08.2004
    Ort
    61169 Friedberg
    Alter
    40
    Beiträge
    7
    Hab zwar keine ahnung was volatile macht aber nun geht alles.

  7. #7
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    08.05.2005
    Ort
    Issum
    Alter
    52
    Beiträge
    2.236
    Das ist aber schlecht,
    Als (angehender) C Programmierer sollte man es schon wissen

    Zugegeben, bei PC Programmierung sieht man volatile seltener, aber google hilft hier weiter:
    http://www.google.com/search?client=...utf-8&oe=utf-8
    wühl Dich da mal durch...

    Gruß Sebastian
    Software is like s e x: its better when its free.
    Linus Torvald

  8. #8
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    06.02.2005
    Ort
    Hamburg
    Alter
    38
    Beiträge
    4.255
    volatile sagt dem Compiler, dass die Variable von anderen Stelle aus geändert werden kann. Es greifen ja das Hauptprogramm und der Interrupt darauf zu. Ohne volatile denkt der Compiler, dass die Variable immer gleich bleibt, wenn sie nicht im Hauptprogramm geändert wird. Er lädt sie darum zb nicht immer aus dem RAM, sondern puffert sie vielleicht in einem Register. Wenn das Hauptprogramm nie was an c ändert, kann der Compiler daraus sogar ne Konstante machen. Egal wie er hier optimiert, das Ergebnis ist, dass das Hauptprogramm nicht mitbekommt, dass im Speicher für c schon ein neuer Wert steht.

  9. #9
    Neuer Benutzer Öfters hier
    Registriert seit
    08.08.2004
    Ort
    61169 Friedberg
    Alter
    40
    Beiträge
    7
    Naja bin eigentlich E-Techniker und hatte erst 2 Semester C-Programmierung.
    Doch da kam sowas nicht vor. Aber gut das ich es nun weis.

    Ihr habt mir Heute echt gut und schnell geholfen vielen Dank nochmal.

    Gruß Nemesis

  10. #10
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    29.07.2007
    Beiträge
    386
    ....Zugegeben, bei PC Programmierung sieht man volatile seltener, .....

    es ist keine schande , wenn man nicht weiss, wo man volatile setzen muss.
    auch c-fachleute scheitern daran, weil jeder c-compiler die werte anders handhabt. mal bleiben die werte der variablen erhalten, mal sind sie weg...lol... das ist c.

    gerade das scheiss winavr-c lässt ein manchmal im stich, hier ist es angebracht, fast alles volatile zu setzen um diese fehlerquelle erst einmal auszuschliessen.


    mfg

Seite 1 von 2 12 LetzteLetzte

Berechtigungen

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

Solar Speicher und Akkus Tests