Probleme mit USART (ATMEGA8535)

Gast #232114
Lesenswert?

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());
      };
}
#232118
Lesenswert?

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.

...
Gast #232119
Lesenswert?

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());
      };
}
Gast #232120
Lesenswert?

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());
      };
}
Gast #232123
Lesenswert?

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.
#232124
Lesenswert?

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.

...
#232127
Lesenswert?

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...

...
Persönliche Seite #232134
Lesenswert?

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.
Gast #232135
Lesenswert?

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
Gast #232136
Lesenswert?

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());
      };
}
#232137
Lesenswert?

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.

...
Angehängte Dateien:
#232138
Lesenswert?

> 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!

...
Gast #232139
Lesenswert?

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?
Gast #232140
Lesenswert?

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?
Gast #232141
Lesenswert?

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)
#232142
Lesenswert?

> 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.

...
#232144
Lesenswert?

> 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.

...
Gast #232145
Lesenswert?

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?
Gast #232146
Lesenswert?

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
Gast #232150
Lesenswert?

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.
Gast #232152
Lesenswert?

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?
Gast #232154
Lesenswert?

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.
Gast #232159
Lesenswert?

> 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...
#232161
Lesenswert?

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.)

...
Gast #232162
Lesenswert?

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
Gast #232163
Lesenswert?

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
#232164
Lesenswert?

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.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren