Atmega zu schnell

#945210
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?
1
sendSPI:
2
  ldi  r20,0b00101110  ; master [clk(5) mosi(3)  ss(2)]=outp
3
  out  DDRB,r20
4
  in  r16,SPSR  ; dummy read
5
  ldi  r20,0b11111111  ; Befehl[FF] für Temp-Sensor(Temp senden)
6
  cbi  portb,2  ; bit 2 von portb auf 0 = cs low
7
  out  spdr,r20  ; 1.byte senden
8
  ret
9

10
receiveSPI:
11
  in  r16,SPSR
12
  sbrs  r16,SPIF  ; warte auf transmitflag
13
  rjmp  receiveSPI
14
  ;sbi  portb,2  ; cs auf high
15
  in  r18,spdr  ; 1.Byte wird empfangen
16
  out  spdr,r20  ; 2.Byte senden
17
  ret
18
receiveSPI2:
19
  in  r16,SPSR
20
  sbrs  r16,SPIF  ; warte auf transmitflag
21
  rjmp  receiveSPI2
22
  sbi  portb,2  ; cs auf high
23
  in  r19,spdr  ; 2.Byte wird empfangen
24

25

26

27
  ret
28

29

30
;--------------------------------------------------------------
31
putTemp:
32
  lds  r16,UCSR0A
33
  sbrs  r16,5  ; Senderegister nicht leer?
34
  ret    ; ... dann Rücksprung
35
  sts  UDR0,r18
36
  sts  UDR0,r19
37

38
  ret    ; nächstes Zeichen
#945238
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.

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

10
receiveSPI:
11
  in  r16,SPSR
12
  sbrs  r16,SPIF  ; warte auf transmitflag
13
  rjmp  receiveSPI
14
  ;sbi  portb,2  ; cs auf high
15
  in  r18,spdr  ; 1.Byte wird empfangen
16
  out  spdr,r20  ; 2.Byte senden
17
  ret
18
receiveSPI2:
19
  in  r16,SPSR
20
  sbrs  r16,SPIF  ; warte auf transmitflag
21
  rjmp  receiveSPI2
22
  sbi  portb,2  ; cs auf high
23
  in  r19,spdr  ; 2.Byte wird empfangen
24

25

26

27
  ret
28

29

30

31

32

33
;--------------------------------------------------------------
34
putTemp:
35
  lds  r16,UCSR0A
36
  sbrs  r16,5  ; Senderegister nicht leer?
37
  ret    ; ... dann Rücksprung
38
  sts  UDR0,r18
39
  sts  UDR0,r19
40

41
  ret    ; nächstes Zeichen
42

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

50
  ret
Gast #945297
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
#945648
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.
#945678
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
#945687
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
Gast #945707
Lesenswert?

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

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

8
  ret
9

10
putTemp:
11
  lds  r16,UCSR0A
12
  sbrs  r16,5  ; Senderegister nicht leer?
13
  ret    ; ... dann Rücksprung
14
  sts  UDR0,r18
15
  sts  UDR0,r19
16

17
  ret    ; nächstes Zeichen
Gast #945826
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).
Gast #945848
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
Gast #945914
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

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