Forum: Mikrocontroller und Digitale Elektronik Atmega48PA RS232 Problem


von A. B. (developer_x)


Lesenswert?

Sehr geehrtes Forum,
ich habe vor einen Atmega48PA per RS232 mit dem
PC kommunizieren zu lassen. Ich verwende HTerm und AVR Studio.

Dazu habe ich Pin 2 (RXD) und Pin 3 (TXD) des Atmegas
mit meinem MAX232 Modul verbunden.

(Mein Max232 Modul ist ein Fertigbauteil, ich habe schon
zwei verschiedene Module verwenden, und die funktionieren
eigentlich)

Auf meinem MAX232 Modul gibt es sogar leds, die anzeigen ob
die Stromversorgung korrekt angeschlossen ist, und LEDs für RXD und TXD.

Nun habe ich nochmal nach diesem Tutorial und Code :
http://www.mikrocontroller.net/articles/AVR-Tutorial:_UART#Senden_von_Zeichen

Das Programm auf meinen Atmega geflashed. Wenn ich nun mein
Terminalprogramm öffne, die im Tutorial beschriebenen Einstellungen
vornehme, und dann die Stromverbindung für den Atmega anstelle,
kommen einfach keine Signale am PC an.

Der Atmega, so zumindest die LEDs von MAX232 Modul, sendet einfach
keine Signale.

Sorry, vielleicht überseh ich einfach eine Kleinigkeit, aber
ich weiß nicht woran es liegen sollte.

Danke für eure Hilfe,
m.f.G.: K.R.

von Oliver R. (orb)


Lesenswert?

Hast Du RXD vom AVR mit RXD oder mit TXD von MAX232 verbunden?
Je nachdem wie der Entwickler gedacht hat, mußt Du die kreuzen.

: Bearbeitet durch User
von A. B. (developer_x)


Lesenswert?

Nein ich habe sie nicht gekreuzt, müssten die LEDs aber nicht trotzdem 
blinken, oder müsste der PC dann nicht wenigstens Mist empfangen?

*Edit: Es funktioniert gekreuzt auch nicht.
Ich denke es liegt eher am Code.
Es ist ein Atmega48 PA. Der Atmega funktioniert auch einwandfrei.
Daran liegt es nicht. Ich vermute ein Softwareproblem.
Kann es daran liegen dass der Code für Atmega8 geschrieben ist?
(Sind doch eigentlich fast gleich ausgestattet auch von den
Bezeichnungen)

: Bearbeitet durch User
von Oliver R. (orb)


Lesenswert?

Wenn 2 Ausgänge aufeinander liegen gewinnt einmal der Stärke und bei 2 
Eingängen passiert garnichts (außer daß vielleicht beide Unsinn 
einfangen).

Um zu testen, ob der Adapter funktioniert kannst Du den AVR mal 
weglassen und RXD und TXD verbinden. Dann muß alles was Du tipst wieder 
angezeigt werden und die LED syncron flackern.

von Thomas E. (thomase)


Lesenswert?

Dann zeig doch deinen Code und verweise nicht auf ein Tutorial, in dem 
drinsteht, wie es richtig sein soll.

mfg.

von A. B. (developer_x)


Lesenswert?

Also:
Erstmal danke für eure Hilfe. Wenn ich RXD und TXD verbinde, kommt 
dasselbe auch wieder am PC an, was abgesendet wurde.
Hardwaretechnisch steht soweit alles.

Mein Code:
1
.include "m8def.inc"
2
 
3
.def temp    = r16                              ; Register für kleinere Arbeiten
4
.def zeichen = r17                              ; in diesem Register wird das Zeichen an die
5
                                                ; Ausgabefunktion übergeben
6
 
7
.equ F_CPU = 4000000                            ; Systemtakt in Hz
8
.equ BAUD  = 9600                               ; Baudrate
9
 
10
; Berechnungen
11
.equ UBRR_VAL   = ((F_CPU+BAUD*8)/(BAUD*16)-1)  ; clever runden
12
.equ BAUD_REAL  = (F_CPU/(16*(UBRR_VAL+1)))      ; Reale Baudrate
13
.equ BAUD_ERROR = ((BAUD_REAL*1000)/BAUD-1000)  ; Fehler in Promille
14
 
15
.if ((BAUD_ERROR>10) || (BAUD_ERROR<-10))       ; max. +/-10 Promille Fehler
16
  .error "Systematischer Fehler der Baudrate grösser 1 Prozent und damit zu hoch!"
17
.endif
18
 
19
    ; Stackpointer initialisieren
20
 
21
    ldi     temp, HIGH(RAMEND)
22
    out     SPH, temp
23
    ldi     temp, LOW(RAMEND)
24
    out     SPL, temp
25
 
26
    ; Baudrate einstellen
27
 
28
    ldi     temp, HIGH(UBRR_VAL)
29
    out     UBRRH, temp
30
    ldi     temp, LOW(UBRR_VAL)
31
    out     UBRRL, temp
32
 
33
    ; Frame-Format: 8 Bit
34
 
35
    ldi     temp, (1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0)
36
    out     UCSRC, temp
37
 
38
    sbi     UCSRB,TXEN                  ; TX aktivieren
39
 
40
loop:
41
    ldi     zeichen, 'T'
42
    rcall   serout                      ; Unterprogramm aufrufen
43
    ldi     zeichen, 'e'
44
    rcall   serout                      ; Unterprogramm aufrufen
45
    ldi     zeichen, 's'
46
    rcall   serout                      ; ...
47
    ldi     zeichen, 't'
48
    rcall   serout
49
    ldi     zeichen, '!'
50
    rcall   serout
51
    ldi     zeichen, 10
52
    rcall   serout
53
    ldi     zeichen, 13
54
    rcall   serout
55
    rcall   sync                        
56
    rjmp    loop
57
 
58
serout:
59
    sbis    UCSRA,UDRE                  ; Warten bis UDR für das nächste
60
                                        ; Byte bereit ist
61
    rjmp    serout
62
    out     UDR, zeichen
63
    ret                                 ; zurück zum Hauptprogramm
64
 
65
; kleine Pause zum Synchronisieren des Empfängers, falls zwischenzeitlich
66
; das Kabel getrennt wurde
67
 
68
sync:
69
    ldi     r16,0
70
sync_1:
71
    ldi     r17,0
72
sync_loop:
73
    dec     r17
74
    brne    sync_loop
75
    dec     r16
76
    brne    sync_1  
77
    ret

von Oliver R. (orb)


Lesenswert?

Du solltest zumindest die
.include "m8def.inc"
in
.include "m48def.inc" oder .include "m48pdef.inc"
ändern.

von der alte Hanns (Gast)


Lesenswert?

Einfach nur kopieren kann ins Auge gehen, wie schon mancher Minister 
erfahren musste.

Im Datenblatt des ATmega48 das Kapitel Register Summary anschauen und 
danach den Unterschied zwischen out und sts ergründen.

von A. B. (developer_x)


Lesenswert?

Sorry, bin bisschen aus der Übung.
Ich werde mich da im Datenblatt nochmal einlesen und melde mich gleich 
zurück.

von Thomas E. (thomase)


Lesenswert?

>     ldi     temp, (1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0)
URSEL hat da auch nichts verloren.

In C wäre das jetzt einfacher. Den Assemblercode musst du schon ein 
bisschen mehr umkrempeln. Vor allen Dingen sind die Adressen nicht mehr 
im I/O Space und daher nicht mehr mit out erreichbar.

mfg.

von der alte Hanns (Gast)


Lesenswert?

Wobei nach dem Tipp von Oliver R. vermutlich der Assembler mit seinen 
Fehlermeldungen bereits in die richtige Richtung weisen wird.

von A. B. (developer_x)


Lesenswert?

Mein Problem ist folgendes, und erinnert mich an die PWM Geschichte von 
mir:
Ich habe ein Tutorial, in welchem mir erklärt wird was ich machen soll. 
Sogar im Datenblatt ist eine Art Tutorial, interessant wird es dann 
aber, wenn selbst der Code aus dem Datenblatt von meinem AVR Studio 
nicht akzeptiert wird, und ich nirgendwo eine Tabelle mit Bezeichnugnen 
der ganzen Bytes finde.

Nun steh ich da und weiß nicht mehr weiter.

Z.B.:
http://www.atmel.com/images/doc2545.pdf
S.178, den Assembler Code zur Initialisierung
bei meinem AVR Studio wird gesagt, dass UBRRnH
nicht existiert (Undefined Symbol).

Hat jemand vielleicht ne gute Erklärung was ich machen könnte?

von spess53 (Gast)


Lesenswert?

Hi

>Hat jemand vielleicht ne gute Erklärung was ich machen könnte?

Atmel hat da schöne Migration Notes. Auch eine vom Übergang vom ATMega8 
zu ATMega48/88/168.

MfG Spess

von der alte Hanns (Gast)


Lesenswert?

Das 'n' steht für eine Ziffer, in diesem Fall wohl '0', denn wenn ich es 
richtig sehe, hat der ATmega48 nur einen USART, eben USART0.

von Thomas E. (thomase)


Lesenswert?

K. R. schrieb:
> http://www.atmel.com/images/doc2545.pdf
> S.178, den Assembler Code zur Initialisierung
> bei meinem AVR Studio wird gesagt, dass UBRRnH
> nicht existiert (Undefined Symbol).
>
> Hat jemand vielleicht ne gute Erklärung was ich machen könnte?

Dir ist aber klar, daß "n" in diesem Fall für "0" steht und entsprechend 
ersetzt werden muß?

mfg.

von A. B. (developer_x)


Lesenswert?

Und womit denn?

Ich habe '_', '0', 'A', 'B' versucht, nichts funktioniert.
Sorry aber diese Erklärungen finde ich nicht gerade sinnvoll,
man kann nicht einfach hingehen, einen Code hinklatschen, ohne
ein einziges Mal zu erklären was n ist, bzw. womit es zu ersetzen ist.

