mikrocontroller.net

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


Autor: Johannes (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.
; ******************************************************
; BASIC .ASM template file for AVR
; ******************************************************

.include "m8def.inc"

; Define here the variables
;

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

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

; t = t5 YH YL ZH ZL

.def t5 = r25  ; letztes byte des timestamps

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

.equ CLOCK = 14745600
.equ BAUD = 9600
.equ UBRRVAL = CLOCK/(BAUD*16)-1

.equ C_CYC = 96
.equ PRESC = 8
.equ OCR = (C_CYC / PRESC) - 1


; Define here Reset and interrupt vectors, if any
;
.org 0x000                    ; kommt ganz an den Anfang des Speichers
         rjmp start           ; Interruptvektoren überspringen
                              ; und zum Hauptprogramm
      reti      ; IRQ0 Handler
      reti      ; IRQ1 Handler
      reti
      reti
      reti      ; Timer1 Capture Handler
      reti      ; Timer1 CompareA Handler
      reti      ; Timer1 CompareB Handler
      reti      ; Timer1 Overflow Handler
      reti      ; Timer0 Overflow Handler
      reti      ; SPI Transfer Complete Handler
      rjmp UAR     ; USART RX Complete Handler      
      reti      ; UDR Empty Handler
      reti      ; USART TX Complete Handler
      reti      ; ADC Conversion Complete Interrupt Handler
      reti      ; EEPROM Ready Handler
      reti      ; Analog Comparator Handler
      reti      ; Two-wire Serial Interface Handler
      reti      ; Store Program Memory Ready Handler
      


; Program starts here after Reset
;
start:
  ; stack
  ldi tmp, LOW(RAMEND)
  out SPL, tmp
  ldi tmp, HIGH(RAMEND)
  out SPH, tmp
  
  ; ram-pointer for data
  ldi XL, LOW(RS)
  ldi XH, HIGH(RS)
  
  ; baudrate
  ldi tmp, LOW(UBRRVAL)
  out UBRRL, tmp
  ldi tmp, HIGH(UBRRVAL)
  out UBRRH, tmp

  ; frameformat
  ldi tmp, (1<<URSEL)|(3<<UCSZ0)
  out UCSRC, tmp
  
  ; TX aktivieren
  sbi UCSRB, TXEN
  sbi UCSRB, RXEN
  sbi UCSRB, RXCIE

  ; messwert-count auf 0 setzen
  clr mwc

  ; register initialisieren
  clr com_reg
  clr flags
  clr stop
  
  inc mwc           ; messwert-counter um 1 erhöhen
  
  
  ; interrupts
  sei

f_loop:

  ldi debug, 0x66
  
  clr tmp
  mov statn, tmp
      
  cp statn, stato     ; wenn sich seit letzter messung nichts getan hat
  brne start_capt

  sbrs flags, 0
  rjmp f_n_com_sw
  cbr flags, 1
  rcall com_sw  ; kommunikation-switch für empfangenes byte

f_n_com_sw:

  rjmp f_loop


start_capt:
  rjmp start_capt

;==================================================================  
;==================================================================  



serout:        ; byte über serielle schnitstelle senden
  ldi debug, 0x04
  sbis UCSRA,UDRE
  rjmp serout
  out UDR, tmp
  ret
  
;==================================================================  
  
UAR:          ; empfangenes byte sichern und t-bit setzen  
  in srg, SREG  
  in com_reg, UDR
  sbr flags, 1
  out SREG, srg
  reti
  

;==================================================================  
  
  
com_sw:

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

  cpi com_reg, 0x64    ; debug-byte
  brne n_dbg
  mov tmp, debug
  rcall serout
  rjmp by_p


n_dbg:

  cpi com_reg, 0x62    ; reset-byte
   brne n_resb
  in tmp, WDTCR
  ori tmp, (1<<WDCE)|(1<<WDE)
  out WDTCR, tmp
  ldi tmp, (1<<WDE)
  out WDTCR, tmp
  cli
endl:  rjmp endl

n_resb:

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

send6:
  ld tmp, X+
  rcall serout

  dec mwc
  cpse mwc, tmp2
  rjmp send6

  ldi stop, 0x01    ; messwert-erfassung stoppen

  rjmp by_p

n_send:
  
by_p:  ret        ; byte processed
  

mfg, johannes

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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?

Autor: Johannes (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Sonic (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Sonic (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ups.. sorry, war noch bei C!

Autor: Ingo (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Johannes (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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?

Autor: Ingo (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Ingo (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Johannes A. (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Johannes (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.