ATmega8 + RS232: nicht immer (mal wieder)

Gast #431567
Lesenswert?

hi,

es geht mal wider um die kommunikation meines atmega8 mit meinem pc.
problem: der aufbau stimmt soweit, es werden zeichen nurückgesendet.
aaaber: es wird nicht jedes zeichen zurück geschickt.

wenn ich ein 'a' tippe, soll ein a zurückgeschickt werden, bei 'd' der 
wert des debug-registers ausgegeben werden

folgendes meine ich im hyperterminal beobachtet zu haben:
wenn ich hyperterminal oder die verbindung frisch öffne, dann wird das 
erste zeichen fast nie 'beantwortet'. dann läufts einige zeit ganz gut, 
wenn ich nicht zu schnell tippe. wenn ich dann aber die buchstaben 
schneller nacheinander tippe, verschluckt er öfters welche.

ich meine, dass es etwas mit der routine zur verarbeitung der eingaben 
zu tun hat und mit dem rxc-interrupt, ich selbst finde aber nicht den 
fehler.

ich habe nur wirklich das nötigste aus dem quelltext gelöscht, damit 
keine fehlerquelle übersehen wird

vielen dank an alle, die sich das ansehen.
1
; ******************************************************
2
; BASIC .ASM template file for AVR
3
; ******************************************************
4

5
.include "m8def.inc"
6

7
; Define here the variables
8
;
9

10
.def statn = r13  ; neuer status der schranken
11
.def stato = r14  ; alter status der schranken
12
.def srg = r15    ; SREG-sicherung
13
.def tmp = r16    ; erstes register für temp. werte
14
.def tmp2 = r17   ; zweites register für temp. werte
15

16
.def flags = r20  ; register für flags
17
.def mwc = r21    ; messwert-count
18
.def com_reg = r22  ; letztes kommando des pcs
19
.def stop = r23    ; stop = 1, wenn messung angehalten wurde
20
.def debug = r24  ; debug-byte
21

22
; t = t5 YH YL ZH ZL
23

24
.def t5 = r25  ; letztes byte des timestamps
25

26
.equ RS = 0x0060  ; anfang des zur freien verfügung stehenden ram-bereichs
27
.equ RE = 0x01F0  ; ende des ram
28

29
.equ CLOCK = 14745600
30
.equ BAUD = 9600
31
.equ UBRRVAL = CLOCK/(BAUD*16)-1
32

33
.equ C_CYC = 96
34
.equ PRESC = 8
35
.equ OCR = (C_CYC / PRESC) - 1
36

37

38
; Define here Reset and interrupt vectors, if any
39
;
40
.org 0x000                    ; kommt ganz an den Anfang des Speichers
41
         rjmp start           ; Interruptvektoren überspringen
42
                              ; und zum Hauptprogramm
43
      reti      ; IRQ0 Handler
44
      reti      ; IRQ1 Handler
45
      reti
46
      reti
47
      reti      ; Timer1 Capture Handler
48
      reti      ; Timer1 CompareA Handler
49
      reti      ; Timer1 CompareB Handler
50
      reti      ; Timer1 Overflow Handler
51
      reti      ; Timer0 Overflow Handler
52
      reti      ; SPI Transfer Complete Handler
53
      rjmp UAR     ; USART RX Complete Handler      
54
      reti      ; UDR Empty Handler
55
      reti      ; USART TX Complete Handler
56
      reti      ; ADC Conversion Complete Interrupt Handler
57
      reti      ; EEPROM Ready Handler
58
      reti      ; Analog Comparator Handler
59
      reti      ; Two-wire Serial Interface Handler
60
      reti      ; Store Program Memory Ready Handler
61
      
62

63

64
; Program starts here after Reset
65
;
66
start:
67
  ; stack
68
  ldi tmp, LOW(RAMEND)
69
  out SPL, tmp
70
  ldi tmp, HIGH(RAMEND)
71
  out SPH, tmp
72
  
73
  ; ram-pointer for data
74
  ldi XL, LOW(RS)
75
  ldi XH, HIGH(RS)
76
  
77
  ; baudrate
78
  ldi tmp, LOW(UBRRVAL)
79
  out UBRRL, tmp
80
  ldi tmp, HIGH(UBRRVAL)
81
  out UBRRH, tmp
82

83
  ; frameformat
84
  ldi tmp, (1<<URSEL)|(3<<UCSZ0)
85
  out UCSRC, tmp
86
  
87
  ; TX aktivieren
88
  sbi UCSRB, TXEN
89
  sbi UCSRB, RXEN
90
  sbi UCSRB, RXCIE
91

92
  ; messwert-count auf 0 setzen
93
  clr mwc
94

95
  ; register initialisieren
96
  clr com_reg
97
  clr flags
98
  clr stop
99
  
100
  inc mwc           ; messwert-counter um 1 erhöhen
101
  
102
  
