UART + Taschenrechner Teil2

OP #624107
Lesenswert?

Hi,
ich mach der Übsicht halber mal nen neuen Thread auf. Also das UArt 
klappt nur komme ich nicht weiter als bis zur ersten LED. Der Code ist 
der:

1
.include "m32def.inc"                    ; bzw. 2333def.inc
2
 
3
.def temp    = R16
4
.def Data    = R17
5
.def Count   = R18
6

7

8
.equ CLOCK   = 16000000
9
.equ BAUD    = 9600
10
.equ UBRRVAL = CLOCK/(BAUD*16)-1
11
 
12
.org 0x00
13
        rjmp main
14
 
15
.org URXCaddr                             ; Interruptvektor für UART-Empfang
16
        rjmp Recive1
17

18

19
;Hauptprogramm
20
main:
21
        ldi temp, LOW(RAMEND)
22
        out SPL, temp
23
        ldi temp, HIGH(RAMEND)
24
        out SPH, temp
25

26
        ldi temp, 0xFF                    ; Port D = Ausgang
27
        out DDRD, temp
28

29
        ldi temp, 0b01100000
30
        out PortD, temp
31
 
32
        ; Baudrate einstellen
33
        ldi temp, HIGH(UBRRVAL)
34
        out UBRRH, temp
35
        ldi temp, LOW(UBRRVAL)
36
        out UBRRL, temp
37
 
38
        ; Frame-Format: 8 Bit
39
        ldi r16, (1<<URSEL)|(1<<USBS)|(1<<UCSZ1)|(1<<UCSZ0)
40
        out UCSRC, temp
41
 
42
        sbi UCSRB, RXCIE                  ; Interrupt bei Empfang
43
        sbi UCSRB, RXEN                   ; RX (Empfang) aktivieren
44
        sbi UCSRB, TXEN                ; TX (Senden) aktivieren 
45
        
46
        sei                               ; Interrupts global aktivieren
47
        
48
loop:  
49
  
50
    rjmp loop                         ; Endlosschleife
51

52
Recive1:
53

54
       sbis UCSRA, RXC    
55
     rjmp  Recive1
56
       in Data, UDR                      ; Empfangenes Byte in Data speichern
57
     cpi  Data, 0x15
58
     brne Ende
59
     
60
     rjmp header_init
61

62
       Ende:
63
     reti                               ; zurück zum Hauptprogramm
64

65

66
Recive:
67

68
       sbis UCSRA, RXC    
69
     rjmp  Recive
70
       in Data, UDR                      ; Empfangenes Byte in Data speichern
71
     ret  
72

73

74

75
Transmit:
76

77
       sbis UCSRA, UDRE                   ; Warten bis UDR ist
78
       rjmp Transmit
79
       out UDR, Data                      ; Data senden
80
     ret
81

82
       
83

84
header_init:
85

86
     cbi UCSRB, RXCIE                   ; Interrupt bei Empfang deaktivieren
87
     cbi  PORTD, 5
88
     
89
     ldi  Data, 0x13
90
     rcall Transmit
91
     ldi  Count, 0x31                    ; Counter der bytes zählt aktivieren
92

93
header_recive:
94
       
95
     
96
       rcall Recive
97
     dec Count
98
     cpi Count, 0
99
     brne header_recive
100
     cbi  PORTD, 6
101
     ldi Data, 0x06
102
     rcall Transmit
103
    
104
    
105

106

107

108
Neustart:
109

110
    sbi UCSRB, RXCIE                   ; Interrupt bei Empfang aktivieren
111
    rjmp loop



hier der Link zum Protokol:

http://users.pandora.be/gp/casio/index.html
Gast #624177
Lesenswert?

Ich denke mal das Problem liegt hier:

header_recive:


       rcall Recive
     dec Count
     cpi Count, 0
     brne header_recive
     cbi  PORTD, 6
     ldi Data, 0x06
     rcall Transmit

entweder du machst das "cpi Count, 0" weg oder ersetzt es durch
"cpi count, 0x00"
#624180
Lesenswert?

Condi wrote:
> entweder du machst das "cpi Count, 0" weg oder ersetzt es durch
> "cpi count, 0x00"
Ersetze XYZ durch XYZ oder "den Teufel mit Beelzebub austreiben"? Die 
beiden Ausdrücke sind gleichwertig (und in Assembler sogar tatsächlich, 
da nicht Case-sensitiv und dementsprechend count = Count)...
Gast #624194
Lesenswert?

Du springst in der Receive Intrerruptroutine raus aus dieser, falls dein 
eingehendes Datenbyte 0x15 ist. Da Du nie wieder in die INtRoutine 
zurückspringst, wird kein RETI aufgerufen und das I-Flag wird nicht 
gelöscht. Daher können keine weiteren Interrupts abgearbeitet werden.

Pack den Transmitkram in die Hauptroutine und frage dort ein bit im 
Register 20 oder so ab. Ist dieses gesetzt, weil 0x15 empfangen wurde, 
machst Du den Job in der Hauptschleife.

Siehe ...HanneS... "Jobflag
http://www.mikrocontroller.net/search?query=jobflag&forums%5B%5D=1&forums%5B%5D=9&forums%5B%5D=10&forums%5B%5D=2&forums%5B%5D=4&forums%5B%5D=3&forums%5B%5D=6&forums%5B%5D=17&forums%5B%5D=11&forums%5B%5D=8&forums%5B%5D=12&forums%5B%5D=14&forums%5B%5D=7&forums%5B%5D=5&forums%5B%5D=15&forums%5B%5D=13&forums%5B%5D=16&max_age=-

AxelR.

8N1 mit 9K6- bist Du sicher???
Gast #624244
Lesenswert?

Laut meinem Mega32 Datenblatt ist:
ldi r16, (1<<URSEL)|(1<<USBS)|(1<<UCSZ1)|(1<<UCSZ0)

8n2

Der Code ist  zwar nicht so schön, aber er sollte funktionieren. Wenn 
0x15 empfangen wurde, wir der Interrupt disabled und dann wird immer 
geprüft ob wieder was empfangen wurde.

Bei Neustart sollte halt anstelle des rjmp loop ein reti stehen. Das 
Problem liegt in der Schleife, die ich schon erwähnte, die scheint nicht 
0 zu werden.
Du solltest mehr Anzeigen in die Schleifen machen, damit du mehr infos 
bekommst.
OP #624263
Lesenswert?

so ich habe lange nicht hier reingeschaut. hier der aktuelle Code:

1
.include "m32def.inc"                    ; bzw. 2333def.inc
2
 
3
.def temp    = R16
4
.def Data    = R17
5
.def Count   = R18
6

7

8
.equ CLOCK   = 16000000
9
.equ BAUD    = 9600
10
.equ UBRRVAL = CLOCK/(BAUD*16)-1
11
 
12
.org 0x00
13
        rjmp main
14
 
15
.org URXCaddr                             ; Interruptvektor für UART-Empfang
16
        rjmp Recive1
17

18

19
;Hauptprogramm
20
main:
21
        ldi temp, LOW(RAMEND)
22
        out SPL, temp
23
        ldi temp, HIGH(RAMEND)
24
        out SPH, temp
25

26
        ldi temp, 0xFF                    ; Port D = Ausgang
27
        out DDRD, temp
28

29
        ldi temp, 0b01100000
30
        out PortD, temp
31
 
32
        ; Baudrate einstellen
33
        ldi temp, HIGH(UBRRVAL)
34
        out UBRRH, temp
35
        ldi temp, LOW(UBRRVAL)
36
        out UBRRL, temp
37
 
38
        ; Frame-Format: 8 Bit
39
        ldi r16, (1<<URSEL)|(1<<USBS)|(1<<UCSZ1)|(1<<UCSZ0)
40
        out UCSRC, temp
41
 
42
        sbi UCSRB, RXCIE                  ; Interrupt bei Empfang
43
        sbi UCSRB, RXEN                   ; RX (Empfang) aktivieren
44
        sbi UCSRB, TXEN                ; TX (Senden) aktivieren 
45
        
46
        sei                               ; Interrupts global aktivieren
47
        
48
loop:  
49
  
50
    rjmp loop                         ; Endlosschleife
51

52
Recive1:
53

54
       in Data, UDR                      ; Empfangenes Byte in Data speichern
55
     cpi  Data, 0x15
56
     brne Ende
57
     
58
     rjmp header_init
59

60
       Ende:
61
     reti                               ; zurück zum Hauptprogramm
62

63

64
Recive:
65

66
       sbis UCSRA, RXC
67
     rjmp Recive
68
       in Data, UDR                      ; Empfangenes Byte in Data speichern
69
     ret  
70

71

72

73
Transmit:
74

75
       sbis UCSRA, UDRE                   ; Warten bis UDR ist
76
       rjmp Transmit
77
       out UDR, Data                      ; Data senden
78
     ret
79

80
       
81

82
header_init:
83

84
     cbi UCSRB, RXCIE                   ; Interrupt bei Empfang deaktivieren
85
    
86

87

88
ldi temp, 10
89
wait0:
90
                push temp
91
                ldi temp, 200
92
wait0_1:                               
93
                nop
94
                nop
95
                nop
96
                nop
97
                nop
98
                dec temp
99
                cpi temp, 0
100
                brne wait0_1
101
                pop temp
102
                dec temp
103
                cpi temp, 0
104
                brne wait0
105

106

107

108
     
109
     ldi  Data, 0x13
110
     rcall Transmit
111
     
112
     ldi  Count, 49                    ; Counter der bytes zählt aktivieren
113

114
       cbi  PORTD, 5
115
header_recive:
116
       
117
     
118
       rcall Recive
119
     
120
     dec Count
121
     cpi Count, 0
122
     brne header_recive
123
     
124

125

126
       ldi temp, 10
127
wait1:
128
                push temp
129
                ldi temp, 200
130
wait1_1:                               
131
                nop
132
                nop
133
                nop
134
                nop
135
                nop
136
                dec temp
137
                cpi temp, 0
138
                brne wait1_1
139
                pop temp
140
                dec temp
141
                cpi temp, 0
142
                brne wait1
143

144

145

146
     ldi Data, 0x06
147
     rcall Transmit
148
     
149

150

151

152

153
     ldi Count, 16
154
data_recive:
155
     rcall Recive
156
     dec count
157
     cpi Count, 0
158
     brne data_recive
159

160

161

162

163

164
ldi temp, 10
165
wait2:
166
                push temp
167
                ldi temp, 200
168
wait2_1:                               
169
                nop
170
                nop
171
                nop
172
                nop
173
                nop
174
                dec temp
175
                cpi temp, 0
176
                brne wait2_1
177
                pop temp
178
                dec temp
179
                cpi temp, 0
180
                brne wait2
181

182

183

184
     ldi Data, 0x06
185
     rcall Transmit
186

187
     
188
cbi  PORTD, 6
189

190

191
ldi  Count, 50
192

193
end_header:
194
       
195
       rcall Recive
196
     
197
     dec Count
198
     cpi Count, 0
199
     brne end_header
200
    
201

202

203

204
ldi temp, 10
205
wait3:
206
                push temp
207
                ldi temp, 200
208
wait3_1:                               
209
                nop
210
                nop
211
                nop
212
                nop
213
                nop
214
                dec temp
215
                cpi temp, 0
216
                brne wait3_1
217
                pop temp
218
                dec temp
219
                cpi temp, 3
220
                brne wait3
221

222

223

224

225

226

227
     ldi Data, 0x06
228
     rcall Transmit
229

230

231
  
232
      
233

234
Neustart:
235

236
rjmp Neustart
237

238
    sbi UCSRB, RXCIE                   ; Interrupt bei Empfang aktivieren
239
    rjmp loop



er hängt bei data_recive...die LED geht nicht an. ansonsten kein Fehler 
auf dem Rechner er hängt sich nur auf
#624290
Lesenswert?

Wegen den Warteschleifen: Der Taschenrechner ist so lahm, dass der µC 
sich etwas gedulden muss, bevor er die Handshakes usw senden darf. An 
sonsten ist der Taschenrechner noch nicht zum Empfangen bereit und das 
Gesendete geht verloren.
Theoretisch könnte man den µC wahrscheinlich mit 4MHz oder so laufen 
lassen, würde locker reichen. Vielleicht geht sogar noch weniger.
Gast #624297
Lesenswert?

nop
                dec temp
                cpi temp, 0
                brne wait0_1

wenn Du temp verringerst, wird das ZeroFlag Erst gesetzt, wenn temp NULL 
ist.

Daher ja auch BRNE. Du brauchst keinen zusätzlichen Vergleich mittels 
CPI temp,0 machen. Das macht der Controller von Hause aus.

dec temp
brne wait0_1

reicht daher.
Gast #624298
Lesenswert?

Stimmt eigentlich, die Bootloader FuseBits hätten es auch sein können. 
Tschuldige.

@Michael

Warum hast du in deinem Programm keine Warteschleifen drin?
Ich war immer der Meinung 9600 Baud ist 9600 Baud egal ob der MC mit 
1Mhz läuft oder 16Mhz, zumindest bei HW-UART.
#624316
Lesenswert?

vom µC aus gesehen stimmt das auch. Nur beim Taschenrechner anscheinend 
nicht. (Ev hat der nen Software-uart oder so was.)
Im Protokoll isses so, dass der GTR (=Taschenrechner) etwas sendet und 
dann der µC das bestätigen soll. Wenn das Bestätigungsbyte aber zu 
schnell nach Empfang der Daten gesendet wird, hat der GTR anscheinend 
ein Problem und erkennt das Byte nicht.
OP #624370
Lesenswert?

@ Michael Frangenberg


danke nochmal für deine Hilfe gestern. Mein ICQ ging irgendwie nichtmehr 
an.


Ich werde heute mal versuchen die Daten zu speichern und wenn das Klappt 
das Programm für allgemeine Übertragungen bereit machen also das mit der 
Datenlänge aus header etc. Am besten wäre je eigentlich zum speichern 
nen externer EEprom oder Sram. Das müsst ich mir noch besorgen.
OP #625041
Lesenswert?

so hier mal mit speicher Funktion:

1
.include "m32def.inc"                    ; bzw. 2333def.inc
2
 
3
.def temp    = R16
4
.def Data    = R17
5
.def Count   = R18
6

7

8

9
.equ CLOCK   = 16000000
10
.equ BAUD    = 9600
11
.equ UBRRVAL = CLOCK/(BAUD*16)-1
12
 
13
.org 0x00
14
        rjmp main
15
 
16
.org URXCaddr                             ; Interruptvektor für UART-Empfang
17
        rjmp Recive1
18

19

20
;Hauptprogramm
21
main:
22
        ldi temp, LOW(RAMEND)
23
        out SPL, temp
24
        ldi temp, HIGH(RAMEND)
25
        out SPH, temp
26

27
        ldi temp, 0xFF                    ; Port D = Ausgang
28
        out DDRD, temp
29

30
        ldi temp, 0b01100000
31
        out PortD, temp
32
 
33
        ; Baudrate einstellen
34
        ldi temp, HIGH(UBRRVAL)
35
        out UBRRH, temp
36
        ldi temp, LOW(UBRRVAL)
37
        out UBRRL, temp
38
 
39
        ; Frame-Format: 8 Bit
40
        ldi r16, (1<<URSEL)|(1<<USBS)|(1<<UCSZ1)|(1<<UCSZ0)
41
        out UCSRC, temp
42
 
43
        sbi UCSRB, RXCIE                  ; Interrupt bei Empfang
44
        sbi UCSRB, RXEN                   ; RX (Empfang) aktivieren
45
        sbi UCSRB, TXEN                ; TX (Senden) aktivieren 
46
        
47
        sei                               ; Interrupts global aktivieren
48
        
49
loop:  
50

51
    ldi temp, 0b01100000
52
        out PortD, temp
53
  
54
    rjmp loop                         ; Endlosschleife
55

56
Recive1:
57

58
       in Data, UDR                      ; Empfangenes Byte in Data speichern
59
     cpi  Data, 0x15
60
     brne Ende
61
     
62
     rjmp header_init
63

64
       Ende:
65
     reti                               ; zurück zum Hauptprogramm
66

67

68
Recive:
69

70
       sbis UCSRA, RXC
71
     rjmp Recive
72
       in Data, UDR                      ; Empfangenes Byte in Data speichern
73
     ret  
74

75

76

77
Transmit:
78
    
79

80
                    ldi temp, 20
81
       wait1:
82
                    push temp
83
                    ldi temp, 200
84
       wait1_1:                               
85
                    nop
86
                    nop
87
                    nop
88
                    nop
89
                    nop
90
                    dec temp
91
                    cpi temp, 0
92
                    brne wait1_1
93
                    pop temp
94
                    dec temp
95
                    cpi temp, 0
96
                    brne wait1
97

98

