www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Atmega zu schnell


Autor: Andre B. (andre-atmega168)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

über die UDRO Schnittstelle übergebe ich eine 16 bit Temperatur. Die ich 
in Labview über die Visa Schnisttelle einlese. Das Problem ist 
folgendes:
Labview initialiesiert die Visa Schnittstelle bei jedem 
Schleifendurchgang neu, so dass schon ca. 1000 Bytes am Port der Visa 
Schnittstelle anliegen bevor die abgeolt werden können. Die Schittstelle 
ist also überladen, weil der uC viel schneller ist. Außerdem wird die 16 
bit Temperatut in Labview manchmal falsch angezeigt. Mal kommt das 
2.Byte vor dem 1.Byte mal umgekehrt.
Kann man den µC mit Labview synchroniesieren oder gibt es noch andere 
Mölglichlkeiten?
Kann mir jemand helfen?
sendSPI:
  ldi  r20,0b00101110  ; master [clk(5) mosi(3)  ss(2)]=outp
  out  DDRB,r20
  in  r16,SPSR  ; dummy read
  ldi  r20,0b11111111  ; Befehl[FF] für Temp-Sensor(Temp senden)
  cbi  portb,2  ; bit 2 von portb auf 0 = cs low
  out  spdr,r20  ; 1.byte senden
  ret

receiveSPI:
  in  r16,SPSR
  sbrs  r16,SPIF  ; warte auf transmitflag
  rjmp  receiveSPI
  ;sbi  portb,2  ; cs auf high
  in  r18,spdr  ; 1.Byte wird empfangen
  out  spdr,r20  ; 2.Byte senden
  ret
receiveSPI2:
  in  r16,SPSR
  sbrs  r16,SPIF  ; warte auf transmitflag
  rjmp  receiveSPI2
  sbi  portb,2  ; cs auf high
  in  r19,spdr  ; 2.Byte wird empfangen



  ret


;--------------------------------------------------------------
putTemp:
  lds  r16,UCSR0A
  sbrs  r16,5  ; Senderegister nicht leer?
  ret    ; ... dann Rücksprung
  sts  UDR0,r18
  sts  UDR0,r19

  ret    ; nächstes Zeichen


Autor: Benedikt K. (benedikt) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert

Autor: Andre B. (andre-atmega168)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
hallo,

hat jemand vielleicht schon ein Beispiel in Quellcode-Form.
bin sehr unter Zeitdruck. DANKE

Autor: Maik Fox (sabuty) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Polling?

Irgendein Zeichen an den µC gesendet, nachdem LabView die Schnittstelle 
initialisiert hat, zB ein "T". Darauf hin schickt der µC die 16 Bit an 
den PC.

Autor: Andre B. (andre-atmega168)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ja polling!

das mache ich schon, schicke bei jedem Schleifendurchgang in Labview die 
PWM-Signalbreite an den µC und lese eine Temperatur aus. Habe aber immer 
ein Dreher zwischen dem 1.Byte und dem 2.Byte.

sendSPI:
  ldi  r20,0b00101110  ; master [clk(5) mosi(3)  ss(2)]=outp
  out  DDRB,r20
  in  r16,SPSR  ; dummy read
  ldi  r20,0b11111111  ; Befehl[FF] für Temp-Sensor(Temp senden)
  cbi  portb,2  ; bit 2 von portb auf 0 = cs low
  out  spdr,r20  ; 1.byte senden
  ret

receiveSPI:
  in  r16,SPSR
  sbrs  r16,SPIF  ; warte auf transmitflag
  rjmp  receiveSPI
  ;sbi  portb,2  ; cs auf high
  in  r18,spdr  ; 1.Byte wird empfangen
  out  spdr,r20  ; 2.Byte senden
  ret
receiveSPI2:
  in  r16,SPSR
  sbrs  r16,SPIF  ; warte auf transmitflag
  rjmp  receiveSPI2
  sbi  portb,2  ; cs auf high
  in  r19,spdr  ; 2.Byte wird empfangen



  ret