103
  ; interrupts
104
  sei
105

106
f_loop:
107

108
  ldi debug, 0x66
109
  
110
  clr tmp
111
  mov statn, tmp
112
      
113
  cp statn, stato     ; wenn sich seit letzter messung nichts getan hat
114
  brne start_capt
115

116
  sbrs flags, 0
117
  rjmp f_n_com_sw
118
  cbr flags, 1
119
  rcall com_sw  ; kommunikation-switch für empfangenes byte
120

121
f_n_com_sw:
122

123
  rjmp f_loop
124

125

126
start_capt:
127
  rjmp start_capt
128

129
;==================================================================  
130
;==================================================================  
131

132

133

134
serout:        ; byte über serielle schnitstelle senden
135
  ldi debug, 0x04
136
  sbis UCSRA,UDRE
137
  rjmp serout
138
  out UDR, tmp
139
  ret
140
  
141
;==================================================================  
142
  
143
UAR:          ; empfangenes byte sichern und t-bit setzen  
144
  in srg, SREG  
145
  in com_reg, UDR
146
  sbr flags, 1
147
  out SREG, srg
148
  reti
149
  
150

151
;==================================================================  
152
  
153
  
154
com_sw:
155

156
  cpi com_reg, 0x61    ; erkennungs-byte
157
  brne n_rb               ; (un)gleich dem RecognitionByte
158
  mov tmp, com_reg        ; den gleichen wert
159
  rcall serout      ; wieder zurück senden
160
  rjmp by_p
161
    
162
n_rb:
163

164
  cpi com_reg, 0x64    ; debug-byte
165
  brne n_dbg
166
  mov tmp, debug
167
  rcall serout
168
  rjmp by_p
169

170

171
n_dbg:
172

173
  cpi com_reg, 0x62    ; reset-byte
174
   brne n_resb
175
  in tmp, WDTCR
176
  ori tmp, (1<<WDCE)|(1<<WDE)
177
  out WDTCR, tmp
178
  ldi tmp, (1<<WDE)
179
  out WDTCR, tmp
180
  cli
181
endl:  rjmp endl
182

183
n_resb:
184

185
  cpi com_reg, 0x63    ; 'daten-send'-byte
186
  brne n_send
187
  ldi XL, LOW(RS)      ; reset ram-pointer
188
  ldi XH, HIGH(RS)
189
  clr tmp2
190

191
send6:
192
  ld tmp, X+
193
  rcall serout
194

195
  dec mwc
196
  cpse mwc, tmp2
197
  rjmp send6
198

199
  ldi stop, 0x01    ; messwert-erfassung stoppen
200

201
  rjmp by_p
202

203
n_send:
204
  
205
by_p:  ret        ; byte processed

mfg, johannes
Gast #431722
Lesenswert?

@ karl heinz

müsst eigentlich so schon stimmen. ich setze das bit mit
sbr flags, 1
wobei sbr aber nicht die nummer des bits als zweiten parameter nimmt, 
sondern ein bitmuster, welches bit er setzen soll. d.h wenn ich sbr 
flags, 0x01 und sbrs flags, 0 aufrufe, verarbeite ich information aus 
dem gleichen bit.

zu srbs und sbrC:
wenn das nullte bit in flags gesetz ist, möchte ich das wieder löschen 
(cbr flags, 1) und dann in co_sw eintreten (rcall com_sw). sollte also 
imho auch stimmen

hab ich einen befehl mal wieder nicht durchschaut? oder was? :-o
Gast #431989
Lesenswert?

schau doch mal nach dem Max232; ich hatte mal ein ähnliches Problem, 
weil einer der Kondensatoren nicht richtig angeschlossen war; Dein 
Problem sieht so aus, als wenn dem MAX zwischendurch die Puste ausgeht 
...
Gruss, Ingo.
Gast #433872
Lesenswert?

so. ich hoffe, ich habe das jetzt gelöst. folgendes hab ich gemacht:

nachdem ingo (DANKE @ ingo) mich darauf gebracht hatte, dass es nicht 
unbedingt ein software problem sein muss. habe ich einfach den atmega8 
mal aus seiner fassung genommen und die pins für den µC am max232 
überbrückt.
und siehe da: wenn ich die zeichen langsam eingebe kommen sie häufiger 
zurück, als wenn ich sie schnell eingebe
=> es war schon mal klar, dass es ein hardware problem ist.
wo suchen? na dort wo es am offensichtlichsten ist. an den ausgängen des 
max232 auf der rs232-seite hatte ich nämlich eine selbstgebaute 
kabelpeitsche hängen (bestehend aus einer d-sub 9 buchse und einem rs232 
-> usb konverter, was bei meinen anfänglichen tests auch ganz gut 
funktionierte)

also den koverter von der peitsche geknipst und siehe da: jetzt kommt 
wirklich jedes zeichen zurück :-)

hoffentlich wars das :)

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