99
       sbis UCSRA, UDRE                   ; Warten bis UDR ist
100
       rjmp Transmit
101
       out UDR, Data                      ; Data senden
102
     ret
103

104
       
105

106
header_init:
107

108
       cbi  PORTD, 5
109
    
110
     cbi UCSRB, RXCIE                   ; Interrupt bei Empfang deaktivieren
111
    
112
     
113
     ldi  Data, 0x13
114
     rcall Transmit
115
    
116
    
117
     ldi     r30,LOW(Header)
118
       ldi     r31,HIGH(Header)
119
     ldi  Count, 49                    ; Counter der bytes zählt aktivieren
120

121
       
122
header_recive:
123
       
124
     
125
       rcall Recive
126
     st Z+, Data
127
     
128
     dec Count
129
     cpi Count, 0
130
     brne header_recive
131
     
132

133

134

135
     ldi Data, 0x06
136
     rcall Transmit
137
     
138

139
     ldi Count, 16
140
     ldi r30,LOW(Content)
141
       ldi r31,HIGH(Content)
142
data_recive:
143
     rcall Recive
144
     st Z+, Data
145
     dec count
146
     cpi Count, 0
147
     brne data_recive
148

149

150

151
     ldi Data, 0x06
152
     rcall Transmit
153

154
    
155

156

157
       ldi Count, 50
158
     ldi r30,LOW(End_Header)
159
       ldi r31,HIGH(End_Header)
160

161
end_header_recive:
162
       
163
       rcall Recive
164
     st Z+, Data
165
     dec Count
166
     cpi Count, 0
167
     brne end_header_recive
168
    
169

170

171

172

173
     ldi Data, 0x06
174
     rcall Transmit
175

176

177

178
Check:
179

180
ldi r30,LOW(Content)
181
ldi r31,HIGH(Content)
182

183
ld r19, Z
184
 
185
cpi r19, 2
186

187
brne Neustart
188

189
cbi  PORTD, 6
190

191

192

193

194
  
195
      
196

197
Neustart:
198

199

200
    sbi UCSRB, RXCIE                   ; Interrupt bei Empfang aktivieren
201
    reti
202

203

204

205

206

207
.DSEG                                      ; das Folgende kommt ins SRAM
208
Header:     .BYTE  50
209
Content:    .BYTE  16
210
End_Header: .Byte  50


nur leider will das ni so wie ich will...der vergleich ist nicht 
erfolgreich...
Gast #625054
Lesenswert?

Hallo Florentin,

das kann es auch nicht - aus mehreren Gründen aber der Reihe nach:

Du solltest zuerst mal "aufräumen"

1. vor brne muß kein cpi, wenn Du auf "0" vergleichst
2. den Z-Pointer mußt Du auch initialisieren (z.B. auf Ramstart)
3. es heißt "receive"

Otto
Gast #625063
Lesenswert?

Hallo Florentin,

auf RAMSTART zu initialisieren geht z.B. so:

Z_INIT:  ldi temp, LOW(RAMSTART)  ; Wert LO initialisieren
  mov ZL, temp         ; Z-Register low
      ldi temp, HIGH(RAMSTART) ;
      mov ZH, temp         ; Z-Register high
  ret

Verstehe es bitte nicht falsch - Du solltest Deinen Code
zuerst mal aufräumen, sonst findet sich evtl. keiner, der
Lust hat, sich da durch zu wühlen.....

Gruss Otto
Gast #625197
Lesenswert?

Welches Modell hast du genau?

@Michael
Du hast 8Mhz verwendet, d.h. du hättest mindestens auch die Hälfte der 
"Waitstates" einlegen müssen. Zumindest (9850, 32kb, schwarz) bei meinem 
funktioniert auch 8n1 und Mega162 mit 14,7Mhz. Naja und mit dem PC 
klappt es ja auch....
Was ich so gefunden habe, scheint der schon mindestens ein UART zu 
haben, nur keine Interrupts bzw. halt deaktiviert.
OP #625215
Lesenswert?

hier mal aufgeräumt:
1
.include "m32def.inc"                    ; bzw. 2333def.inc
2
 
3
.def temp    = R16
4
.def Data    = R17
5
.def Count   = R18
6

7

8

9
.equ CLOCK   = 16000000
10
.equ BAUD    = 9600
11
.equ UBRRVAL = CLOCK/(BAUD*16)-1
12
 
