Forum: Mikrocontroller und Digitale Elektronik UART AM ATMEGA48


von Lukas G. (lukas88)


Lesenswert?

Hallo Users,


Ich möchte das erste mal einen Atmega48-AU mit UART ansprechen. Mein 
Testcode bisher:
1
.nolist
2
.include "/home/lukas/Dokumente/AVR/includes/m48def.inc"
3
.list
4
5
;~ sudo avrdude -c avrispmkII -P usb -p m48  -U lfuse:w:0x7D:m -U hfuse:w:0xDF:m
6
7
8
;**************************************************************
9
;UART
10
;**************************************************************
11
12
 ;Berechnungen
13
.equ F_CPU = 4000000                            ; Systemtakt in Hz
14
.equ BAUD  = 9600                               ; Baudrate
15
16
.equ UBRR_VAL   = ((F_CPU+BAUD*8)/(BAUD*16)-1)  ; clever runden
17
.equ BAUD_REAL  = (F_CPU/(16*(UBRR_VAL+1)))     ; Reale Baudrate
18
.equ BAUD_ERROR = ((BAUD_REAL*1000)/BAUD-1000)  ; Fehler in Promille
19
20
.if ((BAUD_ERROR>10) || (BAUD_ERROR<-10))       ; max. +/-10 Promille Fehler
21
  .error "Systematischer Fehler der Baudrate grösser 1 Prozent und damit zu hoch!"
22
.endif
23
24
25
;**************************************************************
26
;Konstanten
27
;**************************************************************
28
29
30
;**************************************************************
31
;Registerdefinitionen
32
;**************************************************************
33
34
35
.def temp= r17
36
37
38
39
;**************************************************************
40
;SRAM
41
;**************************************************************
42
43
.dseg
44
45
.cseg
46
47
;**************************************************************
48
;Vektorentabelle
49
;**************************************************************
50
51
.org 0x0000
52
rjmp init
53
54
;**************************************************************
55
;Interrupts
56
;**************************************************************
57
;reti
58
59
;**************************************************************
60
;Unterprogramme
61
;**************************************************************
62
63
64
init:
65
66
67
ldi     temp,0xFF
68
out     DDRB,temp
69
70
ldi     temp,0b0000001 ;RGB LED
71
out     PORTB,temp
72
73
ldi         temp,LOW(RAMEND)  ;Stackpointer LOW
74
out         SPL,temp
75
ldi         temp,HIGH(RAMEND) ;Stackpointer HIGH
76
out         SPH,temp
77
78
79
; Uart conf
80
81
 ; Baudrate einstellen
82
83
ldi         temp,HIGH(UBRR_VAL)
84
sts         UBRR0H,temp
85
ldi         temp,LOW(UBRR_VAL)
86
sts         UBRR0L,temp
87
88
ldi         temp,(1<<TXEN0)|(1<<RXEN0)
89
sts         UCSR0B,temp
90
91
; Frame-Format: 8 Bit
92
;Parity Disable
93
;Stopp Bit 1
94
;Rising Edge
95
96
ldi         temp, (1<<UMSEL00)|(1<<UCSZ01)|(1<<UCSZ00)
97
sts         UCSR0C,temp
98
99
 ;senden an
100
101
102
;ADC init
103
104
;~ ldi         temp,0b00000010 ; ADC Kanal 2, PINB4
105
;~ out         ADMUX,temp
106
107
;~ ldi         temp,0b10000101
108
;~ out         ADCSRA,temp
109
110
111
;~ ldi     temp, (1<<WGM01);CTC modue an
112
;~ out     TCCR0A,temp
113
114
;~ ldi     temp,60 ;CTC Wert (4800000Hz /60 = 100000 *1000=0.01ms 1ms = 100 overflows, =>korrktur mit oszi  55)
115
;~ out     OCR0A,temp
116
117
118
;~ ldi     temp,0b000000010 ;8 Prescale 600000 Overflows per sec /60 = 10000 Overflows per sec CTC
119
;~ out     TCCR0B,temp
120
121
;~ ldi     temp,(1<<OCIE0A); Interrupt bei Overflow CTC
122
;~ out     TIMSK0,temp
123
124
125
126
;ldi     temp,(1<<ISC01)|(1<<ISC00) ; INT0 und INT1 auf fallende Flanke konfigurieren
127
;out     MCUCR,temp
128
129
;ldi     temp,0b01000000 ; INT0 aktivieren
130
;out     GIMSK,temp
131
132
;ldi     temp,0b01000000 ; INT0 aktivieren
133
;out     GIFR,temp
134
135
sei ;Interrupts an
136
137
138
139
main:
140
141
lds     temp,UCSR0A ; get USART flags
142
sbrs    temp, UDRE0
143
rjmp    main
144
145
ldi     temp,'x'
146
sts     UDR0,temp
147
148
rjmp main