Im gesamten Kapitel kommt es als Index in allen Bezeichnungen vor,
aber nirgendwo wird gesagt, was es ist.

Sorry, aber was soll ich denn da einsetzen?

von der alte Hanns (Gast)


Lesenswert?

Welche Fehlermeldungen kommen denn, wenn Sie das 'n' durch '0' ersetzen?

von spess53 (Gast)


Lesenswert?

Hi

>Sorry, aber was soll ich denn da einsetzen?

Das was im Datenblatt steht.

MfG Spess

von Thomas E. (thomase)


Lesenswert?

K. R. schrieb:
> Und womit denn?
>
> Ich habe '_', '0', 'A', 'B' versucht, nichts funktioniert.
> Sorry aber diese Erklärungen finde ich nicht gerade sinnvoll,
> man kann nicht einfach hingehen, einen Code hinklatschen, ohne
> ein einziges Mal zu erklären was n ist, bzw. womit es zu ersetzen ist.
>
> Im gesamten Kapitel kommt es als Index in allen Bezeichnungen vor,
> aber nirgendwo wird gesagt, was es ist.
>
> Sorry, aber was soll ich denn da einsetzen?

"0".

Aus RXC im UCSRA-Register wird RXC0 im UCSR0A-Register.

mfg.

von A. B. (developer_x)


Lesenswert?

der alte Hanns schrieb:
> Welche Fehlermeldungen kommen denn, wenn Sie das 'n' durch '0'
> ersetzen?

C:\Users\user\Desktop\AVR RS232 Tests\RS232_Test_1.asm(30): error: 
Undefined symbol: UBRR0H

von der alte Hanns (Gast)


Lesenswert?

Dann sind Sie vermutlich nicht dem Hinweis von Oliver R. gefolgt, dieses 
aber ist unabdingbar.

von Thomas E. (thomase)


Lesenswert?

K. R. schrieb:
> der alte Hanns schrieb:
>> Welche Fehlermeldungen kommen denn, wenn Sie das 'n' durch '0'
>> ersetzen?
>
> C:\Users\user\Desktop\AVR RS232 Tests\RS232_Test_1.asm(30): error:
> Undefined symbol: UBRR0H

Falsche xxdef.inc ?

mfg.

von Hans O. (piwibit)


Lesenswert?

Oliver R. schrieb:
> Du solltest zumindest die
> .include "m8def.inc"
> in
> .include "m48def.inc" oder .include "m48pdef.inc"
> ändern.

^^^^^^^^
Das geändert? weil beim ATmega8 gibt es kein UBRR0H

MfG
Hans

von A. B. (developer_x)


Lesenswert?

Natürlich habe ich das schon geändert.

Also das ist im Moment mein Verstümmelter Code,
und ich weiß gar nicht so recht was jetzt konkret
eingesetzt werden soll, weil, wenn ich das durch 0
ersetze kommen da Fehlermeldungen wie vorhin beschrieben.
1
.include "m48def.inc"
2
 
3
.def temp    = r16                              ; Register für kleinere Arbeiten
4
.def zeichen = r17                              ; in diesem Register wird das Zeichen an die
5
                                                ; Ausgabefunktion übergeben
6
 
7
.equ F_CPU = 1000000                            ; Systemtakt in Hz
8
.equ BAUD  = 9600                               ; Baudrate
9
 
10
; Berechnungen
11
.equ UBRR_VAL   = ((F_CPU+BAUD*8)/(BAUD*16)-1)  ; clever runden
12
.equ BAUD_REAL  = (F_CPU/(16*(UBRR_VAL+1)))      ; Reale Baudrate
13
.equ BAUD_ERROR = ((BAUD_REAL*1000)/BAUD-1000)  ; Fehler in Promille
14
 
15
.if ((BAUD_ERROR>10) || (BAUD_ERROR<-10))       ; max. +/-10 Promille Fehler
16
  .error "Systematischer Fehler der Baudrate grösser 1 Prozent und damit zu hoch!"
17
.endif
18
 
19
    ; Stackpointer initialisieren
20
 
21
    ldi     temp, HIGH(RAMEND)
22
    out     SPH, temp
23
    ldi     temp, LOW(RAMEND)
24
    out     SPL, temp
25
26
;;;;;;;;;;;;;;;;;;;;;;;;;;;
27
28
 ; Set baud rate
29
  out UBRR0H, HIGH(UBRR_VAL)
30
  out UBRR0L, LOW (UBRR_VAL)
31
 ; Enable receiver and transmitter
32
  ldi r16, (1<<RXEN0)|(1<<TXEN0)
33
  out UCSR0B,r16
34
 ; Set frame format: 8data, 2stop bit
35
  ldi r16, (1<<USBS0)|(3<<UCSZn0)
36
  out UCSR0C,r16
37
38
;;;;;;;;;;;;;;;;;;;;;;;;;;;
39
40
loop:
41
    ldi     zeichen, 'T'
42
    rcall   serout                      ; Unterprogramm aufrufen
43
    ldi     zeichen, 'e'