13
.org 0x00
14
        rjmp main
15
 
16
.org URXCaddr                             ; Interruptvektor für UART-Empfang
17
        rjmp Receive1
18

19

20
;Hauptprogramm
21
main:
22
        ldi temp, LOW(RAMEND)
23
        out SPL, temp
24
        ldi temp, HIGH(RAMEND)
25
        out SPH, temp
26

27
        ldi temp, 0xFF                    ; Port D = Ausgang
28
        out DDRD, temp
29

30
        ldi temp, 0b01100000
31
        out PortD, temp
32
 
33
        ; Baudrate einstellen
34
        ldi temp, HIGH(UBRRVAL)
35
        out UBRRH, temp
36
        ldi temp, LOW(UBRRVAL)
37
        out UBRRL, temp
38
 
39
        ; Frame-Format: 8 Bit
40
        ldi r16, (1<<URSEL)|(1<<USBS)|(1<<UCSZ1)|(1<<UCSZ0)
41
        out UCSRC, temp
42
 
43
        sbi UCSRB, RXCIE                  ; Interrupt bei Empfang
44
        sbi UCSRB, RXEN                   ; RX (Empfang) aktivieren
45
        sbi UCSRB, TXEN                ; TX (Senden) aktivieren 
46
        
47
        sei                               ; Interrupts global aktivieren
48
        
49
loop:  
50

51
    ldi temp, 0b01100000
52
        out PortD, temp
53
  
54
    rjmp loop                         ; Endlosschleife
55

56
Receive1:
57

58
       in Data, UDR                      ; Empfangenes Byte in Data speichern
59
     cpi  Data, 0x15
60
     brne Ende
61
     
62
     rjmp header_init
63

64
       Ende:
65
     reti                               ; zurück zum Hauptprogramm
66

67

68
Receive:
69

70
       sbis UCSRA, RXC
71
     rjmp Receive
72
       in Data, UDR                      ; Empfangenes Byte in Data speichern
73
     ret  
74

75

76

77
Transmit:
78
    
79

80
                    ldi temp, 20
81
       wait1:
82
                    push temp
83
                    ldi temp, 200
84
       wait1_1:                               
85
                    nop
86
                    nop
87
                    nop
88
                    nop
89
                    nop
90
                    dec temp
91
                    brne wait1_1
92
                    pop temp
93
                    dec temp
94
                    brne wait1
95

96

97
       sbis UCSRA, UDRE                   ; Warten bis UDR ist
98
       rjmp Transmit
99
       out UDR, Data                      ; Data senden
100
     ret
101

102
       
103

104
header_init:
105

106
       cbi  PORTD, 5
107
    
108
     cbi UCSRB, RXCIE                   ; Interrupt bei Empfang deaktivieren
109
    
110
     
111
     ldi  Data, 0x13
112
     rcall Transmit
113
    
114
    
115
     ldi     r30,LOW(Header)
116
       ldi     r31,HIGH(Header)
117
     ldi  Count, 49                    ; Counter der bytes zählt aktivieren
118

119
       
120
header_receive:
121
       
122
     
123
       rcall Receive
124
     st Z+, Data
125
     
126
     dec Count
127
     brne header_receive
128
     
129
     ldi Data, 0x06
130
     rcall Transmit
131
     
132

133
     ldi Count, 16
134
     ldi r30,LOW(Content)
135
       ldi r31,HIGH(Content)
136
data_receive:
137
     rcall Receive
138
     st Z+, Data
139
     dec count
140
     brne data_receive
141

142
     ldi Data, 0x06
143
     rcall Transmit
144

145
       ldi Count, 50
146
     ldi r30,LOW(End_Header)
147
       ldi r31,HIGH(End_Header)
148

149
end_header_receive:
150
       
151
       rcall Receive
152
     st Z+, Data
153
     dec Count
154
     brne end_header_receive
155

156
     ldi Data, 0x06
157
     rcall Transmit
158

159

160

161
Check:
162

163
ldi r30,LOW(Content)
164
ldi r31,HIGH(Content)
165

166
ld r19, Z
167

168
brne Neustart
169

170
cbi  PORTD, 6
171

172

173
Neustart:
174

175

176
    sbi UCSRB, RXCIE                   ; Interrupt bei Empfang aktivieren