Nachgemessen mit dem Oszi bleibt der TX Pin permanent auf HIGH, RX auf 
LOW. Der Controller sendet also nichts. Mir geht es jetzt darum, ob es 
eine Hardware oder Software Problem ist. Getestet wurde die selbst 
gebaute Schaltung mit einem Atmega8, ebenfalls nur mit TX, funktionierte 
wunderbar.

Der Controller wird wird mit 3.3V versorgt. MAX232 mit 5V, mit 
Spannungsteiler an RX auf 3.3V für den Atmega48.


Mich würde nun intressieren, ob im Code irgend ein Fehler vorhanden ist, 
bevor ich die Hardware umändere?

von S. Landolt (Gast)


Lesenswert?

Das Setzen von UCSR0C ist unnötig und hier, für den ATmega48, falsch.

von Lukas G. (lukas88)


Lesenswert?

Danke für die Hilfe!

Das auslassen von  UCSR0C hat etwas gebracht. Der AVR sendet. Leider 
aber nur 00 obwohl er 'x' senden sollte. Verwede ich auch bein Senden 
das Falsche Register UDRE0?

von S. Landolt (Gast)


Lesenswert?

Also bei mir kommen 'x' an. Baudrate und Systemtakt kontrollieren.

von Lukas G. (lukas88)


Lesenswert?

Bei mir Funktionierst jetzt auch. Mir kam

=>Divide clock by 8 internally; [CKDIV8=0]  bei den Fuses in die Quere.

Besten dank für deine wertvolle Hilfe und Zeit :)

von S. Landolt (Gast)


Lesenswert?

Gern geschehen.

Hätte ich auch merken können, dass ein ATmega48 wohl kaum mit 32 MHz 
läuft, aber ich hatte die auskommentierten Zeilen nicht gelesen.

von Matthias S. (Firma: matzetronics) (mschoeldgen)


Lesenswert?

Vor dem Schreiben auf UDR0 sollte man eigentlich prüfen, ob der Sender 
schon fertig ist. Das klappt hier nur deswegen, weil die Empfangsroutine 
die Wiederholrate bestimmt. Hier die Routine aus dem Datenblatt:
1
USART_Transmit:
2
; Wait for empty transmit buffer
3
   sbis UCSR0A,UDRE0
4
   rjmp USART_Transmit
5
; Put data (r16) into buffer, sends the data
6
   out  UDR0,r16
7
ret

: Bearbeitet durch User
von Lukas G. (lukas88)


Lesenswert?

Ja, ich  weiß. Aber es ging nur darum, ob der selbstgebaute UART 
Adapter(MAX232) auch funktioniert, wie gewünscht. Tut er in dem Fall.

Und der Code im Datenblatt Funktioniert beim Atmega48 anscheinend nicht, 
da teile ins SRAM integriert sind(steht auch im Datenblatt) und nur per 
LDS/STS zugreifbar sind.

Ich schreibe im ersten Augenblick keine Fertigen Programme, sondern 
teste die einzelnen Komponenten separat, erleichtert das Debugging. Und 
die sehen dann eher weniger Professionell aus := )

von S. Landolt (Gast)


Lesenswert?

Matthias S. schrieb:
> Vor dem Schreiben auf UDR0 sollte man eigentlich prüfen, ob der Sender
> schon fertig ist...

Also diesen Kommentar verstehe ich nun nicht, genau das passiert hier 
doch:
1
main:
2
3
lds     temp,UCSR0A ; get USART flags
4
sbrs    temp, UDRE0
5
rjmp    main
6
7
ldi     temp,'x'
8
sts     UDR0,temp
9
10
rjmp main
Schließlich läuft das Programm sowohl bei Lukas G. als auch bei mir.


> Das klappt hier nur deswegen, weil die Empfangsroutine
> die Wiederholrate bestimmt.

?
Welche Empfangsroutine?

von Arduino Fanboy (Gast)


Lesenswert?

Warum nimmst du nicht einfach die entsprechende
Arduino Bibliothek? Dann läuft das in zwei Minuten!

von S. Landolt (Gast)


Lesenswert?

> Arduino Bibliothek

Autsch!
Da freue ich mich, einen Assembler-Mitstreiter gefunden zu haben, und 
dann dies.

von Matthias S. (Firma: matzetronics) (mschoeldgen)


Lesenswert?

S. Landolt schrieb:
> Also diesen Kommentar verstehe ich nun nicht

Ja, da habe ich nicht genau genug hingeguckt. Ich bitte mehrmals um 
Entschuldigung.

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.