Forum: Mikrocontroller und Digitale Elektronik serielle Schnittstelle, eigene Hardware, kann nicht empfangen


von Marian S. (ramsem2)


Angehängte Dateien:

Lesenswert?

Hallo, ich versuche bei dieser Platine über die seriellen Schnittstelle 
zu kommunizieren.

Ich kann etwas an die serielle Schnittstelle aussenden. Das 
funktioniert.
Aber es gelingt mir nicht etwas zu empfangen.

Eigentlich möchte ich ein großes "S" empfangen. Die Programmsequenz 
hierfür füge ich unten ein. Nachdem ich etwas senden kann, muss ich die 
Parametereinstellungen von Baudrate,Parity etc. ja eigentlich richtig 
getroffen haben.

Die Frage ist nun, ob der Fehler in der Schaltung oder in der Software 
liegt.

Ich hoffe jemand kann mir helfen.

Hier sind meine Einstellungen für die serielle Schnittstelle:
#include <avr/io.h>

#include "uarts.h"

void initUarts(void)
{
    //9600 N,8,2 fuer Uart0
    //fosc = 10MHz

    UBRR0L = 64;
    UCSR0B = (1<<TXEN0) | (1<<RXEN0);
    UCSR0C = (0<<USBS0) | (3<<UCSZ00);

}

void charUart0(char ch)
{
    UDR0 = ch;

    while(!(UCSR0A&(1<<UDRE0)))
        ;
}

void strUart0(char *str)
{
    while(*str)
    {
        charUart0(*str++);
    }
}

bool isUart0(void)
{
    return UCSR0A & (1<<RXC0);
}

char getUart0(void)
{
    while(!isUart0())
        ;
    return UDR0;
}


Und hier der Code fürs empfangen

Als erstes der Interrupt:

//Interrupt
ISR(USART0_RX_vect)
{
  char send = getUart0();
  if(send != '\n' || send != '\r')
  {
    strEmpfaenger[strPosition] = '\0';
    strPosition = 0;
    strFinish = true;
  }
  else
  {
  strEmpfaenger[strPosition++] = send;
  strFinish=false;
  }
}

DAs init sieht wie folgt aus:
void main(void)
{
    init();

    if(strFinish==true)
    {
        PORTA = 0xFC; //Wenn was ankommt leuchtet
        if(strcmp(strEmpfaenger,"S")==0)  //Ist der ankommende String 
ein S?
        {
      hilfe = 1;    //Dann setzte Hilfe auf 1
      PORTA = 0xF3;  //Wenn ein S empfangen leuchtet die Platine
        }
    }
}

Das Init habe ich auch vorher gemacht.

void init(void)
{
    DDRA = 0xFF;
    PORTA = 0xFF;
    initUarts();
    sei();
}

von Heinz V. (heinz_v)


Lesenswert?

normalerweise arbeitet die RS232 Schnittstelle mit den Pegeln:

-12V = H / +12V = L

den Empfang vom PC zum ATMega könnte man mit Spannungsteiler + Diode 
machen, aber das Senden geht nicht ohne zusätzlich neg. Hilfsspannung.

BTW: Tx (senden) liegt an der Basis der Transistoren?

bau das doch mit dem Altbewährten MAX232, der erzeugt die benötigten 
Spannungen selbst. (Schaltplan hier auf der Seite im AVR Tutorial)

von spess53 (Gast)


Lesenswert?

Hi

An welcher Stelle wird der Interrupt zum Empfangen freigegeben?

MfG Spess

von c-hater (Gast)


Lesenswert?

Marian S. schrieb:

> Ich kann etwas an die serielle Schnittstelle aussenden. Das
> funktioniert.
> Aber es gelingt mir nicht etwas zu empfangen.

Hier wäre erstmal wichtig, welche Seite du meinst, wenn du von Senden 
und Empfangen sprichst, denn tatsächlich kommt Kommunikation erst dann 
zustande, wenn gleichzeitig gesendet und empfangen wird...

> Die Frage ist nun, ob der Fehler in der Schaltung oder in der Software
> liegt.

Das läßt sich schwer entscheiden, weil du zu der Schaltung nicht gesagt 
hast, welche Aufgabe sie eigentlich zu erfüllen hat. Irgendeinen Sinn 
ergibt sie jedenfalls nur, wenn man mal annimmt, daß der "außen" 
anzuschließende Kommunikationspartner keine übliche PC-Schnittstelle 
ist, sondern ebenfalls ein µC oder irgendein Com-Adapter (USB oder BT). 
Und (was das auch immer für ein Teil ist) mit kleineren Logikpegeln 
arbeitet als der Atmega, aber mit derselben Polarität.

Ist das tatsächlich der Fall?

von public (Gast)


Lesenswert?

Hey,

