Hallo, ich versuche, USART ohne Interrupt gangbar zu machen. Da gibt es Dinge, die ich mir nicht erklären kann: Ein Codeschnipsel: USART_init(); // enth. UCSRB = (1<<RXEN) | (1<<TXEN); // nebst Baud- u. Frame-Einstellg. // get = USART_Receive(); // ???? USART_halt(); // UCSRB = (0<<RXEN) | (0<<TXEN); DDRD |=2; // Kontrolle, ob PD1 wieder verfügbar ist PORTD &= 253; _delay_ms(5); PORTD |= 2; _delay_ms(5); Ich möchte den USART, der ja PORTD 0 u. 1 belegt, benutzen. Anschließend soll aber PD1 wieder low sein. Daß man nach USART_init nicht einfach den vormals als TX benutzten PortD1 manipulieren kann, sehe ich ja ein, deshalb die Zeile mit USART_halt, die die Ports erfolgreich freigibt. Was mir aber sonderbar vorkommt, ist, daß dies nicht mehr hilft, wenn ich im obigen Beispiel die Zeile mit get.... aktiviere (das get- Beispiel steht hier für viele Befehle, die mit dem USART zusammenhängen). Aktiviere ich die Zeile, dann bleibt PD1 high, deaktiviere ich sie wieder, dann zeigt der Oszi das gewünschte Muster am PD1. Ich hatte gedacht, wenn ich RXEN und TXEN auf Null setze, ist das erledigt. Muß man sich vielleicht auch noch um die ausgelesenen oder nicht ausgelesenen Bytes in den Pufferspeicher kümmern? Oder was kann sonst noch zu dem eigenartigen Effekt führen? Schönen Abend noch Egon
>Ich hatte gedacht, wenn ich RXEN und TXEN auf Null setze, ist das >erledigt. Das tuts auch. Die Frage ist eher:
1 | get = USART_Receive(); |
2 | USART_halt(); |
Kann das nicht eher sein, dass der µC in der Zeile get=.. festhängt, weil er dort auf ein Zeichen wartet??? Das sollte vielleicht eher per ISR gemacht werden. So kannst du jederzeit abschalten. Solltest allerdings das TXC-Flag (letztes Senden erfolgreich beendet) vorher prüfen.
Hallo Egon, Deiner Beschreibung kann ich nicht 100% folgen; das liegt auch daran, dass Du uns Deine Funktionen nicht zeigst. Prinzipiell verhält sich bei den AVRs die Freigabe der RXD-Leitung anders als die Freigabe der TXD-Leitung. Bei RXEN=0 sollte die RXD-Leitung (fast, siehe nächst. Satz) sofort freigegeben werden, bei TXEN=0 dauert die TXD-Freigabe, bis die letzte Aussendung komplett ist. Obwohl der RX-Puffer bei RXEN=0 geleert wird, rät Atmel, dass man ein formelles "flush" durchführt, indem man auf RXC=0 wartet (siehe Anlage). Ich hänge diesem Posting einen Datenblatt-Ausschnitt des ATmega32 zum Empfangen an und poste einen Folgebeitrag, der den zugehörigen Ausschnitt zum Senden zeigt. Viele Grüße risu
Hallo, vielen Dank Matthias Lipinsky wrote: >>Ich hatte gedacht, wenn ich RXEN und TXEN auf Null setze, ist das >>erledigt. > > Das tuts auch. > > Die Frage ist eher: >
1 | > get = USART_Receive(); |
2 | > USART_halt(); |
3 | >
|
> > Kann das nicht eher sein, dass der µC in der Zeile get=.. festhängt, > weil er dort auf ein Zeichen wartet??? > Das sollte vielleicht eher per ISR gemacht werden. So kannst du > jederzeit abschalten. Solltest allerdings das TXC-Flag (letztes Senden > erfolgreich beendet) vorher prüfen. Glaube ich eher nicht, weil das Programm nicht ewig wartend anhält, sondern weiter läuft. Außerdem, wenn ich ein anderes Kommando, z.B. ring(); (vgl. angehängtes kpl. Programm) stattdessen hinschreibe, tritt der gleich Effekt auf. > Deiner Beschreibung kann ich nicht 100% folgen; das liegt auch daran, > dass Du uns Deine Funktionen nicht zeigst. Prinzipiell verhält sich bei Programm füge ich bei. Und, ich hatte vergessen zu erwähnnen: es handelt sich um einen Atmeg16. > den AVRs die Freigabe der RXD-Leitung anders als die Freigabe der > TXD-Leitung. Bei RXEN=0 sollte die RXD-Leitung (fast, siehe nächst. > Satz) sofort freigegeben werden, bei TXEN=0 dauert die TXD-Freigabe, bis > die letzte Aussendung komplett ist. > geleert wird, rät Atmel, dass man ein formelles "flush" durchführt, > indem man auf RXC=0 wartet (siehe Anlage). > Viele Grüße > risu Genau genommen, geht es mir nur um TX, weil dort PD1 dauernd high gehalten wird, was das angeschlossene Händie veranlaßt, auf Netzsuche zu gehen. Viele Grüße Egon
Hallo Egon, > Genau genommen, geht es mir nur um TX, weil dort PD1 dauernd high > gehalten wird, was das angeschlossene Händie veranlaßt, auf Netzsuche zu > gehen. Du setzt doch am Ende Deines Codes PD1 auf Ausgang, 5ms auf L und dann 5ms auf H: > DDRD |=2; // Kontrolle über PD1: mache zum Ausgang > PORTD &= 253; // PD1 auf L > //... 5ms warten > PORTD |= 2; // PD1=H ...und da Du (in Deinem Codebeispiel) gar nichts sendest, gilt nach der UART-Initialisierung auch TXD=IDLE=H. Demnach erwarte ich von Deinem Code, dass PD1 etwas über 5ms lang H und 5ms lang L ist, wenn Du nichts sendest oder empfängst. Willst Du sagen, Du siehst dieses 100Hz Signal and PD1 nicht auf dem Oszi? Gruß Fred
PS: Wie sieht die Hardware an PD1=TXD aus? Kann es sein, dass der Fehler dort liegt?
risu wrote: > > ...und da Du (in Deinem Codebeispiel) gar nichts sendest, gilt nach der > UART-Initialisierung auch TXD=IDLE=H. > Demnach erwarte ich von Deinem Code, dass PD1 etwas über 5ms lang H und > 5ms lang L ist, wenn Du nichts sendest oder empfängst. > Willst Du sagen, Du siehst dieses 100Hz Signal and PD1 nicht auf dem > Oszi? > > Gruß > > Fred Da habe ich mich vielleicht zu ungenau ausgedrückt. Das angehängte Programm hat mit dem Ziel rein gar nichts zu tun, ich habe es nur, weil ich irgendwie sehen wollte, warum das angeschlossene Händie nicht reagiert und nach kurzer Zeit auf Netzsuche geht. Also habe ich eine fliegende Drahtverbindung zwischen PD1 und RX des Händies bzw. PD0 und TX am Händie (und natürlich GND). Diese Leitungen sind angezapft für den Oszi. Wenn ich per USART z. B. 'AT' sende, sieht man auf der Leitung ein plausibles Signalmuster. Aber, wenn das Programm pausiert, geht das Händie auf Netzsuche. Nachdem ich nun den USART-Kram auf das mindeste reduziert hatte, habe ich entdeckt, daß PD1 high bleibt und das Händie deshalb nach einigen Sekunden Netzsuche startet. Vielleicht hätte es lieber 3 statt 5V? > PS: Wie sieht die Hardware an PD1=TXD aus? Kann es sein, dass der Fehler > dort liegt? Wird regelmäßig kontrolliert, so leicht macht es uns die Apparatur leider nicht. Viele Grüße Egon
Hallo Egon, > Aber, wenn das Programm pausiert, geht das Händie auf Netzsuche. > Nachdem ich nun den USART-Kram auf das mindeste reduziert hatte, > habe ich entdeckt, daß PD1 high bleibt .... Wenn es nicht ein Problem der Pegelanpassung ist, schlage ich vor, Du machst es wie im von Dir oben angeführten Beispiel (Deine Zahlenkonstanten habe ich hier nur als symbolische Konstanten umgeschrieben - finde ich übersichtlicher), um PD1 auf L zu ziehen, falls es das ist, was der Empfänger sehen will: UCSRB &= ~(1<<TXEN); // TX ausschalten DDRD |= (1<<PD1); // PD1 wird User Ausgang PORTD &= ~(1<<PD1) // PD1=L Dass ein "L" dem seriellen "IDLE" entsprechen soll, ist etwas seltsam, denn normalerweise ist das "IDLE"=H. Vielleicht doch ein Pegel-Problem? Kommt denn das "AT" korrekt beim Empfänger an (Du sprichst nur von einem "plausiblen Signal" auf dem Oszi)? Könnte das Signal invertiert sein? Gruß risu
Hallo risu > risu wrote: > Wenn es nicht ein Problem der Pegelanpassung ist, schlage ich vor, Du > machst es wie im von Dir oben angeführten Beispiel (Deine > Zahlenkonstanten habe ich hier nur als symbolische Konstanten > umgeschrieben - finde ich übersichtlicher), außerdem ist offensichtlich UCSRB &= ~(1<<TXEN) besser als UCSRB &= (0<<TXEN); > um PD1 auf L zu ziehen, > falls es das ist, was der Empfänger sehen will: > Ich habe eine Funktion void PD1_low(void) { UCSRB &= ~(1<<TXEN); DDRD |= (1<<PD1); PORTD &= ~(1<<PD1); } eingefügt, damit bleibt jetzt PD1 low und die Netzsucherei hat ein Ende. Damit ist es nun möglich, längere Zeit auf irgend etwas vom Händie zu warten, z.B. einen Anruf. > > Dass ein "L" dem seriellen "IDLE" entsprechen soll, ist etwas seltsam, > denn normalerweise ist das "IDLE"=H. Vielleicht doch ein Pegel-Problem? > Kommt denn das "AT" korrekt beim Empfänger an (Du sprichst nur von einem > "plausiblen Signal" auf dem Oszi)? Wenn ich das irgendwie kontrollieren könnte, wäre ich sehr froh! Es gibt aber nur die eine Verbindung AVR - Händie. Ich fürchte mich vor der blinden Kommunikation mit dem Händie, wo man nicht weiß, woran man ist. Ich werde zunächst wenigstens versuchen, ein 'ok' zu detektieren als Antwort auf mein 'AT'. Das müßte ja nun gehen mit dem PD1_low. Bis hierher erst mal vielen Dank! Viele Grüße Egon
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.