Hallo zusammen, Ich habe mir nun einmal das GCC-Tutorial durchgelesen und auch das senden mit dem USART ausprobiert. AVR: mega8515 Terminalprogramm: Br@y Den Sendecode habe ich 1:1 aus dem Tutorial übernommen. ------------------------ #include <avr/io.h> #include <avr/interrupt.h> #include <inttypes.h> #define CLOCK 8000000 //Clock 8MHz #define BAUD 19200 //USART BAUD #define UBRR_BAUD ((CLOCK/(16*BAUD))-1) int uart_putc(unsigned char c) { while (!(UCSRA & (1<<UDRE))); /* warten bis Senden moeglich */ UDR = c; /* sende Zeichen */ return 0; } int main(void) { DDRD = 0xff; PORTD |= (1 << PD7); UCSRB |= (1<<TXEN); // UART TX einschalten UCSRA |= (1 << U2X); UCSRC |= ( 1 << URSEL )|( 3<<UCSZ0 ); // Asynchron 8N1 UBRRH = (uint8_t) (UBRR_BAUD>>8); // USART Baud UBRRL = (uint8_t) UBRR_BAUD; uart_putc('A'); } ----------------------- Mein Problem ist jetzt dass im Terminal zwar jedesmal wenn ich den AVR resete was ankommt allerding immer 0x00, obwohl ich ja 'A' sende. Bin noch Neuling in der Welt von C :) Woran kann das liegen? Gruß Julien
Nun der mega8515 hängt auf nem STK500 mit externem 8MHz Quarz. Muss hier dann noch was anderes eingestellt werden bzw dann an den FUSE BITs? RS232 SPARE ist mit PortD des Megas verbunden. Zum Proggen nehme ich das AVR Studio.-->erhalte dort keinerlei Fehlermeldungen.
Jap, schau dir mal die Registerkarte "Fuses" im AVR Studio an. da kannst du das schön bequem auswählen woher er den takt nehmen soll. dann klappts auch mitm nachbarn.
Nun dort ist EXT. CRYSTAL/RESONATOR HIGH SPEED ausgewählt. CKSEL=1111 SUT=11 ebenso: BODLEVEL=1 BOOTSZ=00 Leider funktioniert es nicht, oder ist eben gerade diese einstellung falsch?
Die Portinitialisierung in main() birgt eine Falle: DDRD = 0xff; Beim "DDRD = 0xff" schaltest Du alle Pins als Output, also geht auch der TX-Pin (PD1) auf Low, da in PortD zu dieser Zeit nur Nullen stehen. Diese Low-Flanke gelangt aber als Startbit zum PC und dessen UART versucht nun, ein Zeichen zu samplen. Das kurz danach korrekt abgesendete 'A' kann dadurch nicht korrekt empfangen werden. Lösung: Am besten den TX-Pin erstmal als Eingang lassen, d.h. bei der DDR-Anweisung auf Null lassen. Sobald der Transmitter über das TXEN-Bit aktiviert wird, setzt der Controller den Pin automatisch auf High und als Ausgang. Also z.B.: . . . int main(void) { DDRD = 0xff - (1<<PD1); . . . Oder: Zuerst PORTD setzen, dabei das TX-Bit (PD1) auf High setzen. Dann erst im DDRD als Ausgang setzen. Dadurch bleibt der Pin die ganze Zeit auf High. Also: . . . int main(void) { PORTD = (1 << PD7) | (1 << PD1) ; DDRD = 0xff; . . . Während Reset sind die Controller-Pins übrigens hochohmig und werden vom MAX232 automatisch als High erkannt (über interne Pullups im MAX232). MfG Olaf
@Olaf Vielen Dank für diesen Hinweis:) Leider hat sich das Problem dadurch noch nicht gelöst! Es wird immernoch nach jedem RESET eine 0 gesendet. Wo können denn noch Fehler stecken? Gruß
Hab gerade gesehen dass U2X = 1 Dann stimmt natürlich die Berechnung von UBRR nicht. Aber egal was ich nehme, U2X = 0 mit entsprechender Berechnungsformel oder obengenanntes. Nix geht-> außer der netten NULL. Gibt es irgendwelche Vorgaben, wie mann übertragen muss damit der PC was erkennt?
Naja also irgendwie verzweifel ich langsam an diesem USART! Wenn schon das senden nicht funktioniert dann wollte ich mal sehen ob er wenigstens was vom PC empfangen kann. Aber ebenfalls vergeblich :( Ich habe jetzt einfach mal meinen Source inden Anhang gepackt. Es wäre sehr hilfreich wenn sich jemand erbarmen könnte unter Zuhilfenahme dieses Source(enthält eine USART lib)einen kleinen Code zu schreiben der folgendes prüft. - Zeichen(BYTE) an den PC senden (kann dann ja übers terminalprogramm ekannt werden) - Zeichen(BYTE) an den µC senden und dieses dann an PORTB über LEDs ausgeben. Vielen Dank im Vorraus. Aber wenigstens gibt es Lichtblicke für mich als Anfänger in der Welt der Hochsprache. Ansteuerung von Ports (LEDs Taster) sowie einer PWM funktionieren sehr gut! Gruß Julien
Auf die schnelle sieht es soweit ganz gut aus! Habe folgendes korrigiert: in usart.c sowie in (usart)test.c => #include "usart.h" //Hochkommas "" statt <> in usart.c Zeile 35: => kein semicolon [;] nach dem #endif Weiss nicht ob's daran lag. Hab das ganze als AvrStudio-Projekt angehängt, probier mal ob's bei Dir tut. Ich hab leider kein AtMega8515 zum ausprobieren Gruss Peter
>=> kein semicolon [;] nach dem #endif
Das ist auch nicht notwendig. Präprozessoranweisung terminiert man
nicht mit Semikola.
@Peter Vielen Dank für deine Arbeit, habs auch mal getestet, aber irgendwie rührt sich da nix. Hab leider auch kein scope da um zu sehen was am TX bzw. Rx raus-/rein geht :( P.S.: der code von Dir sollte Eigentlich auf den meisten megas laufen! Ich werde jetzt nochmal einen Test machen, bei dem ich auschließlich das ganze interuptgesteuert mache. Mal sehen ob dann was geht. Ansonsten kann ja nur noch was am STK500 nicht stimmen. Ist aber eigentlich auzuschließen da ja mal nur "0" nach einem rest ankam. Gruß
Schreibs nochmal um, sodass ein einer Schleife staendig gesendet wird. Dann haeng mal eine LED an den Transmit Ausgang. Die muesste eigentlich flackern. Dann check nochmal das Seriell-Kabel durch (gekreuzt, nicht-gekreuzt) und stell sicher, dass das Sende-Signal am PC auch am richtigen Pin ankommt. Meistens sind es die einfachen Dinge, die schief gehen. Auf Interrupt wuerde ich da zunaechst mal nicht bauen. Wenns in der allereinfachsten Version nicht geht, dann bringen Interrupts nur einen Level Komplexitaet mehr ins Spiel. Zum Fehlersuchen sollen die Dinge aber so einfach wie moeglich sein.
Hier noch der geänderte Code: #include <avr/io.h> #include <avr/interrupt.h> #include <inttypes.h> #include "usart.h" typedef unsigned char BYTE; typedef unsigned short WORD; void reset(void) { DDRB = 0xff; PORTB = 0x00; DDRD |= (1<<DDD1); PORTD |= (1<<PD1); } int main(void) { reset(); usart_init(9600, 8, 'N', 1); //Init USART mit 9600 8N1 while(1) { usart_putc(2); } } Wenn ich den jetzt ausführe Leuchtet die LED an PD1 permanent. ist das jetzt richtig? ich vermute dass Sie leuchtet da ich PD1 auf High beim reset gesetz habe. Weiter ist mir beim debuggen noch folgendes aufgefallen. Nach der initialisierung des USART **usart_init(9600, 8, 'N', 1); ** Hat UBRRL = 51 und in UBRRH sind Bit 1,2 und 7 gesetzt. Hat das nicht zur folge das dann die Baudrate nicht mehr stimmt? oder hat des mit URSEL(Bit7) zu tun und spielt keine rolle? Gruß
Es könnte alles so einfach sein:) Hab den Fehler endlich gefunden Es lag am STK500 Entgegen den angaben im AVR Studio muss Pin RXD vom SPARE mit dem RX vom µC verbunden werden. genauso TXD komisch, iss aber so Trotzdem nochmals vielen Dank für eure Bemühungen. Man merkt wieder einmal, wie hilfreich es ist gemeinsam Probleme zu lösen. Gruß Julien
@Patrick Dohmen >>kein semicolon [;] nach dem #endif >Das ist auch nicht notwendig. Präprozessoranweisung >terminiert man nicht mit Semikola. _______________________ Mein ich ja auch, das Semikolon war zuviel! Doch ich habe mich zugegebenermassen nicht klar genug ausgedrück! Gruzzo Peter
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.