44
    rcall   serout                      ; Unterprogramm aufrufen
45
    ldi     zeichen, 's'
46
    rcall   serout                      ; ...
47
    ldi     zeichen, 't'
48
    rcall   serout
49
    ldi     zeichen, '!'
50
    rcall   serout
51
    ldi     zeichen, 10
52
    rcall   serout
53
    ldi     zeichen, 13
54
    rcall   serout
55
    rcall   sync                        
56
    rjmp    loop
57
 
58
serout:
59
    sbis    UCSRA0,UDRE0                  ; Warten bis UDR für das nächste
60
                                        ; Byte bereit ist
61
    rjmp    serout
62
    out     UDR0, zeichen
63
    ret                                 ; zurück zum Hauptprogramm
64
 
65
; kleine Pause zum Synchronisieren des Empfängers, falls zwischenzeitlich
66
; das Kabel getrennt wurde
67
 
68
sync:
69
    ldi     r16,0
70
sync_1:
71
    ldi     r17,0
72
sync_loop:
73
    dec     r17
74
    brne    sync_loop
75
    dec     r16
76
    brne    sync_1  
77
    ret

Fehlermeldungen
1
AVRASM: AVR macro assembler 2.1.42 (build 1796 Sep 15 2009 10:48:36)
2
Copyright (C) 1995-2009 ATMEL Corporation
3
4
C:\Users\user\Desktop\AVR RS232 Tests\RS232_Test_1.asm(2): Including file 'C:\Program Files (x86)\Atmel\AVR Tools\AvrAssembler2\Appnotes\m48def.inc'
5
C:\Users\user\Desktop\AVR RS232 Tests\RS232_Test_1.asm(17): error: Systematischer Fehler der Baudrate grösser 1 Prozent und damit zu hoch!
6
C:\Users\user\Desktop\AVR RS232 Tests\RS232_Test_1.asm(30): error: Invalid register
7
C:\Users\user\Desktop\AVR RS232 Tests\RS232_Test_1.asm(31): error: Invalid register
8
C:\Users\user\Desktop\AVR RS232 Tests\RS232_Test_1.asm(34): error: Operand 1 out of range: 0xc1
9
C:\Users\user\Desktop\AVR RS232 Tests\RS232_Test_1.asm(36): error: Undefined symbol: UCSZn0
10
C:\Users\user\Desktop\AVR RS232 Tests\RS232_Test_1.asm(37): error: Operand 1 out of range: 0xc2
11
C:\Users\user\Desktop\AVR RS232 Tests\RS232_Test_1.asm(60): error: Undefined symbol: UCSRA0
12
C:\Users\user\Desktop\AVR RS232 Tests\RS232_Test_1.asm(63): error: Operand 1 out of range: 0xc6
13
C:\Users\user\Desktop\AVR RS232 Tests\RS232_Test_1.asm(79): No EEPROM data, deleting C:\Users\user\Desktop\AVR RS232 Tests\RS232_Test_1.eep
14
15
Assembly failed, 8 errors, 0 warnings

von der alte Hanns (Gast)


Lesenswert?

'... out of range' heißt in unserem Zusammenhang 'out' durch 'sts' 
ersetzen.
'Undefined symbol' weist meist auf einen Tippfehler hin.

>  ldi r16, (1<<USBS0)|(3<<UCSZn0)
Was bedeutet dieses?

UCSR0A liegt beim 48er im extended IO, also muss
> serout:
>    sbis    UCSRA0,UDRE0                  ; Warten bis UDR für das nächste
>                                          ; Byte bereit ist
>    rjmp    serout
komplett umgeschrieben werden.

von Thomas E. (thomase)


Lesenswert?

K. R. schrieb:
> Undefined symbol: UCSRA0

Das Register heisst UCSR0A.

Der Atmega48 hat ein paar grössere Verwandte, die mehrere USARTs haben. 
Um das konform zu gestalten, hat man bei dem die "0" da eingefügt. Nur 
derjenige, der die Namen für die Interruptvektoren festgelegt hat, ist 
bei dem Meeting, in dem das besprochen wurde, offenbar abwesend gewesen. 
Die Interruptvektoren heissen daher z.B. USART_RX. Das nur mal am Rande.

mfg.

von der alte Hanns (Gast)


Lesenswert?

> bei dem Meeting, in dem das besprochen wurde, offenbar abwesend gewesen.

Es menschelt eben überall.

von A. B. (developer_x)


Lesenswert?

Also, einige Probleme habe ich lösen können, andere wiederum nicht.

Ich habe neben den ganzen Problemen eine Frage:
Welche Taktfrequenz hat denn ein 48PA Standardmäßig? Ich habe nie was 
umgestellt oder nen externen Quarz.
1
.include "m48def.inc"
2
 
3
.def temp    = r16                              ; Register für kleinere Arbeiten
4
.def zeichen = r17                              ; in diesem Register wird das Zeichen an die
5
                                                ; Ausgabefunktion übergeben
6
 
7
.equ F_CPU = 4000000                            ; Systemtakt in Hz
8
.equ BAUD  = 9600                               ; Baudrate
9
 
