Hallo. Ich möchte mit einem Controller (ATMEGA16) und seinem USART durch aufnehmen von Daten die Leuchtdiode 1 bzw. Leuchtdiode 2 ansteuern. Ich schicke jeweils einen String z.B. 'C' für Diode 1 oder 'F' für Diode 2 durch ein C Programm. Das C Programm funkioniert, weil ich es schon durch ein Terminal und eine Kreuzverbindung zwischen Com1 und Com2 getestet habe. Der ATMEGA16 soll diesen String erkennen und abhängig davon Diode 1 bzw. 2 einschalten. Beim Probieren habe ich festgestellt, daß der Controller irgendwelche Daten aufnimmt, weil das RXC Bit aktiviert wird. Das Problem ist, daß ich es nicht schaffe das UDR Register nach dem Richtigen Wert abzufragen und abhängig davon die Dioden anzusteuern. Ich habe es auf verschiedene Weisen Probiert ( durch masken, durch Abspeichern in einer Veriablen usw. ). Habe ich etwa ein Problem mit dem Frame oder werden da die MSB und LSB vertauscht oder gibt es da noch etwas was ich nicht weiß? David
Ein Stückchen Code würde sicherlich helfen DIr zu helfen. Wie ist der ATMEga USART initialisiert?
So sieht der Gesamte Code aus. Es ist nichts besonderes, aber laut meinen Überlegungen sollte es so funktionieren, oder etwa nicht. In diesem Fall wird nur eine Diode falls Sting 'a' angeschaltet. Es leuchter aber nur die 0x02 adressierte Diode. void main (void) { unsigned char empfWert; DDRA = 0xFF; /* We put port B pins in output mode */ UBRRH = 0; // Taktteiler UBRR H/L für Baudrate UBRRL = 51; // 51 bei 16 MHz für 19200 Baud UCSRB = _BV(RXEN);// Receiver enable UCSRC = _BV(URSEL) | _BV(UCSZ0) | _BV(UCSZ1); // RegisterSelect UCSRC (URSEL) // Asynchronous Mode // Parity disable and 1 Stop-Bit // Datasize: 8Bit (UCSZO, UCSZ1) while(1) { empfWert = Usart_Rx; if ( empfWert == 'a') PORTA = 0x01; else { PORTA = 0x02; } } } unsigned char Usart_Rx(void) { while (!(UCSRA & (1<<RXC))); // warten bis Zeichen verfuegbar return UDR; // Zeichen aus UDR an Aufrufer zurueckgeben } David
> empfWert = Usart_Rx; Wohl eher: empfWert = Usart_Rx(); > DDRA = 0xFF; /* We put port B pins in output mode */ ...und vielleicht mal drauf achten, dass Kommentar und Code auch zusammenpassen!
Kleiner Tipp: versuch mal das UDR-Register einer Variablen zuzuweisen und die Variable zurück zu geben. Also: temp = UDR und return temp Hatte während meiner Technikerarbeit die gleichen Probleme und sie damit behoben.
man könnte auch das empfangene Zeichen zuerst mal an LEDs an einem PORT binär ausgeben um den Empfangserfolg zu kontrollieren. So sieht man ob überhaupt was ankommt und auch was genau. bye Frank
> UBRRL = 51; // 51 bei 16 MHz für 19200 Baud
Und er läuft auch wirklich mit 16 MHz und nicht etwa mit dem
1 MHz vom internen RC-Oszillator, mit dem er aus dem Laden
kommt?
Ja UBRRL = 51; stimmt. Habe diese Initialisierung dem USERS Manuel entnomen. Ich wollte mich bei euch Bedanken. Es hat geklappt nach dem ich die Tipps von Euch befolgt habe. Es werden demnächst weitere Fragen meinerseits kommen z.B zum EEPROM usw. Ich bin natürlich selber auch bereit Fragen (wenn ich sie beantworten kann) zu beantworten in Richtung ATMEGA16 Programmieren LCD-Anzeige usw usw. Bis Bald
Was Jörg meinte, ist nicht, ob der Wert für 16 MHz stimmt (was ja anscheinend der Fall ist), sondern ob Dein µC tatsächlich mit 16 MHz läuft. Wenn Du die Fusebits nämlich nicht programmiert hast, läuft der Mega16 nämlich mit internem RC-Oszillator und 1 MHz.
Ok dann nehme ich das Thema wieder auf. also der CLk arbeitet mit 16 MHz das ist klar. Ich verstehe nicht, warum er mit 1 Mhz arbeiten sollte, wenn ich ihn auf Externen Clk beim Brennen durch meinen brenner "initialisiert" habe. Es funktioniert auch alles bis jetzt :-). Die Einstellung von UBRRL = 51; // 51 bei 16 MHz für 19200 Baud bezieht sich ja nur auf den USART und die Baudrate. David
Wenn Du die Fuses korrekt gesetzt hast, ist das ja auch kein Problem. Das hattest Du aber weiter oben noch nicht erwähnt!
Es geht mit dem Thema weiter. Vorerst mal eine Allgemeine Frage. Kann mir jemand verraten wie ich einen Kontroller adressieren kann, damit ich mit dem PC mal den Einen mal den Anderen Controller steuern kann? Ich weiß ich brauche eine RS485 Schnittstelle. Habe auch den nötigen Schaltplan zum Anschluss an den USART. Wie Programmiere ich die nötige ADRESSE damit jeder Controller sie empfängt aber nur der angesprochene Daten Sendet?
Da musst Du ein Protokoll vereinbaren. Da brauchst Du auch nicht unbedingt eine RS485-Schnittstelle. Das geht im Prinzip mit jeder Übertragungshardware...
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.