177
    reti
178

179

180

181
.DSEG                                      ; das Folgende kommt ins SRAM
182
Header:     .BYTE  50
183
Content:    .BYTE  16
184
End_Header: .Byte  50



mit dem Z-Pointer initialisieren habe ich auch noch nicht ganz 
begriffen. Das habe ich noch nirgendwo gelesen. Aber es scheint logisch.
Gast #625241
Lesenswert?

Hallo Florentin,

der Warteschleife solltest Du ein 2. Register
spendieren und nicht mit "push" und "pop"
arbeiten.

Die im SRAM gespeicherten Konstanten werden
von den Routinen überschrieben - da kann ich
keinen Sinn erkennen.

Beispiel:

den Z-Pointer (R30 und R31) hast Du mittels:

ldi r30,LOW(Content)
ldi r31,HIGH(Content)

auf die Adresse von "content" gelegt.

                       ldi Count, 16
                       ldi r30,LOW(Content)
                       ldi r31,HIGH(Content)
data_receive:          rcall Receive
                       st Z+, Data
                       dec count
                       brne data_receive

mit "st Z+" speicherst Du Daten ab dieser
Adresse und überschreibst damit

"END_Header"

Gruss Otto
Gast #625370
Lesenswert?

Hallo,

     ldi r30,LOW(Content)
     ldi r31,HIGH(Content)

data_receive:      rcall Receive
                   st Z+, Data
                   dec count
                   brne data_receive

> sezt den Z Pointer auf Content

ja, aber sndchliessend durchläufst Du
16 x Data_receive und speicherst die Daten
mit Z+ d.h. die Daten werden gespeichert
unter

content
content+1
content+2
..
..
OP #626608
Lesenswert?

ich habs jetzt so gemacht. aber es geht leider immer noch nicht.

1
.include "m32def.inc"                    ; bzw. 2333def.inc
2
 
3
.def temp    = R16
4
.def Data    = R17
5
.def Count   = R18
6

7

8

9
.equ CLOCK   = 16000000
10
.equ BAUD    = 9600
11
.equ UBRRVAL = CLOCK/(BAUD*16)-1
12
 
13
.org 0x00
14
        rjmp main
15
 
16
.org URXCaddr                             ; Interruptvektor für UART-Empfang
17
        rjmp Receive1
18

19

20
;Hauptprogramm
21
main:
22
        ldi temp, LOW(RAMEND)
23
        out SPL, temp
24
        ldi temp, HIGH(RAMEND)
25
        out SPH, temp
26

27
        ldi temp, 0xFF                    ; Port D = Ausgang
28
        out DDRD, temp
29

30
        ldi temp, 0b01100000
31
        out PortD, temp
32

33
        ; Baudrate einstellen
34
        ldi temp, HIGH(UBRRVAL)
35
        out UBRRH, temp
36
        ldi temp, LOW(UBRRVAL)
37
        out UBRRL, temp
38
 
39
        ; Frame-Format: 8 Bit
40
        ldi r16, (1<<URSEL)|(1<<USBS)|(1<<UCSZ1)|(1<<UCSZ0)
41
        out UCSRC, temp
42
 
43
        sbi UCSRB, RXCIE                  ; Interrupt bei Empfang
44
        sbi UCSRB, RXEN                   ; RX (Empfang) aktivieren
45
        sbi UCSRB, TXEN                ; TX (Senden) aktivieren 
46
        
47
        sei                               ; Interrupts global aktivieren
48
        
49
loop:  
50

51
    ldi temp, 0b01100000
52
        out PortD, temp
53
  
54
    rjmp loop                         ; Endlosschleife
55

56
Receive1:
57

58
       in   r20, SREG   
59
       in Data, UDR          ; Empfangenes Byte in Data speichern
60
       cpi  Data, 0x15
61
     brne Ende
62
     rjmp header_init
63

64
       Ende:
65
     out SREG, r20 
66
     reti                               ; zurück zum Hauptprogramm
67

68

69
Receive:
70

71
       sbis UCSRA, RXC
72
     rjmp Receive
73
       in Data, UDR                      ; Empfangenes Byte in Data speichern
74
     ret  
75

76

77

78
Transmit:
79
    
80

81
                    ldi temp, 20
82
       wait1:
83
                    push temp
84
                    ldi temp, 200
