Forum: Mikrocontroller und Digitale Elektronik ATmega8 + RS232: nicht immer (mal wieder)


von Johannes (Gast)


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

von Karl H. (kbuchegg)


Lesenswert?

>   cp statn, stato     ; wenn sich seit letzter messung nichts getan hat
>   brne start_capt
>
>   sbrs flags, 0

Wieso 0?
Das müsste doch Bit 1 sein, dass dir den Empfang eines Zeichens
anzeigt.


Müsste das nicht eigentlich

   sbrC flags, 1

heissen?

von Johannes (Gast)


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

von Karl H. (kbuchegg)


Lesenswert?

Du hast recht. Da komm ich immer durcheinander, wann man eine
Maskie angiebt und wann eine Bitnummer :-) Muss immer nachschauen.

Dann seh ich auch nicht wo das Problem liegen würde.

von Sonic (Gast)


Lesenswert?

Hi, du hast die Baudrate mit '.equ UBRRVAL = CLOCK/(BAUD*16)-1'
berechnet.
Probier's mal mit '.equ UBRRVAL = CLOCK/(BAUD*16L)-1' (die 16 als long), 
sonst wird die Baudrate falsch berechnet.

von Sonic (Gast)


Lesenswert?

ups.. sorry, war noch bei C!

von Ingo (Gast)


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.

von Johannes (Gast)


Lesenswert?

@ ingo:

ich habs die schaltung nochmal vom board her überprüft, bin auf das 
ergebnis im bild gekommen:
http://img516.imageshack.us/my.php?image=scan007bv8.jpg

müsste doch eingentlich stimmen, oder?

von Ingo (Gast)


Lesenswert?

nein, der Kondensator an V+ muß mit der anderen Seite an GND. Die 
anderen unbenutzten Eingänge des MAX232 solltest Du fest definieren; 
damit der sich nix einfangen kann.

Gruss, Ingo.

von Ingo (Gast)


Lesenswert?

ach, schade: ich sehe gerade im Datenblatt, dass VCC für den Kondensator 
auch ok ist. Gut, Du kannst es also so lassen, ist richtig.

von Johannes A. (Gast)


Lesenswert?

> Die
> anderen unbenutzten Eingänge des MAX232 solltest Du fest definieren;
> damit der sich nix einfangen kann.

Das ist nicht nötig. Der Chip hat eingebaute Pullups auf der TTL- und 
Pulldowns auf der RS232-Seite.

von Johannes (Gast)


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

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.