Ich hab ein kleines Programm für den ATMEGA8535 mit CodeVision AVR geschrieben. Die RS232 verhält sich komisch beim ATMEGA8535. Es scheint so zu sein, dass das senden funktioniert. Nur der Empfang funktioniert nicht. Ich kann am Controller nix empfangen. Ich wäre sehr dankbar, wenn jemand mal den C-Code anschauen würde. ********************************* #include <mega8535.h> #include <glcd_t6963.h> #include <delay.h> #include <math.h> #include <string.h> #include <delay.h> #include <stdlib.h> #include <stdio.h> unsigned char SetBaudrate = 0x33; // Baudrate 9600 Baud (ext.Quarz 8Mhz) // Stopbit = 1, Parity = none, Data Bits = 8 void USART_Transmit (unsigned char data) { while(!(UCSRA & (0x20))) ; UDR = data; } unsigned char USART_Receive (void) { while(!(UCSRA & (0x80))) ; return UDR; } //***************************************************** //***************************************************** //Hauptprogramm void main(void) { DDRB = 0xFF; PORTB = 0; DDRD = 0x00; PORTD = 0; t6963cinit(); LCD_Clear_Graphics(); LCD_Clear_Text(); UBRRL = SetBaudrate; UCSRB=0x18; UCSRC=0x86; ACSR=0x80; #asm("sei") while (1) { delay_ms(150); LCD_printfz(0,1,"Zeichen:%2x",USART_Receive()); }; }
Der Controller kann nichts von der RS232 empfangen. Was ist an meinem Programm falsch?
Schade das mir hier niemadn was zu meinen Code sagen kann. Ich weiss halt einfach nicht weiter. Sicherlich gibt es hier viele, die denken, ach Gott was will der den.
Liest du eigentlich die Antworten auf deine Fragen??? Hans Dieter hat dir doch die Lösung genannt. Er hat dich auch darauf hingewiesen, dass du die Bits in den I/O-Registern beim Namen nennen sollst anstatt nichtssagende HEX-Zahlen (sehen ja sooooo intelligent aus) hinzuschreiben. Wer soll sich denn die Arbeit machen, jeden Wert im Datenblatt nachzuschlagen um deinen Code zu verstehen? Nenne die Bits beim Namen, dann findet sich wahrscheinlich auch ein C-Kundiger, der sich den Code mal bis zu Ende durchliest. Du willst etwas, nicht wir, also mach das Helfen nicht unnötig schwer. > Im Prinzip sind nur diese Register -> UDR, UCSRB und UBRRL relevant, > oder? Anscheinend nicht, sonst wäre Hans Dieter nicht auf den Sonderfall eingegangen. Wenn du nicht verstehst, was er damit meinte, dann recherchiere im Datenblatt bist du es verstanden hast. Es steht alles drin. ...
RS232 Einstellungen: // Baudrate 9600 Baud (ext.Quarz 8Mhz) // Stopbit = 1, Parity = none, Data Bits = 8 ********************************* #include <mega8535.h> #include <glcd_t6963.h> #include <delay.h> #include <math.h> #include <string.h> #include <delay.h> #include <stdlib.h> #include <stdio.h> unsigned char SetBaudrate = 0x33; void USART_Transmit (unsigned char data) { while(!(UCSRA & (0x20))) ; UDR = data; } unsigned char USART_Receive (void) { while(!(UCSRA & (0x80))) ; return UDR; } //***************************************************** //***************************************************** //Hauptprogramm void main(void) { DDRB = 0xFF; PORTB = 0; DDRD = 0x00; PORTD = 0; t6963cinit(); LCD_Clear_Graphics(); LCD_Clear_Text(); UBRRL = SetBaudrate; //Baudrate 9600Baud --> 0x33 UCSRB=0x18; //folgende Bits werden hier gesetzt:RXEN Bit 4, TXEN Bit 3 UCSRC=0x86; //folgende Bits werden hier gesetzt:URSEL Bit 7, UCSZ1 Bit 2, UCSZ0 Bit 1 ACSR=0x80; #asm("sei") while (1) { delay_ms(150); LCD_printfz(0,1,"Zeichen:%2x",USART_Receive()); }; }
Ich habe noch was vergessen hier anzugeben! RS232 Einstellungen: // Baudrate 9600 Baud (ext.Quarz 8Mhz) // Stopbit = 1, Parity = none, Data Bits = 8 ********************************* #include <mega8535.h> #include <glcd_t6963.h> #include <delay.h> #include <math.h> #include <string.h> #include <delay.h> #include <stdlib.h> #include <stdio.h> unsigned char SetBaudrate = 0x33; void USART_Transmit (unsigned char data) { while(!(UCSRA & (1<<UDRE))) ; UDR = data; } unsigned char USART_Receive (void) { while(!(UCSRA & (1<<RXC))) ; return UDR; } //***************************************************** //***************************************************** //Hauptprogramm void main(void) { DDRB = 0xFF; PORTB = 0; DDRD = 0x00; PORTD = 0; t6963cinit(); LCD_Clear_Graphics(); LCD_Clear_Text(); UBRRL = SetBaudrate; //Baudrate 9600Baud --> 0x33 UCSRB=0x18; //folgende Bits werden hier gesetzt:RXEN Bit 4, TXEN Bit 3 UCSRC=0x86; //folgende Bits werden hier gesetzt:URSEL Bit 7, UCSZ1 Bit 2, UCSZ0 Bit 1 ACSR=0x80; #asm("sei") while (1) { delay_ms(150); LCD_printfz(0,1,"Zeichen:%2x",USART_Receive()); }; }
Nimm einen Baudratenquarz. Mit 8 MHz wird das (wenn überhaupt) sehr unsicher. ...
Ok durch deinen EIntrag hab ichs verstanden. Mir geht es nur mal jetzt darum, ob theoretisch mein C Programm ok ist. Sind die Register richtig initialisiert oder nicht?
Auf der Mikrocontroller.com Seite habe ich mir vor langer Zeit eine Platine für den AT90S8535 gekauft und bestückt. Da verwende ich den gleichen Quarz und da funktionierte die RS232 prima. Jetzt habe ich mir eine Platine mit ATMEGA8535 dazu noch ein Grafikdisplay aufgebaut. Der COntroller und das Display funktionieren auch ohne Probleme. Nur die UART macht mir halt noch Probleme.
Dein C-Programm werde ich nicht analysieren, ich schreibe in ASM. Ich habe soeben einen ellenlangen Beitrag mit ASM-Beispielen in deinem anderen Thread geschrieben. Leider war dieser Thread bereits beim Absenden meines Beitrags gelöscht. Nochmal schreibe ich den Beitrag aber nicht, ich habe auch noch andere Interessen. ...
Danke für deine Unterstützung. Aber das alles bringt mich halt nicht sehr viel weiter. Wie gesagt an dem QUarz kann es nicht liegn.siehe Beitrag von 14:25.
Auf der Seite www.mikrocontroller.net habe ich ein Beispielprogramm für den AT90S8535 heruntergeladen und getestet. Auf dem AT90S8535 funktioniert die UART. Wenn ich diesen C-Code für den ATMEGA8535 einsetzte dann habe ich beim senden und empfangen wie gesagt Probleme. Desshalb verstehe ich das ganze überhaupt nicht.
Es gibt von ATMEL Appnotes, die die Unterschiede zwischen AT90S8535 und ATMega8535 erklären. Könnte man mal lesen... Aber: Ich hatte mit einem Mega8535 und 3,6864MHz-Quarz das Phänomen, dass der Quarz mit dreifacher Frequenz lief. Erst mit Kondensatoren von 330pF lief der Quarz mit der korrekten Frequenz. Der Quarz stammte aus einem Quarzsortiment von Pollin (Restposten/Industrieschrott), ich hatte also kein verbindliches Datenblatt dazu. Du schreibst (irgendwo), dass UART auf dem STK500 funktioniert hat. Dann teste doch das aktuelle Programm mal auf dem STK500. Vielleicht liegt es ja nur an einem miserablen (nicht EMV-gerechten) Platinenlayout? Es gibt sehr viel, was man falsch machen kann... ...
Tschuldigung, ich meinte nicht STK500 sondern Board aus dem Shop. Habe eben nochmal nach dieser Aussage gesucht. ...
Aber vom Prinzip müsste doch mein C-Programm so funktionieren oder? //Baudrate=9600Bd, Stoppbit=1,Parity=keine UBRRL=0x33; UCSRB=0x18; UCSRC=0x86; Ja sind die Register so korrekt eingestellt?
So große unterschiede gibt es gar nicht. Die Register für die UART sind gleich. Vielleicht nur von der Namensgebung.
Also ich komme mir hier jetzt total hilflos vor. Bisher konnte mir hier niemand ein STATEMENT zu meinem C Code geben!
Mach ersma das hier: Er hat dich auch darauf hingewiesen, dass du die Bits in den I/O-Registern beim Namen nennen sollst anstatt nichtssagende HEX-Zahlen (sehen ja sooooo intelligent aus) hinzuschreiben. Wer soll sich denn die Arbeit machen, jeden Wert im Datenblatt nachzuschlagen um deinen Code zu verstehen? Nenne die Bits beim Namen, dann findet sich wahrscheinlich auch ein C-Kundiger, der sich den Code mal bis zu Ende durchliest.
Vielleicht weißt du einfach nicht was die Leute mit "nenne die Bits beim Namen" meinen. Deshalb hier ein Beispiel: UCSRC = (1<<URSEL)|(0<<USBS)|(1<<UCSZ1)|(1<<UCSZ0); Statt Hexzahlen kannst du auch so die Register initialisiern. Cpt
Das habe ich doch schon getan. Was soll das eigentlich. In diesem Forum sind doch so viele schlaue Leute. ALso noch deutliche kann ich nicht werden. ********************************* #include <mega8535.h> #include <glcd_t6963.h> #include <delay.h> #include <math.h> #include <string.h> #include <delay.h> #include <stdlib.h> #include <stdio.h> unsigned char SetBaudrate = 0x33; void USART_Transmit (unsigned char data) { while(!(UCSRA & (0x20))) ; UDR = data; } unsigned char USART_Receive (void) { while(!(UCSRA & (0x80))) ; return UDR; } //***************************************************** //***************************************************** //Hauptprogramm void main(void) { DDRB = 0xFF; PORTB = 0; DDRD = 0x00; PORTD = 0; t6963cinit(); LCD_Clear_Graphics(); LCD_Clear_Text(); UBRRL = SetBaudrate; //Baudrate 9600Baud --> 0x33 UCSRB=0x18; //folgende Bits werden hier gesetzt:RXEN Bit 4, TXEN Bit 3 UCSRC=0x86; //folgende Bits werden hier gesetzt:URSEL Bit 7, UCSZ1 Bit 2, UCSZ0 Bit 1 ACSR=0x80; #asm("sei") while (1) { delay_ms(150); LCD_printfz(0,1,"Zeichen:%2x",USART_Receive()); }; }
Hi Simon... Hat er doch inzwischen gemacht. Die letzte Version seines Codes nannte die Bits beim Namen. Da er dafür aber wieder einen neuen Thread eröffnete, wurde dieser kurzerhand vom Admin gelöscht. Einen Versuch zur Hilfe werde ich aber noch starten: Ich hänge einen halbfertigen ASM-Quelltext an, bei dem ein Mega8535 per USART mit dem PC (eigenes VB-Programm) mit 9k6 kommuniziert. Da das Programm üppig kommentiert ist, dürfte man den USART-Zugriff leicht finden. ...
> Was soll das eigentlich. In diesem Forum sind doch so viele schlaue > Leute. ALso noch deutliche kann ich nicht werden. Inzwischen ärgere ich mich schon fast, dass ich versucht habe dir zu helfen. Du tust ja so, als ob wir verpflichtet wären, dir zu helfen, während du zu faul bist, mal ins Datenblatt zu schaun. Deine Arroganz stinkt zum Himmel. Du willst etwas, nicht wir, also benimm dich dementsprechen! ...
Guten Abend Hannes, erstmal recht herzlichen Dank für den ASM Code. Leider bin ich in ASM nicht fitt. Ich habe mal jetzt den Code angeschaut. Wo wird da die UART initialisiert bzw. wo sind die entsprecheneden Register? Gibt es hier niemand der den ATMEGA8535 mit C programmiert?
Ja was mache ich schon die ganze Zeit...schlafen oder was. Ich habe das Datenblatt auch angeschaut. Daraus werde ich auch nicht schlau. Ist das so ein geheimniss, wenn mandem anderen gleich eine Hilfestelllung zum C Code gibt?
Ich hatte beim umstieg von einem 90s8515 auf nen mega8 auch mal problem mit dem uart. ein fehler war, dass auch UBBRH, das zweite register für die baudrate, beschrieben werden muss, damit es funktioniert. (selbst wenn dort nur eine null steht, wie es bei mir und auch in deinem programm der fall ist)
> Leider bin ich in ASM nicht fitt. Ich habe mal jetzt den Code > angeschaut. Wo wird da die UART initialisiert bzw. wo sind die > entsprecheneden Register? Im Menüpunkt 1 des Programms. Der Init-Code wurde übrigens dem Datenblatt des Mega8535 entnommen. USART_Init: out UBRRH,null ;Set baud rate ldi wl,baud out UBRRL,wl ldi wl, (1<<RXEN)|(1<<TXEN) out UCSRB,wl ;Enable Receiver & Transmitter ; ldi wl, (1<<URSEL)|(1<<USBS)|(3<<UCSZ0) ;Set frame format: 8data, 2stop bit ldi wl, (1<<URSEL)|(3<<UCSZ0) ;Set frame format: 8data, 1stop bit out UCSRC,wl print 1,1 ;LCD löschen ret USART_aus: cbr flags,1<<v24rx ;Empfangsroutine deaktivieren cbr flags,1<<v24tx ;Senderoutine deaktivieren out ucsrb,null ;USART aus print 1,1 ;LCD löschen locate 1,0 ;Trennlinien printf linie ;neu locate 6,0 ;aufbauen printf linie ret > Gibt es hier niemand der den ATMEGA8535 mit C programmiert? Vielleicht sind diese Leute ja der Meinung, dass dir bereits ausreichend geholfen wurde und weitere Hilfe daher überflüssig ist. ...
Hei vielen Dank Hannes ich werde es mal heute bei mir testen. Also liegt es bei mir nur daran dass ich das Regisster "UBRRH" mit dem Wert 0 beschreiben muss.
> Also liegt es bei mir nur daran dass ich das Regisster "UBRRH" > mit dem Wert 0 beschreiben muss. Oder auch daran, - dass du keinen Baudratenquarz benutzt, - dass dein Quarz auf falscher Frequenz schwingt (nachgemessen?), - dass dein Layout nicht optimal ist (die erste eigene Platine ist selten optimal) Abblock-Cs vorhanden? - dass dein RS232-Pegelwandler nicht korrekt arbeitet (Pegel gemessen?), - dass der Rest deines C-Programms noch irgendwelche Bugs enthalten könnte - oder an einem der vielen weiteren Gründe, dir mir jetzt nicht einfallen. Wenn du systematisch vorgehst, kannst du einen Punkt nach dem anderen ausschließen. - Läuft denn der Rest von deinem Programm? - Hast du die Betriebsspannung nachgemessen und auf Störimpulse untersucht? - Hast du die Spannungen am RS232-Pegelwandler nachgemessen? - Hast du die RS232-Pegel nachgemessen? (Oszilloskop) - Hast du das richtige Kabel für RS232? - Sind die erforderlichen Brücken für Handshake in der RS232-Leitung vorhanden? Es gibt noch viele andere Möglichkeiten, etwas falsch zu machen. ...
Die Betriebsspannung liegt bei mir auf +5V. Der Rest von der Schaltung (Grafik Dsiplay) funktioniert super. Das RS232 Kabel habe ich nur so aufgebaut: Die Sende leitung und die Empfangsleitung habe ich gekreuzt. Dazu kommt noch die Masse. (PIN 2,3,5 verwende ich da) Was meinst du damit? "Sind die erforderlichen Brücken für Handshake in der RS232-Leitung vorhanden?" Welche Leitung muss ich da physlikalisch Brücken?Ist da notwendig?
brücken für handshake sind nicht unbedingt nötig, wenn man den handshake im terminalprogramm am PC ausschaltet. aber du hast den AVR direkt mit dem PC verbunden? das wird nicht funktionieren (und hast evtl schon den rx pin vom AVR geschrottet). die schnittstelle am PC arbeitet nämlich mit einem pegel von +-12V, während der AVR 0V/5V erwartet. beim senden reicht also die spannung vielleicht nicht aus, damit was am PC ankommt, und beim empfangen kommt eine überspannung beim AVR an. man benötigt daher ein konverter-IC wie den MAX232. die schaltung dazu gibts hier: http://www.mikrocontroller.net/tutorial/uart
Ja den IC habe ich doch schon auf meinem Board drauf. Dazu habe ich noch 4 100nF Kondensatoren verwendet. Was nun?
Die RS232 verbindung habe ich auch so wie auf dem Schaltplan aufgebaut. Nur an dem 9poligen Stecker habe ich nur PIN 2,3 und 5 verwendet. Die anderen Verbindungen habe ich weggelassen.
es gibt mehrere typen des MAX232. bei manchen reichen 100nF kondensatoren, bei anderen müssen es 1µF oder 22µF sein. miss mal am MAX232 nach, ob dessen spannungswandler richtig arbeitet. an pin2 müssen mehr als 5V zu messen sein, bei mir sinds etwas 9V. an pin 9 müsste eine etwa genausogroße negative spannung messbar sein, bei mir -9V.
Deine Schaltung entspricht aber nicht deiner Beschreibung in Worten... ...
Hi Hannes hab ich was anderes gesagt? Vielleicht war ich nicht verständlich genug. Reicht es eigentlich aus, wenn ich nur PIN 2,3 und 5 vom SUBD9 verwende? Da muss dann bei Handshaking none wählen oder?
ups, bei pin 9 hab ich mich vertippt, das müsste pin 6 sein. pin 2 stimmt aber. wenn bei dir dort nur 4,5V ankommen, werden wahrscheinlich die 100nF für deinen MAX232 zu wenig sein. tausch die kondensatoren mal gegen 1µF aus... 100NF funktioneren nur mit speziellen typen, die auch wesentlich teurer als die normalen sind. was ist die genaue typenbezeichnung, die bei dir draufsteht? ich hab nen "MAX232N" und betreibe ihn erfolgreich mit 1µF.
Nein ich habe einenMAX232ECPE. Was oll ich jetzt tun???????????????
Hat dein MAX232 denn einen eigenen Abblock-Kondensator parallel zur Betriebsspannung? (wird in Prinzipschaltzeichnungen oft weggelassen, da Selbstverständlichkeit) ...
Ou...leider nicht. Ja ist das echt wichtig? Verhält sich dadurch meine RS232 so komisch? Also ich meine das wird nicht viel bringen.
> Nein ich habe einenMAX232ECPE. laut datenblatt braucht ein MAX232E aber 1µF kondensatoren (das CPE steht nur für die gehäuseform). du müsstest also größere kondensatoren einabuen, sonst wird das ganze wohl nie funktionieren...
Nein, das zeigt nur, wie oberflächlich du an die Sache heran gehst. Wenn dein MAX232 mindestens +9V und -9V erzeugt, dann hast du lediglich eine von vielen Fehlerquellen ausgeschlossen. Bei deiner Arbeitsweise ist die Chance recht groß, dass du an anderen Stellen des Projekts weitere Fehler eingebaut hast, weil du (teils bewusst) Selbstverständlichkeiten missachtest. Oder hat inzwischen jeder Chip seinen eigenen Abblock-Kondensator? (Das wäre nur 1 Punkt von vielen Selbstverständlichkeiten.) ...
Ich habe nicht alles mir durchgelesen. Ich programiere den ATMega8535 mit C. Ich gebe dir ein Beispiel Code. Initialisierung: DDRB= 0x07; // Multiplexleitungen seriell PB0-2 als Ausgang PORTB= 0x03; // UART verbinden mit COM UBRRH= 0x0; // UART auf 9600 baud (siehe ATmega8535 Datasheet) UBRRL= 0x5F; // UBRR= (fquarz/ (16* BAUD) ) -1 (siehe ATmega8535 Datasheet) UCSRB= 0x18; // Transmitter und Receiver einschalten (Datasheet) UCSRC=0x86; // 8 bit 1 Stop No Parity (siehe ATmega8535 Datasheet) Dann zwei Funktionen send und read.... char uart_read(void){ while (!(UCSRA&(1<<RXC))); // Warten bis RXC-Bit in UCSRA Warten bis was ankommt return UDR; // Zeichen das angkommen ist zurückgeben } void uart_send(char data) { while (((UCSRA >> UDRE) & 1) ==0){} // warten bis UART sendebereit UDR= data; } Falls es nicht läuft überprüfe die FUSE BITS des Atmels ogb die Richtig gesetzt sind. Sie sind vom Werk aus anders gesetzt. Hast du in deiner Schalung einen externen Quarz??? 14,...MHZ must du die dies in den Fuse bits einstellen
ahh soo ich habe es nicht bemerkt beim kopieren des codes DDRB= 0x07; // Multiplexleitungen seriell PB0-2 als Ausgang PORTB= 0x03; // UART verbinden mit COM ist für meine anwendung spezifisch... die Zeilen kannst du weglassen
Hallo, ich habe zwar ein anderes serielles Problem bei einem m16c, möchte aber trotzdem einen Gedanken loswerden: senden geht, empfangen nicht: die SioLeitungen liegen ja fast immer auf Portleitungen, oft wird vergessen, die korrespondierenden Portleitungen explizit auf Eingang bzw. Ausgang zu setzen. Manchmal sind andere Harwarefunktionen auf den Portleitungen vorhanden, die ggf. ausgeschaltet werden müssen, da sie sonst die Pins mit falschen Pegeln überlagern.
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.