Forum: Compiler & IDEs Uart - Empfangen


von Harald (Gast)


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

von Florian Pfanner (Gast)


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

von Harald (Gast)


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

von Ronny Schulz (Gast)


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.

von Harald (Gast)


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

von Harald (Gast)


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

von Rahul (Gast)


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.

von Harald (Gast)


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

von Rahul (Gast)


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... ;)

von Harald (Gast)


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

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.