10
; Berechnungen
11
.equ UBRR_VAL   = ((F_CPU+BAUD*8)/(BAUD*16)-1)  ; clever runden
12
.equ BAUD_REAL  = (F_CPU/(16*(UBRR_VAL+1)))      ; Reale Baudrate
13
.equ BAUD_ERROR = ((BAUD_REAL*1000)/BAUD-1000)  ; Fehler in Promille
14
 
15
.if ((BAUD_ERROR>10) || (BAUD_ERROR<-10))       ; max. +/-10 Promille Fehler
16
  .error "Systematischer Fehler der Baudrate grösser 1 Prozent und damit zu hoch!"
17
.endif
18
 
19
    ; Stackpointer initialisieren
20
 
21
    ldi     temp, HIGH(RAMEND)
22
    out     SPH, temp
23
    ldi     temp, LOW(RAMEND)
24
    out     SPL, temp
25
26
;;;;;;;;;;;;;;;;;;;;;;;;;;;
27
28
 ; Set baud rate
29
  out UBRR0H, HIGH(UBRR_VAL)
30
  out UBRR0L, LOW (UBRR_VAL)
31
 ; Enable receiver and transmitter
32
  ldi r16, (1<<RXEN0)|(1<<TXEN0)
33
  sts UCSR0B,r16
34
 ; Set frame format: 8data, 2stop bit
35
  ldi r16, (1<<USBS0)|(3<<UCSZn0)
36
  sts UCSR0C,r16
37
38
;;;;;;;;;;;;;;;;;;;;;;;;;;;
39
40
loop:
41
    ldi     zeichen, 'T'
42
    rcall   serout                      ; Unterprogramm aufrufen
43
    ldi     zeichen, 'e'
44
    rcall   serout                      ; Unterprogramm aufrufen
45
    ldi     zeichen, 's'
46
    rcall   serout                      ; ...
47
    ldi     zeichen, 't'
48
    rcall   serout
49
    ldi     zeichen, '!'
50
    rcall   serout
51
    ldi     zeichen, 10
52
    rcall   serout
53
    ldi     zeichen, 13
54
    rcall   serout
55
    rcall   sync                        
56
    rjmp    loop
57
 
58
serout:
59
    sbis    UCSR0A,UDRE0                  ; Warten bis UDR für das nächste
60
                                        ; Byte bereit ist
61
    rjmp    serout
62
    sts     UDR0, zeichen
63
    ret                                 ; zurück zum Hauptprogramm
64
 
65
; kleine Pause zum Synchronisieren des Empfängers, falls zwischenzeitlich
66
; das Kabel getrennt wurde
67
 
68
sync:
69
    ldi     r16,0
70
sync_1:
71
    ldi     r17,0
72
sync_loop:
73
    dec     r17
74
    brne    sync_loop
75
    dec     r16
76
    brne    sync_1  
77
    ret
1
AVRASM: AVR macro assembler 2.1.42 (build 1796 Sep 15 2009 10:48:36)
2
Copyright (C) 1995-2009 ATMEL Corporation
3
4
C:\Users\user\Desktop\AVR RS232 Tests\RS232_Test_1.asm(2): Including file 'C:\Program Files (x86)\Atmel\AVR Tools\AvrAssembler2\Appnotes\m48def.inc'
5
C:\Users\user\Desktop\AVR RS232 Tests\RS232_Test_1.asm(30): error: Invalid register
6
C:\Users\user\Desktop\AVR RS232 Tests\RS232_Test_1.asm(31): error: Invalid register
7
C:\Users\user\Desktop\AVR RS232 Tests\RS232_Test_1.asm(36): error: Undefined symbol: UCSZn0
8
C:\Users\user\Desktop\AVR RS232 Tests\RS232_Test_1.asm(60): error: Operand 1 out of range: 0xc0
9
C:\Users\user\Desktop\AVR RS232 Tests\RS232_Test_1.asm(79): No EEPROM data, deleting C:\Users\user\Desktop\AVR RS232 Tests\RS232_Test_1.eep
10
11
Assembly failed, 4 errors, 0 warnings


Übrigstens bin ich da anscheinend nicht der einzige, der ein Problem mit 
diesem Chaos hat:
http://www.roboternetz.de/community/threads/45300-Atmega48-Uart-Wahnsinn

Danke für eure Hilfe bis jetzt

von A. B. (developer_x)


Lesenswert?

*Update
Ich habe jetzt mal in die m48def.inc geschaut,
und da habe ich UCSZn0 in UCSZn00 umbenannt.

Der Fehler is schonmal weg.

von Hans (Gast)


Lesenswert?

Natürlich habe ich das schon geändert

Die erste Fehlermeldung sagt wohl, das die Datei nicht
gefunden werden konnte.

MfG
Hans

von der alte Hanns (Gast)


Lesenswert?

Ausgeliefert wird er mit 1 MHz.

Und die Zeile
>  ldi r16, (1<<USBS0)|(3<<UCSZn0)
ist noch immer da.