;--------------------------------------------------------------
putTemp:
  lds  r16,UCSR0A
  sbrs  r16,5  ; Senderegister nicht leer?
  ret    ; ... dann Rücksprung
  sts  UDR0,r18
  sts  UDR0,r19

  ret    ; nächstes Zeichen

getPWM:
  lds  r16,UCSR0A
  sbrs  r16,7  ; Alle Daten im UDR-Register...
  ret    ; ... wenn nicht, dann Rücksprung
  lds  serdatin,UDR0  ; ... wenn doch,  dann Zeichen abholen
  sts  OCR1AL,serdatin  ; PWM bedienen

  ret


Autor: Uwe (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi!
Bin ja bischen doof, aber kannste mir deine Denkweise an der Stelle mal 
erklären:

>putTemp:
>  lds  r16,UCSR0A
>  sbrs  r16,5  ; Senderegister nicht leer?
>  ret    ; ... dann Rücksprung
>>  sts  UDR0,r18
>>  sts  UDR0,r19

Ohne nachzufragen schreibst du 2 Byte nach UDR??

MFG Uwe

Autor: Andre-Atmega168 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Genau. Die beiden Bytes schicke ich ins UDR0 und übergebe diese in 
Labview, allerdings habe ich dann fast immer eine Dreher in der 
Temperatur(wie oben beschrieben)

Autor: André (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Du koenntest zwischendrin auch einfach mal warten, bis der Uart fertig 
damit ist, das erste Byte zu senden :D. Siehe Datenblatt.

Autor: Andre-Atmega168 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
der Uart wird doch so schnell berschrieben, so dass die Daten in Labview 
gar nicht zu schnell abgeholt werden. oder meinst du was anderes

Autor: Stefan Ernst (sternst)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Nein, die Frage ist, woher weißt du beim zweiten "sts  UDR0,rXX", dass 
UDR0 schon wieder frei ist?

Und wenn die beiden Bytes verkehrt herum ankommen, dann sendest du sie 
entweder verkehrt herum, oder du hast einen Fehler im Ablauf und LabView 
und µC sind nicht mehr synchron.

Autor: Andre-Atmega168 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
die temperatur wird sporadisch mal richig mal falsch angezeigt.
Das heisst, entweder kommt das 1.Byte vor dem 2.Byte oder umgekehrt.
Die Reihenfolge im Assembler ist auch richtig.

Autor: Stefan Ernst (sternst)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Dann korrigiere erstmal das UDR0-Handling, und schaue was dann kommt.

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Andre B. wrote:
> Außerdem wird die 16
> bit Temperatut in Labview manchmal falsch angezeigt. Mal kommt das
> 2.Byte vor dem 1.Byte mal umgekehrt.

Woher soll den Labview auch wissen, welches das 1. und welchse das 
2.Byte ist?
Labview kann ja nicht hellsehen.

Dein Problem ist, Du hast kein Protokoll.

Ein einfaches Protokoll wäre, der AVR sendet nur auf Anforderung.
Z.B. Labwiev sendet ein '?' und dann erst sendet der AVR. Damit weiß 
dann Labview, welches das 1. Byte ist.


Peter

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Uwe wrote:

>>putTemp:
>>  lds  r16,UCSR0A
>>  sbrs  r16,5  ; Senderegister nicht leer?
>>  ret    ; ... dann Rücksprung
>>>  sts  UDR0,r18
>>>  sts  UDR0,r19
>
> Ohne nachzufragen schreibst du 2 Byte nach UDR??

Stimmt, der Code ist falsch.
Wenn man 2 Byte schreiben will, muß man auf das TXC0 Bit testen.
Das geht aber schief, wenn noch garnichts gesendet wurde.

Daher besser ne putchar-Funktion schreiben und die zweimal aufrufen.


Peter

Autor: Andre-Atmega168 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das habe ich ja soweit verstanden. Es hapert bei mir aber noch an der 
Umsetzung. Kann mir jemand nen Beispiel schicken. Danke.

Autor: Stefan Ernst (sternst)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Peter Dannegger wrote:

> Dein Problem ist, Du hast kein Protokoll.

Ich dachte, er hätte eins, weil er sagte:
> das mache ich schon, schicke bei jedem Schleifendurchgang in Labview die
> PWM-Signalbreite an den µC und lese eine Temperatur aus.

Autor: Andre-Atmega168 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
richtig, so mache ich das auch, es funktioniert aber nicht.

nochmal der Code.
getPWM:
  lds  r16,UCSR0A
  sbrs  r16,7  ; Alle Daten im UDR-Register...
  ret    ; ... wenn nicht, dann Rücksprung
  lds  serdatin,UDR0  ; ... wenn doch,  dann Zeichen abholen
  sts  OCR1AL,serdatin  ; PWM bedienen

  ret

putTemp:
  lds  r16,UCSR0A
  sbrs  r16,5  ; Senderegister nicht leer?
  ret    ; ... dann Rücksprung
  sts  UDR0,r18
  sts  UDR0,r19

  ret    ; nächstes Zeichen



Autor: Stefan Ernst (sternst)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
An dem Code ist nicht zu erkennen, ob du irgendein Protokoll hast, z.B. 
ob du die Temperatur immer sendest, nachdem du den neuen PWM-Wert 
bekommen hast.

Autor: Thilo M. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich hatte das Problem auch mal. Bin jetzt dazu übergegangen, die 
Messwerte in ASCII zu übertragen. LabView kann die prima einlesen, auch 
bei 115200 Baud keine Fehler drin, da ein eindeutiger Rahmen das 
Datenpaket kennzeichnet (\n zum Schluss und <spc> als Trennzeichen).

Autor: Uwe (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi!

Wie wäre es denn so:

putTemp:
lds   r16,UCSR0A
sbrs  r16,UDRE  ; Senderegister nicht leer?
rjmp  putTemp    ; ... dann Rücksprung
sts   UDR0,r18
Byte2:
lds   r16,UCSR0A
sbrs  r16,UDRE  ; Senderegister nicht leer?
rjmp  Byte2
sts   UDR0,r19
ret

Viel Erfolg, Uwe

Autor: Andre-Atmega168 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
hi,
also den dreher habe ich ich nicht mehr.(siehe die letzten 4 Zeilen bei 
"getPWM". Allerdings kriege ich periodisch immer mal wieder eine 0 
Übergeben. Die Visaschnittstelle gibt dann auch 0Bytes am Port an. Woher 
kommt die null?




getPWM:
  lds  r16,UCSR0A
  sbrs  r16,7  ; Alle Daten im UDR-Register...
  ret    ; ... wenn nicht, dann Rücksprung
  lds  serdatin,UDR0  ; ... wenn doch,  dann Zeichen abholen
  sts  OCR1AL,serdatin  ; PWM bedienen

  lds  r16,UCSR0A
  sbrs  r16,7  ; Alle Daten im UDR-Register...
  rcall putTemp
  rcall mainloop

  ret

putTemp:
  lds  r16,UCSR0A
  sbrs  r16,5  ; Senderegister nicht leer?
  ret    ; ... dann Rücksprung
  sts  UDR0,r18
  sts  UDR0,r19

  ret    ; nächstes Zeichen

Autor: Andre-Atmega168 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hat keiner ne Idee

Autor: Stefan Ernst (sternst)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Hat keiner ne Idee

Wie wäre es, wenn du erstmal das beseitigst, was dir schon mehrfach 
genannt wurde?

> sts  UDR0,r18
> sts  UDR0,r19

Autor: Andre-Atmega168 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
das habe ich schon gemacht, ändert aber auch nix

Autor: Uwe (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi!
>das habe ich schon gemacht, ändert aber auch nix
Das sah aber in deinem letzten post nicht so aus.

Sende mal feste Werte, nicht das bei deiner Einleserei was schief geht.

Viel Erfolg, Uwe

Autor: Simon K. (simon) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Andre-Atmega168 wrote:
> das habe ich schon gemacht, ändert aber auch nix

Zeig mal den berichtigten Code.

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.