www.mikrocontroller.net

Forum: Compiler & IDEs Uart - Empfangen


Autor: Harald (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

Ich wollte gestern meinen Uart dazu bringen Daten zu empfangen. Leider
haut das nicht so hin wie ich mir dass erhofft habe.

Ich verwende folgenden Code. [steht im Datenblatt des MC's]

/*****************************************/
unsigned char USART_Receive( void )
{
/* Wait for data to be received */
while ( !(UCSRA & (1<<RXC)) )
;
/* Get and return received data from buffer */
return UDR;
}
/*****************************************/

Ich dachte mir ich rufe die Funktion in der Interruptroutine auf,
jedoch kommt er erst gar nicht soweit.

SIGNAL(SIG_UART_RECV) {
  unsigned char recv ='d';

  recv = USART_Receive();
  SendeString("Test");

}

Weiss jemand von euch weiter ?

mfG Harald

Autor: Florian Pfanner (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

wieso rufst du in einer Interruptroutine für den Receive-Complete
nochmal eine schleife auf, welche prüft ob das Zeichen empfangen
wurde????
Versuchs mal so:

SIGNAL (SIG_UART_RECV) {
  unsigned char recv;

  recv=UDR;         //Zeichen vom Register holen
  UDR=recv;         //Zeichen zurücksenden
}

Müsste gehen. Wenn nicht, so poste bitte den kompletten Code, besonders
die Initialisierung des UARTs.

Gruß, Florian

Autor: Harald (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Funktioniert leider nicht. Unten sind auszüge aus meinem Programm.



int main(void)
{


    DDRB = 0x02;
    DDRA = 0xE7;


    TCCR0 = _BV(CS02) | _BV(CS01) | _BV(CS00);
    USART_Init(25);
                SendeString("Start"); // Senden funktioniert!!
          sei ();

    int bisLeft = 0;
    int bisRight = 0;
    int counterLeft=0;
    int counterRight = 0;
    char buffer[100];
    int n = 1;
    int pressed = 0;
    while (1) {


      // Umdrehungen der Räder - Berechnung und Ausgabe

      if (bit_is_set (PINA, PINA3)) {
        if (bisLeft==0) {
          n = sprintf(buffer,"Counter Left : %d Counter Right : %d \r",
counterLeft, counterRight);
          SendeString(buffer);
          counterLeft++;
          bisLeft = 1;
        }
      } else {
        bisLeft = 0;
      }


      if (bit_is_set (PINA, PINA4)) {
        if (bisRight==0) {
          counterRight++;
          n = sprintf(buffer,"Counter Left : %d Counter Right : %d \r",
counterLeft, counterRight);
          SendeString(buffer);
          bisRight = 1;
        }
      } else {
        bisRight = 0;
      }



      // Switch der Direction
      if (bit_is_clear (PINB, PINB0) && (pressed ==0)) {

        n = sprintf(buffer,"\n\r***\n\r");
        SendeString(buffer);
        n = sprintf(buffer,"direction: %d",direction);
        SendeString(buffer);
        n = sprintf(buffer,"\n\r***\n\r");
        SendeString(buffer);
        direction = switchState(direction);
        pressed = 1;

      } else
      {
        if (pressed > 0) {
          pressed++;
          if (pressed == 10000)
            pressed = 0;
        }
      }




      //
      //usartReceive = USART_Receive();
      //USART_Transmit(usartReceive);

      //if (usartReceive == 'w')
      //  MotorLeftForward();

      // Ausgleich der Räder

      //if (counterLeft > counterRight) {
      //  MotorLeftStop();
      //}  else
      //  MotorLeftForward();




    }


  /*********************************************************************** 
*******/

  return 0;

}



void USART_Init( unsigned int baud )
{
  /* Set baud rate */
    UBRRH = (unsigned char)(baud<<8);
    UBRRL = (unsigned char) baud;
  /* Enable receiver and transmitter */
    UCSRB = (1<<RXEN)|(1<<TXEN);
  /* Set frame format: 8data, 2stop bit */
    UCSRC = (1<<URSEL)|(1<<USBS)|(3<<UCSZ0);
}



SIGNAL (SIG_UART_RECV) {
  unsigned char recv;

  recv=UDR;         //Zeichen vom Register holen
  UDR=recv;         //Zeichen zurücksenden
}


mfG Harald

Autor: Ronny Schulz (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
DU musst ihm auch sagen, dass er den Interrupt auslösen soll, wenn ein
Zeichen reinkommt. Einfach in UCRSB noch RXCIE einsetzen und mit sei()
die Interrupts aktivieren.

Was da in UBRRH und UBRRL steht sieht auch sehr merkwürdig aus. Da
solltest Du nochmal nachschauen.

Autor: Harald (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Vielen Dank. Ich werde es gleich heute Abend ausprobieren. Scheint mir
ja ganz einleuchtend :) Das mit UBRRH und UBRRL  und müsste eigentlich
passen ( da setze ich die Baudrate und senden funktioniert bestens.

mfG Harald

Autor: Harald (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Funktioniert bestens :)

Jedoch habe ich mittlerweile ein anderes Problem. Ich wollte meinen
Roboter durch eine IR - Fernsteuerung steuern. Solange die Motoren
nicht angeschlossen sind funktioniert alles bestens. Aber ab dem
Zeitpunkt an dem ich die Motoren anschliesse funktioniert es nicht
mehr. Bzw. es funktioniert aber er läuft alle Zustände ( vor, zurück,
links, rechts, stop ) durch, solange bis die Motoren Stoppen. Das
heisst er empfängt immer wieder ir signale. Das Ganze wurde entprellt
er wartet also bis ein zähler auf 10000 ist ( entspricht etwa einer
sekunde) bis er überhaupt weiter zählt. Könnte dass die Streuspannung
der Motoren sein ? Ich verwenden einen L293D Motortreiberchip der
eigentlich schon dioden eingebaut haben sollte die das verhindern.
Falls jemand eine Antwort weiss ich wäre wie immer sehr dankbar :)

mfG Harald

Autor: Rahul (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hast Du Block-Kondensatoren an deinen ICs? Sind die Motoren entstört?
Vielleicht hängt es irgendwie mit den Spannungsspitzen zusammen, die
Motoren beim Ausschalten erzeugen.
Poste doch mal den Schaltplan, da kann man dann eher was zu sagen.

Autor: Harald (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich habe nun einen Elektrolytkondensator dazugebaut und nun funktioniert
es. Obwohl er nach wie vor zufällig etwas empfängt ( selten ), ist
jedoch nicht so tragisch da ich diese Bitmuster einfach nicht
verwende.

Vielen Dank für eure Hilfe.

mfG Harald

Autor: Rahul (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Du solltest jedem IC einen 100nF Kondensator spendieren. Die sind
schneller im Ladungsausgleich als Elkos.
Sie sollten auch möglichst dicht am IC sitzen (es gibt IC-Sockel mit
integriertem Bunkerkondensator), da lange Leiterbahnen wiederum einen
Widerstand darstellen...
Die Kondensatoren sorgen einfach nur dafür, dass bei besonderer
Belastung der Spannungsquelle die Spannung am IC nicht zu sehr
zusammenbricht. (so, genug kluggeschissen... ;)

Autor: Harald (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ok, werd ich machen.

danke

apropos motoren: ich verwende einen L293D chip, der dioden eingebaut
hat die den induzierten strom der motoren stoppen sollte. dachte ich
jedenfalls.
danke nochmals wegen dem tip mit den kondensatoren. klingt recht
einleuchtend.

mfG Harald

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.