Hallo Forum,

ich möchte mit 3 DA-Wandlern LTC1257 analoge Spannungen ausgeben.
Diese DA-Wandler hängen hintereinander, hinter Optokopplern und müssen daher mit invertierten Signalen angesteuert werden.

Ich habe dazu eine Sub Analog, welche die 3 Sollspannungen übergeben bekommt.
Um nun nicht laufend identische Werte in die DA-Wandler zu shiften, möchte ich einen Vergleich zwischen bereits geladenen Werten und neuen Werten durchführen und nur bei Differenz neu laden.

Testweise rufe ich die Sub zyklisch mit identischen Werten auf - dennoch werden unterschiedliche Parameter erkannt.

Wo ist hier der Fehler?

Hier eine Beispielausgabe aus dem Terminal:

1000 0 2000 0 3000 0
1000 1000 331 2000 3000 3000
1000 1000 2000 331 3000 3000
1000 1000 2000 2000 364 3000
1000 1000 2000 2000 3000 364
800 1000 2000 2000 3000 3000
1000 800 2000 2000 3000 3000
1000 1000 288 2000 3000 3000
1000 1000 2000 288 3000 3000
288 1000 2000 2000 3000 3000
1000 288 2000 2000 3000 3000
1000 1000 288 2000 3000 3000
1000 1000 2000 288 3000 3000
288 1000 2000 2000 3000 3000
1000 288 2000 2000 3000 3000
1000 1000 2000 2000 288 3000
1000 1000 2000 2000 3000 288
1000 1000 2000 2000 2848 3000
1000 1000 2000 2000 3000 2848
353 1000 2000 2000 3000 3000
1000 353 2000 2000 3000 3000
1000 1000 2000 2000 314 3000
1000 1000 2000 2000 3000 314
288 1000 2000 2000 3000 3000
1000 288 2000 2000 3000 3000
288 1000 2000 2000 3000 3000
1000 288 2000 2000 3000 3000
288 1000 2000 2000 3000 3000
1000 288 2000 2000 3000 3000
800 1000 2000 2000 3000 3000
1000 800 2000 2000 3000 3000
1000 1000 288 2000 3000 3000
1000 1000 2000 288 3000 3000
288 1000 2000 2000 3000 3000
1000 288 2000 2000 3000 3000
1000 1000 288 2000 3000 3000
1000 1000 2000 288 3000 3000
288 1000 2000 2000 3000 3000
1000 288 2000 2000 3000 3000
1000 1000 2000 2000 288 3000
1000 1000 2000 2000 3000 288
1000 1000 2000 2000 2848 3000
1000 1000 2000 2000 3000 2848
288 1000 2000 2000 3000 3000
1000 288 2000 2000 3000 3000
1000 1000 288 2000 3000 3000
1000 1000 2000 288 3000 3000
288 1000 2000 2000 3000 3000
1000 288 2000 2000 3000 3000


und nachfolgend der reduzierte Quellcode

mfG
BoGe-Ro


Code:
$regfile = "M32def.dat"
$crystal = 12288000
$hwstack = 128
$swstack = 64
$framesize = 64
$baud = 57600


'### LCD #######################################################################
Config Lcdpin = Pin , Db4 = Portb.2 , Db5 = Portb.3 , Db6 = Portb.4 , _
                       Db7 = Portb.5 , E = Portb.1 , Rs = Portb.0
Config Lcd = 20 * 4
Cursor Off Noblink
Initlcd
Lcd_enable Alias Portb.1 : Config Lcd_enable = Output
Dim Lcd_inhalt As String * 80                               'Textpuffer für Displayausgabe
Dim Lcd_inhalt_byte(80) As Byte At Lcd_inhalt Overlay
Lcd_inhalt = Space(80)
Dim Lcd_cnt As Byte
Dim Lcd_text As String * 20                                 'Temp-Variable für String-Zusammenbau
Dim Lcd_text_char(20) As Byte At Lcd_text Overlay

Declare Sub Lcd_put(byval _x As Byte , Byval _reg As Byte)
Declare Sub Lcd_print(byval _x As Byte , Byval _y As Byte , Byval _text As String)
'###############################################################################


'### Timer0-Systemtakt #########################################################
Tccr0 = &B1000_1011                                         'ctc-mode, prescaler=64
Ocr0 = 191                                                  '95=500µs   /   191=1ms
Timsk.ocie0 = 1
On Oc0 Isr_timer0


'### DA-Wandler ################################################################
A_latch Alias Portd.6 : Config A_latch = Output : Reset A_latch
A_clock Alias Portd.4 : Config A_clock = Output : Set A_clock
A_data Alias Portd.3 : Config A_data = Output
Declare Sub Analog(byval _w1 As Word , Byval _w2 As Word , Byval _w3 As Word , Byval _mamv As Byte)
'_w1 = p-soll
'_w2 = p-ist
'_w3 = 0-10V / 4-20mA
'_mav: 0=µA / 1=mV
Dim W1_alt As Word , W2_alt As Word , W3_alt As Word

Dim L_temp As Long
Dim B_temp As Byte
Dim W_temp As Word
Dim Beschleunigung As Word : Beschleunigung = 0