Wie verbindest du denn deine serielle schnitte vom pc zum uC? willst du 
denn das board überhaupt mit dem pc verbinden?

gibt es noch irgend eine hardware die du benutzt, hier aber nicht kund 
getan hast?

Beste grüsse
Public

von Marian S. (ramsem2)


Lesenswert?

Entschuldigung, ich vergaß wohl zu erwähnen, dass die serielle 
Schnittstelle an die GPIO-Pins eines Raspberry Pis (Model B) 
angeschlossen werden.

von Marian S. (ramsem2)


Lesenswert?

Mit ich kann senden, meine ich, dass das Raspberry Pi etwas empfängt, 
wenn ich die Funktion strUart0("Hallo\n); aufrufe. In dem Fall kommt das 
"genau" so an.

von m.n. (Gast)


Lesenswert?

Marian S. schrieb:
> if(send != '\n' || send != '\r')
>   {
>     strEmpfaenger[strPosition] = '\0';
>     strPosition = 0;
>     strFinish = true;
>   }

Das if() ist doch immer erfüllt?

von Marian S. (ramsem2)


Lesenswert?

Ja, das stimmt wirklich nicht, da gehört statt "!=" dass hin "=="!

von holger (Gast)


Lesenswert?

Deine main() läuft einmal durch und tut dann gar nichts mehr.

von c-hater (Gast)


Lesenswert?

Marian S. schrieb:

> Entschuldigung, ich vergaß wohl zu erwähnen, dass die serielle
> Schnittstelle an die GPIO-Pins eines Raspberry Pis (Model B)
> angeschlossen werden.

OK, also ist es so, wie ich vermutet hatte. Partner arbeitet auch mit 
Logikpegeln, nur halt mit kleineren. Dann passt die Schaltung erstmal 
prinzipiell zur Aufgabe.

D.h. aber leider noch nicht, daß die Schaltung auch korrekt aufgebaut 
ist.

> Mit ich kann senden, meine ich, dass das Raspberry Pi etwas empfängt,
> wenn ich die Funktion strUart0("Hallo\n); aufrufe. In dem Fall kommt das
> "genau" so an.

D.h.: Wenn es einen Fehler in der Adapterhardware gibt, liegt er in der 
Mimik mit den zwei Transistoren. Ganz grob kann man die Sache schon mit 
einem 5€-Multimeter überprüfen.

Einfach vom PasPi aus dauerhaft eine Folge von 'U's senden. Multimeter 
auf "AC" schalten, eine Strippe des Multimeter an GND festmachen und mit 
der anderen zuerst mal an TxD des Konnektors. Es sollte eine "deutliche" 
Wechselspannung angezeigt werden, vielleicht irgendwas um ein Volt. Der 
genaue Anzeigewert spielt keine Rolle, die billigen Multimeter sind für 
sowas sowieso nicht gedacht. Aber sie reichen als Indikator für 
Größenordnungen aus. Wenn Null angezeigt wird oder etwas im µ- oder 
unteren mV-Bereich, dann stimmt sehr wahrscheinlich schon auf 
RasPi-Seite irgendwas nicht.

Wenn aber soweit alles i.O. ist, tastet man als nächstes die Basis des 
linken Transistors an. Es sollte auch dort eine Wechselspannung 
angezeigt werden, allerdings deutlich geringer, vielleicht so ungefähr 
in der Größenordnung von 100mV. Danach dasselbe am Kollektor des linken 
Transistors. Hier wären dann eine Anzeige von deutlich über ein Volt zu 
erwarten, dasselbe am Kollektor des rechten Transistors. Als letztes 
tastet man dann noch direkt an den RxD-Pin des Atmega, die Anzeige 
sollte die so ziemlich die gleiche sein wie am Kollektor des rechten 
Transistors.

Wenn das soweit alles so eingetreten ist, ist es relativ wahrscheinlich, 
daß die Hardware im Prinzip funktioniert, der Fehler also mit einiger 
Wahrscheinlichkeit in der Software zu suchen ist.

Wenn hingegen signifikate Abweichungen von diesen Vorhersagen zu 
erkennen sind, ist ein Schaltungsfehler oder Bauelementeausfall relativ 
wahrscheinlich.

von Marian S. (ramsem2)


Lesenswert?

Danke für den obigen Beitrag.

Ich habe es mittlerweile geschafft, primär einmal einen Interrupt 
auszulösen, wenn etwas empfangen wird.

ISR(PCINT3_vect)
{
  intFlag=true;
}

Im Init kommt noch dass dazu:

setBit(PCMSK3,PCINT24); //PinChange Interrupt 25 enabled
setBit(PCICR,PCIE3);  //enable PCINT3_vect für PCINT24-31

Dann kann ich, wenn der Interrupt aufgetreten ist, zum Beispiel LEDs zum 
leuchten bringen

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.