Dass Sie den Code nach serout: umschreiben müssen, haben Sie 
mitbekommen?

> und da habe ich UCSZn0 in UCSZn00 umbenannt.
> Der Fehler is schonmal weg.
Definitiv nicht, Sie sind etwas von der Rolle.

von Thomas E. (thomase)


Lesenswert?

K. R. schrieb:
> *Update
> Ich habe jetzt mal in die m48def.inc geschaut,
> und da habe ich UCSZn0 in UCSZn00 umbenannt.
>
> Der Fehler is schonmal weg.

Das sind noch 2:

  out UBRR0H, HIGH(UBRR_VAL)
  out UBRR0L, LOW (UBRR_VAL)

mfg.

von Thomas E. (thomase)


Lesenswert?

der alte Hanns schrieb:
> Ausgeliefert wird er mit 1 MHz.
>
> Und die Zeile
>>  ldi r16, (1<<USBS0)|(3<<UCSZn0)
> ist noch immer da.
>
> Dass Sie den Code nach serout: umschreiben müssen, haben Sie
> mitbekommen?
>
>> und da habe ich UCSZn0 in UCSZn00 umbenannt.
>> Der Fehler is schonmal weg.
> Definitiv nicht, Sie sind etwas von der Rolle.

Gott sei Dank muss man sich C um so einen Scheiss nicht kümmern. Das 
musste jetzt einfach mal gesagt werden.

mfg.

von spess53 (Gast)


Lesenswert?

Hi

>Übrigstens bin ich da anscheinend nicht der einzige, der ein Problem mit
>diesem Chaos hat:
>http://www.roboternetz.de/community/threads/45300-...

Haben nur Leute, die nicht Lesen können oder wollen:

http://www.atmel.com/Images/doc2553.pdf

MfG Spess

von der alte Hanns (Gast)


Lesenswert?

1
serout:
2
    lds   temp,UCSR0A
3
    sbrs  temp,UDRE0
4
   rjmp   serout
5
    sts   UDR0,zeichen
6
   ret

Den Rest, Tippfehler &c., können Sie sicher alleine.

von A. B. (developer_x)


Lesenswert?

So alle Fehler behoben (mit F_CPU=4000000), aber es kommt immer noch 
nichts an, eine Idee woran es liegen könnte?
(Die LED flackert trotzdem nicht)

Wenn ich F_CPU auf 1000000 setze, dann funktioniert es nicht, weil der 
Compiler dann natürlich folgende Zeile ausspuckt:
.error "Systematischer Fehler der Baudrate grösser 1 Prozent und damit
geht es nicht.

Was soll ich da machen?
1
.include "m48def.inc"
2
 
3
.def temp    = r16                              ; Register für kleinere Arbeiten
4
.def zeichen = r17                              ; in diesem Register wird das Zeichen an die
5
                                                ; Ausgabefunktion übergeben
6
 
7
.equ F_CPU = 1000000                            ; Systemtakt in Hz
8
.equ BAUD  = 9600                               ; Baudrate
9
 
10
; Berechnungen
11
.equ UBRR_VAL   = ((F_CPU+BAUD*8)/(BAUD*16)-1)  ; clever runden
12
.equ BAUD_REAL  = (F_CPU/(16*(UBRR_VAL+1)))      ; Reale Baudrate
13
.equ BAUD_ERROR = ((BAUD_REAL*1000)/BAUD-1000)  ; Fehler in Promille
14
 
15
.if ((BAUD_ERROR>10) || (BAUD_ERROR<-10))       ; max. +/-10 Promille Fehler
16
  .error "Systematischer Fehler der Baudrate grösser 1 Prozent und damit zu hoch!"
17
.endif
18
 
19
    ; Stackpointer initialisieren
20
 
21
    ldi     temp, HIGH(RAMEND)
22
    out     SPH, temp
23
    ldi     temp, LOW(RAMEND)
24
    out     SPL, temp
25
26
;;;;;;;;;;;;;;;;;;;;;;;;;;;
27
/*
28
 ; Set baud rate
29
  out UBRR0H, HIGH(UBRR_VAL)
30
  out UBRR0L, LOW (UBRR_VAL)
31
 ; Enable receiver and transmitter
32
  ldi r16, (1<<RXEN0)|(1<<TXEN0)
33
  sts UCSR0B,r16
34
 ; Set frame format: 8data, 2stop bit
35
  ldi r16, (1<<USBS0)|(3<<UCSZ00)
36
  sts UCSR0C,r16
37
*/
38
;;;;;;;;;;;;;;;;;;;;;;;;;;;
39
40
    ; Baudrate einstellen
41
 
42
    ldi     temp, HIGH(UBRR_VAL)
43
    sts     UBRR0H, temp
44
    ldi     temp, LOW(UBRR_VAL)
45
    sts     UBRR0L, temp
46
 
47
    ; Frame-Format: 8 Bit
48
 
49
    ldi     temp, (1<<7)|(1<<2)|(1<<1)
50
    sts     UCSR0C, temp
51
 
