- LiFePO4 Speicher Test         
Seite 2 von 2 ErsteErste 12
Ergebnis 11 bis 18 von 18

Thema: RS232 to I2C Adapter von Robotikhardware

  1. #11
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    29.10.2004
    Ort
    GRAZ
    Alter
    57
    Beiträge
    576
    Anzeige

    Praxistest und DIY Projekte
    Hallo Jaecko
    Ja, du hast Recht...
    Da war ja mal was mit lesen = +1
    Durch die Binärzahlen hatte ich das ganz vergessen .

    Ich hatte jetzt ein 24C EEProm angesprochen. (schreiben)
    (EEprom noch nicht angehängt)

    Adresse 160 mit einen Schreibwert von 000
    Ergibt Binär: 1010 0000 0000 0000
    161 ergibt das gleiche: 1010 0000 0000 0000 (wegen schreiben)
    162 ergibt : 1010 0011 0000 0000 (falsch ?)
    163 ergibt : 1010 0011 0000 0000 (falsch ?)
    164 ergibt : 1010 0100 0000 0000
    irgendwie fehlt da aber das NAck-Bit ??
    Wenn ich dann schreibe
    160 und 128: 1010 0000 1000 0000
    dann zeiht mir das EEprom den 1er von 128er (2.Wert), gegen Masse!!!
    Also zu : 1010 0000 0000 0000
    (Adressleitungen vom EEprom sind alle auf Low. Also Adresse 160)

    Und da ist auch die Adresse so beschrieben wie Du gemeint hast.
    A0 ist das zweite Bit von dem ersten Byte
    Also ist A0 eigentlich A1 ?!

    Ich habe den Code mal angehängt:
    Code:
    Option Strict Off
    Option Explicit On
    Imports Microsoft.VisualBasic.PowerPacks
    Friend Class frmi2cmain
    	Inherits System.Windows.Forms.Form
    	'I2C-Bus realisiert an der PC RS232-Schnittstelle
    	'
    	'Über einen einfachen Adpater RN_PC->I2CBUS (siehe robotikhardware.de)
    	'können I2C-Bus LCD´s, Boards, Chips, Roboternetz-Baords jetzt
    	'auch über den PC angesteuert werden. Der Adapter wird einfach in
    	'den seriellen Port gesteckt. Wie üblich, können zahlreiche Busteilnehmer
    	'angeschlossen werden. Der I2C-Bus ist Steckerkompatibel zum üblichen
    	'Roboternetz-Standard
    	'Der I2C Bus Treiber liegt hier im Visual Basic Quellcode vor
    	'Wichtig sind die Funktionen:
    	'sub i2c_init()
    	'sub i2c_start()
    	'sub i2c_stop()
    	'subi2c_SendByte(wert As Byte)
    	'Function i2c_EmpfangeByte() As Byte
    	'
    	'Die Funktionen können ähnlich wie in Bascom verwendet werden:
    	'Beispielübertragung:
    	' i2c_init
    	' i2c_start
    	' i2c_sendebyte(slaveid)
    	' i2c_sendebyte(wert1)
    	' i2c_sendebyte(wert2)
    	' i2c_stop
    	'
    	'Dieses Programm demonstriert die Anwendung und stellt die Funktionen
    	'für eigene Anwendungen bereit
    	'Passenden Adapter gibts als Bausatz oder nur Platine übe robotikhardware.de
    	'Autor: Frank
    	' ---------------------------------------------------------------------------
    	
    	
    	
    	Private Sub buttInit_Click(ByVal eventSender As System.Object, ByVal eventArgs As System.EventArgs) Handles buttInit.Click
    		LabelHinweis.Visible = True
    		i2c_init()
    		ZeigePegel()
    	End Sub
    	
    	Private Sub buttReadbytes_Click(ByVal eventSender As System.Object, ByVal eventArgs As System.EventArgs) Handles buttReadbytes.Click
    		Dim i As Short
    		System.Diagnostics.Debug.Write("Empfange:")
    		buttReadbytes.Enabled = False
    		If slaveid.Text = "" Then
    			MsgBox("Eine Slave ID braucht man schon")
    			Exit Sub
    		End If
    		If Val(txtAnzahl.Text) > 5 Then
    			MsgBox("Es klappt im Demo nur mit 5 Zahlen")
    			Exit Sub
    		End If
    		
    		For i = 0 To 4
    			txtEWert(i).Text = ""
    		Next 
    		
    		i2c_start()
    		i2c_SendByte(CByte(slaveid.Text))
    		delay()
    		For i = 0 To CDbl(txtAnzahl.Text) - 1
    			txtEWert(i).Text = CStr(i2c_EmpfangeByte)
    			delay()
    			If i < (CDbl(txtAnzahl.Text) - 1) Then
    				i2c_ack((True)) : Debug.Print("ack")
    			Else
    				i2c_ack((False)) : Debug.Print("no ack")
    			End If
    			delay()
    		Next i
    		i2c_stop()
    		buttReadbytes.Enabled = True
    	End Sub
    	
    	Private Sub buttSCL_Click(ByVal eventSender As System.Object, ByVal eventArgs As System.EventArgs) Handles buttSCL.Click
    		Dim status As Boolean
    		status = MSComm1.CTSHolding 'SCL Eingang
    		set_scl((Not status)) 'SCL Ausgang
    		ZeigePegel()
    		
    	End Sub
    	
    	Private Sub buttSDA_Click(ByVal eventSender As System.Object, ByVal eventArgs As System.EventArgs) Handles buttSDA.Click
    		Dim status As Boolean
    		status = MSComm1.DSRHolding 'SDA Eingang
    		set_sda((Not status)) 'SDA Ausgang
    		ZeigePegel()
    	End Sub
    	
    	
    	
    	Private Sub buttSendByte_Click(ByVal eventSender As System.Object, ByVal eventArgs As System.EventArgs) Handles buttSendByte.Click
    		Dim i As Short
    		buttSendByte.Enabled = False
    		
    		i2c_start()
    		i2c_SendByte(CByte(txtwert(0).Text))
    		For i = 1 To 5
    			If txtwert(i).Text = "" Then Exit For
    			i2c_SendByte(CByte(txtwert(i).Text))
    			delay()
    		Next i
    		i2c_stop()
    		
    		ZeigePegel()
    		buttSendByte.Enabled = True
    	End Sub
    	
    	
    	Private Sub frmi2cmain_Load(ByVal eventSender As System.Object, ByVal eventArgs As System.EventArgs) Handles MyBase.Load
    		
    		MSComm1.PortOpen = True
    		i2c_init()
    		ZeigePegel()
    	End Sub
    	
    	
    	
    	
    	
    	
    	
    	'*********************************************************
    	'                  I2C-Funktionen
    	
    	'Initialisiert I2C Bus
    	'Muss nur einmal im Programm aufgerufen werdne
    	Sub i2c_init()
    		i2c_stop()
    		delay()
    	End Sub
    	
    	Sub i2c_start()
    		Do 
    			System.Windows.Forms.Application.DoEvents()
    		Loop Until (get_scl() = True) And (get_sda() = True) 'Warte bis Bus frei
    		set_sda((0))
    		delay()
    		set_scl((0))
    		delay()
    		
    	End Sub
    	
    	Sub i2c_stop()
    		set_sda((0))
    		set_scl((1))
    stopa: 
    		If get_scl() = 0 Then GoTo stopa
    		set_sda((1))
    	End Sub
    	
    	Sub i2c_ack(ByRef ack As Boolean)
    		If ack = True Then
    			set_sda((0))
    			pulse()
    		Else
    			set_sda((1))
    			pulse()
    			delay()
    		End If
    	End Sub
    	
    	Sub i2c_SendByte(ByRef wert As Byte)
    		Dim i As Short
    		Dim bitmask As Byte
    		
    		bitmask = 128
            For i = 1 To 7
                set_sda((0))
                If (wert And bitmask) > 0 Then
                    set_sda((1))
                Else
                    set_sda((0))
                End If
                bitmask = bitmask / 2
                delay()
                pulse()
            Next i
    		delay()
    		pulse()
    		delay()
    	End Sub
    	
    	'Liest ein Byte vom I2C-Port
    	Function i2c_EmpfangeByte() As Byte
    		Dim i As Short
    		Dim bitmask As Byte
    		
    		set_sda((1))
    		
    		i2c_EmpfangeByte = 0
            bitmask = 128
    		For i = 1 To 8
    			
    			set_scl((1))
    empanga: 
    			If get_scl() = 0 Then GoTo empanga
    			If get_sda() = True Then
    				i2c_EmpfangeByte = i2c_EmpfangeByte Or bitmask
    			End If
    			bitmask = bitmask / 2
    			set_scl((0))
    			delay()
    		Next i
    	End Function
    	
    	
    	
    	'Funktionen um Pegel bei SDA und SCL zu setzen oder zu lesen
    	
    	Sub set_sda(ByRef zustand As Boolean)
    		MSComm1.DTREnable = zustand
    	End Sub
    	
    	Sub set_scl(ByRef zustand As Boolean)
    		MSComm1.RTSEnable = zustand
    	End Sub
    	
    	Function get_scl() As Boolean
    		get_scl = MSComm1.CTSHolding
    	End Function
    	
    	Function get_sda() As Boolean
    		get_sda = MSComm1.DSRHolding
    	End Function
    	
    	Sub pulse()
    		set_scl((1)) 'Clock High bedeutet Datenbyte liegt an
    pulse1: 
    		If get_scl() = 0 Then GoTo pulse1
    		set_scl((0)) 'Nur bei Null darf Datenbit auf Datenleitung gelegt werden
    	End Sub
    	
    	'Kurze Pause, je nach Busgeschwindigkeit
    	Sub delay()
    		Dim i As Object
    		For i = 1 To 255
    		Next i
    	End Sub
    	
    	'Funktion zeigt Pegel visuell in dem Fenster an
    	Sub ZeigePegel()
    		If get_sda = True Then 'Ist SDA High?
    			LabelSDAPegel.Text = "High"
    			ShapeSDA.FillColor = System.Drawing.ColorTranslator.FromOle(QBColor(10))
    		Else
    			LabelSDAPegel.Text = "Low"
    			ShapeSDA.FillColor = System.Drawing.ColorTranslator.FromOle(QBColor(2))
    		End If
    		
    		If get_scl() = True Then 'Ist SDA High?
    			LabelSCLPegel.Text = "High"
    			ShapeSCL.FillColor = System.Drawing.ColorTranslator.FromOle(QBColor(10))
    		Else
    			LabelSCLPegel.Text = "Low"
    			ShapeSCL.FillColor = System.Drawing.ColorTranslator.FromOle(QBColor(2))
    		End If
    	End Sub
    	
    	
    	
    	
    	
    	
    	Private Sub frmi2cmain_FormClosed(ByVal eventSender As System.Object, ByVal eventArgs As System.Windows.Forms.FormClosedEventArgs) Handles Me.FormClosed
    		set_sda((1))
    		set_scl((1))
    		
    	End Sub
    
        Private Sub MSComm1_OnComm(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MSComm1.OnComm
    
        End Sub
    
        Private Sub Frame2_Enter(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Frame2.Enter
    
        End Sub
    
        Private Sub Frame1_Enter(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Frame1.Enter
    
        End Sub
    End Class

    l.G. Roberto

    Ps.:
    Lesen ergibt:

    160 = 1010 0000 11111111
    161 = 1010 0000 11111111
    162 = 1010 0011 11111111
    163 = 1010 0011 11111111
    164 = 1010 0100 11111111

    ???

  2. #12
    Erfahrener Benutzer Robotik Einstein Avatar von Jaecko
    Registriert seit
    16.10.2006
    Ort
    Lkr. Rottal/Inn
    Alter
    41
    Beiträge
    2.009
    Also wenn bei dem EEPROM (24C32) alle Adress-Pins auf Masse liegen und du nur 0xA0 als Adresse sendest, müsste ein ACK zurückkommen. Wenn NAK kommt, gibts kein Gerät mit der Adresse (oder es ist defekt etc.)
    162 = 1010 0011 stimmt dann, wenn du von 162 lesen willst.

    Bei den I2C-EEPROMs wars von der Kommunikation her so:
    Master: START senden
    Master: Adresse "schreiben" senden (Schreiben, letztes Bit = 0)
    Slave: ACK
    Master: High-Adresse Speicherzelle
    Slave: ACK
    Master: Low-Adresse Speicherzelle
    Slave: ACK
    Master: (repeated) START
    Master: Adresse "lesen" senden (letztes Bit = 1)
    Slave: ACK + Byte in gewählter Speicherzelle
    Master: ACK (wenn mehr Bytes gewünscht werden) oder NAK, wenns genug ist.
    Master: STOP.

    Wenn du nen Code in C brauchst, mit dem man solche EEPROMs schreibt/liest, sags einfach, dann stell ich die hier mal rein. Ist evtl. ne Hilfe.
    #ifndef MfG
    #define MfG

  3. #13
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    29.10.2004
    Ort
    GRAZ
    Alter
    57
    Beiträge
    576
    Hallo Jaecko
    Frage:
    Stimmst Du mir zu, dass die Binärwerte, die ich oben geschrieben habe, falsch sind ? (162 und 163)

    Irgendwie fehlt mir da auch ein ACK-Bit ?

    Bei Adresse 160 müsste ich doch haben: (schreiben)
    1010 0000 1 0000 0000
    Hatte aber nur:
    1010 0000 0000 0000
    Darum habe ich ja als zweites Byte ein 128 geschrieben, damit mir das EEprom diese 1 nach Masse ziehen kann, was es dann auch tut

    l.G.Robert Und Danke für die Infos

  4. #14
    Erfahrener Benutzer Robotik Einstein Avatar von Jaecko
    Registriert seit
    16.10.2006
    Ort
    Lkr. Rottal/Inn
    Alter
    41
    Beiträge
    2.009
    Also 162 müsste 1010 0010 sein, nicht 1010 0011.
    163 stimmt, 164 ebenfalls.

    Ein ACK/NAK kriegst du in jedem Fall nach dem Adressbyte. Die Frage ist nur woher. Wenn als 9. Bit ne 0 kommt, hat irgendjemand auf die Adresse reagiert.
    Du müsstest dir mal (sofern von der Auflösung her möglich) eine ganze I2C-Übertragung anschauen, also von START bis STOP.
    Dann lässt sich recht einfach feststellen, ob irgendwo ein ACK-Bit fehlt bzw. was denn da eigentlich gesendet wird. Das blöde ist hier aber, dass man nicht sehen kann, wer sendet.

    Und dass du beim Lesen 11111111 kriegst, liegt daran, dass der Leerlaufpegel des I2C gelesen wird (es ist ja niemand da, der SDA auf die entsprechenden richtigen Pegel setzt)
    #ifndef MfG
    #define MfG

  5. #15
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    29.10.2004
    Ort
    GRAZ
    Alter
    57
    Beiträge
    576
    Start und Stop sind vorhanden.

    Bei dem Programm kann man eine Adresse eingeben und dann halt 1 bis 5 Daten-Byte
    Beim Senden von der Adresse und einem Daten-Byte sind dann aber nur 16Bit

  6. #16
    Erfahrener Benutzer Robotik Einstein Avatar von Jaecko
    Registriert seit
    16.10.2006
    Ort
    Lkr. Rottal/Inn
    Alter
    41
    Beiträge
    2.009
    Komisch irgendwie. Bei 2 gesendeten Bytes hätte ich 18 Bit erwartet.
    Kannst du dem EEPROM mal 3 Datenbytes schicken und die Übertragung mal aufzeichnen und hier reinstellen?
    Also 1 Adressbyte (0xA0 oder wie er adressiert ist) + 3 Daten z.B. 0x00, 0xAA, 0x55. Damit sollte der EEPROM den Wert 0x55 an die Adresse 0x00AA schreiben. Vielleicht sieht man da dann was auffälliges.

    Steckt der Adapter bei dir direkt an nem echten COM-Port oder ist da ein USB-RS232-Wandler dazwischen?
    #ifndef MfG
    #define MfG

  7. #17
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    29.10.2004
    Ort
    GRAZ
    Alter
    57
    Beiträge
    576
    Hallo Jaecko

    Habe inzwischen weiterprobiert.
    Irgendwie muss ich mich wohl mit den Bit's verzählt haben... sind eh
    18 Bit bei 2 Byte.

    Habe das inzwischen auch so hinbekommen, dass das Programm beim Senden auch das Ack-Bit auf High setzt.
    Anscheinend braucht es das aber gar nicht... Es schreibt da wohl blind raus ?!
    Das mit dem Lesen, muss ich erst hinbekommen (EEprom)

    Andere Frage:
    Bei Slave-Adresse 0, müssten sich da alle Geräte mit dem Ack-Bit melden ?
    Auch ein EEprom ?
    Sehe da nix

    l.G. Robert

  8. #18
    Erfahrener Benutzer Robotik Einstein Avatar von Jaecko
    Registriert seit
    16.10.2006
    Ort
    Lkr. Rottal/Inn
    Alter
    41
    Beiträge
    2.009
    Das Ack-Bit muss Low für ACK sein; High-Level ist NAK (Leerlaufpegel)
    Nach dem Start wird immer die Slave-Adresse gesendet, sofern der Bus frei ist. Erkennt der Master dann ein NAK (9. Bit high), sollte er eigentlich die Kommunikation abbrechen, da der adressierte Slave ja nicht antwortet bzw. nicht existiert.

    Bei Adresse 0 reichts, wenn einer ACK sendet.
    Ob das Gerät auf den General Call reagiert, steht im Datenblatt bzw. wird in der Firmware (AVR) festgelegt.
    Bei nem EEPROM macht der GC wenig Sinn. Ist eher, um allgemeine Daten zu verbreiten wie z.B. Uhrzeit senden; wer sie braucht, schreibt mit, die anderen ignorierens einfach ("Adresse 0? Bin ich nicht.")
    #ifndef MfG
    #define MfG

Seite 2 von 2 ErsteErste 12

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •  

LiFePO4 Speicher Test