Enable Interrupts


Do
   L_temp = 2000
   Sreg.7 = 0
   Lcd_text = "Kanal 3: " + Str(l_temp) + Space(2) : Call Lcd_print(1 , 3 , Lcd_text)
   Sreg.7 = 1

   If Beschleunigung = 0 Then Call Analog(1000 , 2000 , 3000 , 1)
Loop
End



'### ISR's #####################################################################
Isr_timer0:
   If Beschleunigung > 0 Then Decr Beschleunigung
   Incr Lcd_cnt                                             'nächstes Zeichen im Display-Puffer
   If Lcd_cnt =< 80 Then Call Lcd_put(lcd_inhalt_byte(lcd_cnt) , 1)       'Zeichen ausgeben
   If Lcd_cnt = 81 Then Call Lcd_put(2 , 0)                 'Cursor at home (2ms)
   If Lcd_cnt = 90 Then Lcd_cnt = 0
Return





'### Sub's #####################################################################

'### DA-Wandler ################################################################
Sub Analog(_w1 , _w2 , _w3 , _mamv)
'invertierte Ansteuerung aufgrund Optokoppler
'_w1 = p-soll
'_w2 = p-ist
'_w3 = 0-10V / 4-20mA
'_mamv:0=10µA / 1=mV
Local _s1 As Single
Local _s2 As Single
Local _s3 As Single

   '4095        1
   '---- => --------
   '10 V    2.442 mV

   If _w1 <> W1_alt Or _w2 <> W2_alt Or _w3 <> W3_alt Then
      Sreg.7 = 0
      Print _w1 ; Chr(9) ; W1_alt ; Chr(9) ; _w2 ; Chr(9) ; W2_alt ; Chr(9) ; _w3 ; Chr(9) ; W3_alt
      Sreg.7 = 1
      W1_alt = _w1 : W2_alt = _w2 : W3_alt = _w3

      _s1 = _w1 * 0.4095 : _s1 = _s1 + 0.5 : _w1 = _s1
      _s2 = _w2 * 0.4095 : _s2 = _s2 + 0.5 : _w2 = _s2

      If _mamv = 1 Then
            _s3 = _w3 * 0.4095
            _s3 = _s3 + 0.5
         Else
            If _w3 >= 400 Then
                  _s3 = _w3 * 2.559375
                  _s3 = _s3 - 1023.25                       '-1023.75 + 0.5 für Rundung
               Else
                  _s3 = 0
            End If
      End If
      _w3 = _s3

      Shift _w1 , Left , 4 : _w1 = _w1 Xor &HFFFF
      Shift _w2 , Left , 4 : _w2 = _w2 Xor &HFFFF
      Shift _w3 , Left , 4 : _w3 = _w3 Xor &HFFFF
      Shiftout A_data , A_clock , _w3 , 0 , 12 , 10
      Shiftout A_data , A_clock , _w2 , 0 , 12 , 10
      Shiftout A_data , A_clock , _w1 , 0 , 12 , 10
      Set A_latch : Waitms 1 : Reset A_latch
   End If
End Sub


'### LCD #######################################################################
'
Sub Lcd_print(byval _x As Byte , Byval _y As Byte , _text As String * 20)
'Z1S1 = 1-20
'Z2S1 = 41-60
'Z3S1 = 21-40
'Z4S1 = 61-80
Local _position As Byte
Local _anzahl As Byte
Local _i As Byte
   Select Case _y
      Case 1 : _position = 0
      Case 2 : _position = 40
      Case 3 : _position = 20
      Case 4 : _position = 60
   End Select
   _position = _position + _x
   _anzahl = Len(_text)
'   _i = Memcopy(_text , Lcd_inhalt_byte(_position) , _anzahl)
   For _i = 1 To _anzahl
      If Lcd_text_char(_i) = "ü" Then Lcd_text_char(_i) = $f5
      If Lcd_text_char(_i) = "ö" Then Lcd_text_char(_i) = $ef
      If Lcd_text_char(_i) = "ä" Then Lcd_text_char(_i) = $e1
      If Lcd_text_char(_i) = "ß" Then Lcd_text_char(_i) = $e2
      Lcd_inhalt_byte(_position) = Lcd_text_char(_i)
      Incr _position
      If _position = 81 Then Exit For
   Next _i
End Sub


Sub Lcd_put(_x As Byte , _reg As Byte)
' _reg=1: Datenregister
' _reg=0: Befehlsregister
Local Lcd_data As Byte
   Lcd_data = _x And &HF0 : Shift Lcd_data , Right , 2      'oberes Nibble
   Portb = Lcd_data + _reg                                  'Datenbyte auf Bus legen
   !nop
   !nop
   Lcd_enable = 1
   !nop
   !nop
   Lcd_enable = 0

   Lcd_data = _x And &H0F : Shift Lcd_data , Left , 2       'unteres Nibble
   Portb = Lcd_data + _reg                                  'Datenbyte auf Bus legen
   !nop
   !nop
   Lcd_enable = 1
   !nop
   !nop
   Lcd_enable = 0
End Sub