85
       wait1_1:                               
86
                    nop
87
                    nop
88
                    nop
89
                    nop
90
                    nop
91
                    dec temp
92
                    brne wait1_1
93
                    pop temp
94
                    dec temp
95
                    brne wait1
96

97

98
       sbis UCSRA, UDRE                   ; Warten bis UDR ist
99
       rjmp Transmit
100
       out UDR, Data                      ; Data senden
101
     ret
102

103
       
104

105
header_init:
106

107
       cbi  PORTD, 5
108
    
109
     cbi UCSRB, RXCIE                   ; Interrupt bei Empfang deaktivieren
110
    
111
     
112
     ldi  Data, 0x13
113
     rcall Transmit
114
    
115
    
116
     ldi     r30,LOW(Header)
117
       ldi     r31,HIGH(Header)
118
     ldi  Count, 49                    ; Counter der bytes zählt aktivieren
119

120
       
121
header_receive:
122
       
123
     
124
       rcall Receive
125
     st Z+, Data
126
     
127
     dec Count
128
     brne header_receive
129
     
130
     ldi Data, 0x06
131
     rcall Transmit
132
     
133

134
     ldi Count, 16
135
     ldi r30,LOW(Content)
136
       ldi r31,HIGH(Content)
137
data_receive:
138
     rcall Receive
139
     st Z+, Data
140
     dec count
141
     brne data_receive
142

143
     ldi Data, 0x06
144
     rcall Transmit
145

146
       ldi Count, 50
147
     ldi r30,LOW(End_Header)
148
       ldi r31,HIGH(End_Header)
149

150
end_header_receive:
151
       
152
       rcall Receive
153
     st Z+, Data
154
     dec Count
155
     brne end_header_receive
156

157
     ldi Data, 0x06
158
     rcall Transmit
159

160

161

162
Check:
163

164
ldi r30,LOW(Content)
165
ldi r31,HIGH(Content)
166

167
ld r19, Z
168

169
brne Neustart
170

171
cbi  PORTD, 6
172

173

174
Neustart:
175

176

177
    sbi UCSRB, RXCIE                   ; Interrupt bei Empfang aktivieren
178
    reti
179

180

181

182
.DSEG                                      ; das Folgende kommt ins SRAM
183
Header:     .BYTE  50
184
Content:    .BYTE  16
185
End_Header: .Byte  50
OP #626728
Lesenswert?

so kaum ist das eine Problem gelöst hat man auch schon das nächste am 
Hals. ich wollte jetzt machen, das man mehrere Dioden via Rechner an und 
aus schalten kann...aber jetzt gehts nimmer. Das äusert sich in sofern, 
dass das prog einmal durchläuft auch ordentlich kommuniziert mit dem 
Reechner...aber keine Diode geht an. Und wenn ich dann ein zweites mal 
was sende was vorher ging kommt jetzt nen Error.
Angehängte Dateien:
OP #626917
Lesenswert?

die überprüft die vom Rechner gesendete Variable auf den einen Wert der 
dann die entsprechende LED aktiviert. Hä die ist doch schon aktiviert. 
Die wird dann nur später deaktiviert und am ende wieder aktiviert.


Also wenn ein Interrupt ausgelöst wird, aber die Bedingung nicht erfüllt 
ist springter inne Schleife. Interrupt ist aber noch aktiv...und wenns 
erfolgreich war springt er zu header_init und da wird sie deaktiviert 
und am ende aktiviert wenn die Übertragung komplett ist.
Gast #627177
Lesenswert?

Hallo Florentin,

>die überprüft die vom Rechner gesendete Variable auf den einen Wert der
dann die entsprechende LED aktiviert.

Kannst Du das Programm vom GTR mal bitte in den Anhang stellen?

Dann kann man das evtl. hier mal nachvollziehen.


Danke
AxelR.
OP #627307
Lesenswert?

ok ein Problem hätte ich gelöst...und zwar hatte ich immer nur versucht 
2 zu senden und genau die LED war falsch angeschlossen auf dem 
Steckbrett. Aber es bleibt immer noch das Problem, das es nicht mehr 
richtig weiter empfängt nach einer Übertragung und das ich auf dem 
Rechner immer nen Error erhalte. Ich vermute es springt nicht richtig 
zurück, weil ich weitere Unterroutinen Aufrufe.

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