52
   ldi    temp, UCSR0B
53
  ldi    temp, (1<<TXEN0)
54
   sts   UCSR0B, temp
55
   // sts     UCSR0B,TXEN0                  ; TX aktivieren
56
 
57
;;;;;;;;;;;;;;;;;;;;;;;;;;;
58
59
loop:
60
    ldi     zeichen, 'T'
61
    rcall   serout                      ; Unterprogramm aufrufen
62
    ldi     zeichen, 'e'
63
    rcall   serout                      ; Unterprogramm aufrufen
64
    ldi     zeichen, 's'
65
    rcall   serout                      ; ...
66
    ldi     zeichen, 't'
67
    rcall   serout
68
    ldi     zeichen, '!'
69
    rcall   serout
70
    ldi     zeichen, 10
71
    rcall   serout
72
    ldi     zeichen, 13
73
    rcall   serout
74
    rcall   sync                        
75
    rjmp    loop
76
 
77
serout:
78
   // sbis    UCSR0A,UDRE0                ; Warten bis UDR für das nächste
79
                                        ; Byte bereit ist
80
  ldi temp, UCSR0A
81
    sbrs temp, UDRE0
82
83
    rjmp    serout
84
    sts     UDR0, zeichen
85
    ret                                 ; zurück zum Hauptprogramm
86
 
87
; kleine Pause zum Synchronisieren des Empfängers, falls zwischenzeitlich
88
; das Kabel getrennt wurde
89
 
90
sync:
91
    ldi     r16,0
92
sync_1:
93
    ldi     r17,0
94
sync_loop:
95
    dec     r17
96
    brne    sync_loop
97
    dec     r16
98
    brne    sync_1  
99
    ret

von Thomas E. (thomase)


Lesenswert?

K. R. schrieb:
> So alle Fehler behoben (mit F_CPU=4000000), aber es kommt immer noch
> nichts an, eine Idee woran es liegen könnte?
> (Die LED flackert trotzdem nicht)
>

Das ist ja nun kompletter Unsinn.

> Wenn ich F_CPU auf 1000000 setze, dann funktioniert es nicht, weil der
> Compiler dann natürlich folgende Zeile ausspuckt:
> .error "Systematischer Fehler der Baudrate grösser 1 Prozent und damit
> geht es nicht.
>
> Was soll ich da machen?

Setz die Baudrate auf 4800 und aktiviere das U2X0-Bit in UCSR0A. Damit 
verdoppelst du die Geschwindigkeit und hast wieder 9600. Aber dann passt 
der Teiler besser.

mfg.

: Bearbeitet durch User
von spess53 (Gast)


Lesenswert?

Hi

>Was soll ich da machen?

Dann setze die Baudrate auf 4800. 9600Bd geht halt mit 1MHz nicht.

MfG Spess

von A. B. (developer_x)


Lesenswert?

Ich habe mal die Baudrate auf 4800 gesetzt und dasselbe auch in HTERM 
gemacht, anstatt mein U2X0-Bit in UCSR0A zu setzen.

Aber trotzdem sendet mein Atmega nichts.

von der alte Hanns (Gast)


Lesenswert?

Legen Sie vorläufig diese Berechnungen still und nehmen Sie die Werte 
aus dem Datenblatt Examples of Baud Rate Setting:

    ldi   temp,high(12)    ; 9600 Bd bei 1 MHz mit U2X0=1
    sts   UBRR0H,temp
    ldi   temp,low(12)
    sts   UBRR0L,temp
    ldi   temp,(1<<U2X0)
    sts   UCSR0A,temp

und weiter sollten Sie schreiben:
    ldi   temp,(1<<USBS0)+(1<<UCSZ01)+(1<<UCSZ00)
    sts   UCSR0C,temp
anstelle dieser Bitraterei bei UCSR0C.

Nebenbei:

> Dann setze die Baudrate auf 4800. 9600Bd geht halt mit 1MHz nicht.

Das stimmt so nicht ganz, siehe oben.

von der alte Hanns (Gast)


Lesenswert?

>  ldi temp, UCSR0A
>  sbrs temp, UDRE0

Das haben Sie aber nicht von mir!

von der alte Hanns (Gast)


Lesenswert?

Eine geschlagene halbe Stunde ohne Reaktion ?! - Ich geh' schlafen.

Kann mich aber doch nicht enthalten, bei allem Verständnis, Reinhard Mey 
zu zitieren:
"Ich übe den Fortschritt, und das nicht faul,
nehme zwei Schritt auf einmal und fall aufs Maul."

von A. B. (developer_x)


Lesenswert?

der alte Hanns schrieb:
>>  ldi temp, UCSR0A
>>  sbrs temp, UDRE0
>
> Das haben Sie aber nicht von mir!

Wie soll man das denn sonst lösen?

der alte Hanns schrieb:
> Eine geschlagene halbe Stunde ohne Reaktion ?! - Ich geh'
> schlafen.
>
> Kann mich aber doch nicht enthalten, bei allem Verständnis, Reinhard Mey
> zu zitieren:
> "Ich übe den Fortschritt, und das nicht faul,
> nehme zwei Schritt auf einmal und fall aufs Maul."

Danke für Ihr Engagement, aber ich kann bedauerlicherweise erst morgen 
weiterarbeiten, ich muss zur Arbeit.

der alte Hanns schrieb:
> Legen Sie vorläufig diese Berechnungen still und nehmen Sie die
> Werte
> aus dem Datenblatt Examples of Baud Rate Setting:
>
>     ldi   temp,high(12)    ; 9600 Bd bei 1 MHz mit U2X0=1
>     sts   UBRR0H,temp
>     ldi   temp,low(12)
>     sts   UBRR0L,temp
>     ldi   temp,(1<<U2X0)
>     sts   UCSR0A,temp
>
> und weiter sollten Sie schreiben:
>     ldi   temp,(1<<USBS0)+(1<<UCSZ01)+(1<<UCSZ00)
>     sts   UCSR0C,temp
> anstelle dieser Bitraterei bei UCSR0C.
>
> Nebenbei:
>
>> Dann setze die Baudrate auf 4800. 9600Bd geht halt mit 1MHz nicht.
>
> Das stimmt so nicht ganz, siehe oben.
Ich werde morgen versuchen den Schritten zu folgen

Danke!

von spess53 (Gast)


Lesenswert?

Hi

>> Nebenbei:

>>> Dann setze die Baudrate auf 4800. 9600Bd geht halt mit 1MHz nicht.

>> Das stimmt so nicht ganz, siehe oben.
>Ich werde morgen versuchen den Schritten zu folgen

Bei 1MHz bekommst du bei 9600Bd einen Fehler von 7%. Mit Double Speed 
kommst du auf (theoretische) 0,2%. Allerdings mit verminderter 
Störsicherheit.

Wenn dein 1MHz-Takt vom internen RC-Oszillator kommt, wird das ganze eh 
zum Vabanquespiel. Kann (manchmal) funktionieren oder auch (manchmal) 
nicht.

MfG Spess

von Thomas E. (thomase)


Lesenswert?

spess53 schrieb:
> Hi
>
>>> Nebenbei:
>
>>>> Dann setze die Baudrate auf 4800. 9600Bd geht halt mit 1MHz nicht.
>
>>> Das stimmt so nicht ganz, siehe oben.
>>Ich werde morgen versuchen den Schritten zu folgen
>
> Bei 1MHz bekommst du bei 9600Bd einen Fehler von 7%. Mit Double Speed
> kommst du auf (theoretische) 0,2%. Allerdings mit verminderter
> Störsicherheit.
>
> Wenn dein 1MHz-Takt vom internen RC-Oszillator kommt, wird das ganze eh
> zum Vabanquespiel. Kann (manchmal) funktionieren oder auch (manchmal)
> nicht.

Nein. Das funktioniert sehr zuverlässig. Sofern man die Bedingungen, 
unter denen der Oszillator werkskalibriert ist, einigermassen einhält.
Daß es ohne Neukalibrierung über den gesamten Temperatur- und 
Spannungsbereich nicht funktioniert, ist klar.

mfg.

von der alte Hanns (Gast)


Lesenswert?

K. R. schrieb:
> der alte Hanns schrieb:
>>>  ldi temp, UCSR0A
>>>  sbrs temp, UDRE0
>>
>> Das haben Sie aber nicht von mir!
>
> Wie soll man das denn sonst lösen?

Sie sollten korrekt kopieren: ich hatte lds geschrieben, nicht ldi (da 
UCSR0A=C0 und UDRE0=5, wird die Schleife nie verlassen).


spess53 schrieb:
> Wenn dein 1MHz-Takt vom internen RC-Oszillator kommt, wird das ganze eh
> zum Vabanquespiel. Kann (manchmal) funktionieren oder auch (manchmal)
> nicht.

Schon, spess53, aber wir wären ja bereits froh gewesen, wenn K.R. 
irgendeine Reaktion auf dem Monitor gesehen hätte.

von wendelsberg (Gast)


Lesenswert?

K. R. schrieb:
> Übrigstens bin ich da anscheinend nicht der einzige, der ein Problem mit
> diesem Chaos hat:
> http://www.roboternetz.de/community/threads/45300-Atmega48-Uart-Wahnsinn
>
> Danke für eure Hilfe bis jetzt

Das hier ist wiedermal ein schoenes Beispiel fuer jemanden, der 
offensichtlich nicht zu Ende gelesen hat.
Im verlinkten Thread lag es eben gerade nicht an "diesem Chaos", sondern 
wie so oft sass die Fehlerursache vor dem Computer.

wendelsberg

von A. B. (developer_x)


Lesenswert?

Funktioniert jetzt alles :D

von A. B. (developer_x)


Lesenswert?

Nur die Geschwindigkeit ist auf 9600 Baud gedrosselt.
Wenn ich dieses eine Bit setze, damit der Chip doppelt so schnell 
arbeitet,
klappt das nicht, aber egal.

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
Noch kein Account? Hier anmelden.