Aardvark I2C VB编程问题......关于WRITE功能API不明确

时间:2015-03-06 13:01:51

标签: vb.net api i2c eeprom

在没有深入到项目背景的情况下,我们通过使用一些非常有创意的编码,从一些标准文本字段创建了一个BIN文件。没问题 - 它运作得很好。然后,我们使用称为Aardvark的编程器将此BIN文件写入EEPROM芯片。它有自己的程序来执行此操作,称为FlashCenter,但也提供API。因为编程这个芯片对于一些员工来说是一个障碍,我们希望将这个功能包含在我们的BIN文件生成器中(即 - 生成,存储并立即将BIN文件写入EEPROM)。

唯一的问题是,由于我的知识有限,这是非常先进的,并且无法弄清楚如何使用Aardvark API提供的VB代码将BIN文件数据传递到EEPROM。我希望你不介意我提供一些示例代码,希望有人可以帮我解决这个问题。

这是Aardvark API中提供的示例VB代码: 代码:

'==========================================================================
' (c) 2004-2009  Total Phase, Inc.
  '--------------------------------------------------------------------------
' Project : Aardvark Sample Code
' File    : aai2c_eeprom.bas
   '--------------------------------------------------------------------------
' Perform simple read and write operations to an I2C EEPROM device.
'--------------------------------------------------------------------------
' Redistribution and use of this file in source and binary forms, with
' or without modification, are permitted.
'
' THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
' "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
' LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
' FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
' COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
' INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
' BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
' LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
' CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
' LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
' ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
' POSSIBILITY OF SUCH DAMAGE.
'==========================================================================
Imports TotalPhase

Module aai2c_eeprom

    '==========================================================================
' CONSTANTS
'==========================================================================
Const I2C_BITRATE As Integer = 100  'kHz
Const I2C_BUS_TIMEOUT As UShort = 150  'ms
Const I2C_DEVICE As UShort = &H54


'==========================================================================
' MAIN PROGRAM
'==========================================================================
Sub aai2c_eeprom_run(ByRef sampletext As Windows.Forms.TextBox)
    Dim handle As Long

    handle = AardvarkApi.aa_open(0)
    If (handle <= 0) Then
        sampletext.Text &= "Unable to open Aardvark device on port 0" & vbCrLf
        sampletext.Text &= "Error code = " & handle & vbCrLf
        Exit Sub
    End If

    ' Ensure that the I2C subsystem is enabled
    Call AardvarkApi.aa_configure(handle, AardvarkConfig.AA_CONFIG_SPI_I2C)

    ' Enable the I2C bus pullup resistors (2.2k resistors).
    ' This command is only effective on v2.0 hardware or greater.
    ' The pullup resistors on the v1.02 hardware are enabled by default.
    Call AardvarkApi.aa_i2c_pullup(handle, AardvarkApi.AA_I2C_PULLUP_BOTH)

    ' Power the board using the Aardvark adapter's power supply.
    ' This command is only effective on v2.0 hardware or greater.
    ' The power pins on the v1.02 hardware are not enabled by default.
    Call AardvarkApi.aa_target_power(handle, AardvarkApi.AA_TARGET_POWER_BOTH)

    ' Set the bitrate
    Dim bitrate As Long
    bitrate = AardvarkApi.aa_i2c_bitrate(handle, I2C_BITRATE)
    sampletext.Text &= "Bitrate set to " & bitrate & " kHz" & vbCrLf

    ' Set the bus lock timeout
    Dim bus_timeout As Long
    bus_timeout = AardvarkApi.aa_i2c_bus_timeout(handle, I2C_BUS_TIMEOUT)
    sampletext.Text &= "Bus lock timeout set to " & bus_timeout & " ms" & vbCrLf

    ' Write the offset and read the data
    'Dim offset(15) As Byte
    Dim offset() As Byte = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1}  'THIS IS JUST A TEST STRING, but doesn't seem to ever get written
    Dim data(128) As Byte
    Dim result As Long
    Dim k As String = String.Empty

    offset(0) = 1
    Call AardvarkApi.aa_i2c_write(handle, I2C_DEVICE, AardvarkI2cFlags.AA_I2C_NO_STOP, 128, offset)


    result = AardvarkApi.aa_i2c_read(handle, I2C_DEVICE, AardvarkI2cFlags.AA_I2C_NO_FLAGS, 128, data)

    If result <= 0 Then
        sampletext.Text &= "i2c read error" & vbCrLf
    Else
        Dim i As Integer
        sampletext.Text &= "Read data bytes:"
        For i = 0 To 127
            k &= System.Convert.ToChar(data(i)).ToString
        Next
        sampletext.Text &= k
        sampletext.Text &= vbCrLf
    End If

    ' Close the device and exit
    AardvarkApi.aa_close(handle)
End Sub
End Module

具体处理“写”功能:

Call AardvarkApi.aa_i2c_write(handle, I2C_DEVICE, AardvarkI2cFlags.AA_I2C_NO_STOP, 128, offset)

...这是支持文件定义的内容:

Master Write(aa_i2c_write)

      int aa_i2c_write (Aardvark         aardvark,
                        aa_u16           slave_addr,
                        AardvarkI2cFlags flags,
                        aa_u16           num_bytes,
                        const aa_u08 *   data_out);

将字节流写入I2C从设备。 参数 Aardvark手柄的Aardvark适配器 slave_addr从中读取的slave 标记“注释”部分中描述的特殊操作 num_bytes要写入的字节数(最大65535) data_out指向数据的指针 回报价值 写入的字节数。

特定错误代码 AA_I2C_WRITE_ERROR读取Aardvark适配器的确认时出错。这很可能是通信错误的结果。 细节 对于普通的7位寻址,slave_addr的低7位应对应于从地址。最顶部的位被忽略。 Aardvark I2C子系统将在抓取总线后将地址与R / W位组合在一起。对于10位寻址,addr的低10位应对应于从地址。然后,Aardvark适配器将地址组装成适当的格式,如飞利浦规范中所述。如果使用10位寻址模式,则存在一个限制,即在单个事务中最多只能写入65534个字节。

slave_addr 0x00已在I2C协议规范中保留用于一般呼叫寻址。启用响应广播呼叫的I2C从设备将确认此地址。 Aardvark I2C主设备不会特别处理广播呼叫。如果需要具有通用调用的硬件地址编程功能,则此API的用户可以手动汇编第一个数据字节。

实际上可以向从器件写入0个字节。从站将被寻址,然后Aardvark适配器将立即发送停止条件。没有字节发送到从器件,因此忽略数据参数(即,它可以是0或指向无效的存储器)。

如果写入的字节数为零,则可能出现以下情况。

找不到请求的奴隶。 请求的从站在公交车上,但拒绝确认其地址。 由于存在另一个I2C主设备,Aardvark适配器无法占用总线。这里,仲裁在从属寻址阶段丢失,结果可能是不可预测的。 从机已被寻址,并且没有写入任何字节,因为num_bytes设置为0。 由于以下可能性,写入的字节数可能小于事务中请求的字节数。

由于存在另一个I2C主设备,Aardvark适配器在数据传输期间丢失了总线。 从机拒绝接收任何更多字节。


很明显我必须传递一个字节数组,但我不完全确定如何编码BIN文件以便它可以传递。在这个低级别有很多转换,我是多云...将事物转换为字符串,或字节,或字符等等。我已经玩了很多,他们知道在某些情况下,你最终得到了ASCII或十六进制等...但我不确定在这种情况下需要什么来使它工作。

为了使这更加简单,我希望将任何内容传递给EEPROM。无论我在这段代码中做了什么改变,我都无法得到任何写入EEPROM的内容。或许它确实如此,我只是没有看到它。运行此代码时,“读取”功能会生成输出“12345678910111213141516”。目前有128个字节的虚拟内容填充EEPROM,而1-16不在那里。

如果任何人能让我走上正轨,那将非常感激!!!!谢谢。

3 个答案:

答案 0 :(得分:0)

正确编程和读取EEPROM取决于EEPROM使用的协议以及在编程板上的物理配置。

很可能它使用了Aardvark docs here中讨论的Phillips协议。示例代码具有一些内置常量和假设。第一个假设是你的I2C网络工作在100KHz,EEPROM是从机,它位于地址0x54(代码样本Const I2C_DEVICE As UShort = &H54)。

寻址

I2C可以使用7位或10位器件(总线)寻址。最高有效位(MSB)用于识别设备类型。 EEPROMS具有器件类型1010(0x8)。这占用了高地址字节中的4个MSB。许多器件都有一个或多个引脚,用于控制它使用的I2C地址。例如,如果EEPROM是4K Atmel AT24C04C器件,其引脚A1为低电平(接地)且引脚A2拉高(+ Vcc),则使用(二进制)101010XY进行寻址。其中X = 0表示设备上的页面0,1表示页面1,Y = 1表示读取设备,Y = 0表示写入设备。该设备的地址如下:

  • 0xA8 = write page 0
  • 0xAC = write page 1
  • 0xA9 = read page 0
  • 0xAB = read page 1

我们关心的是芯片的地址线(A2和A1)与EEPROM内的地址空间(4Kbit EEPROM的0到512)相结合。不幸的是,由于R / _W位是总线地址字节的第0位,而页面位是总线地址字节的第1位。因此,从API的角度来看,EEPROM的地址空间不是连续的。因此物理总线地址始终是上述之一。当总线地址与另一个存储器地址字节组合时,它指定我们在I2C总线上的特定EEPROM中实际读取或写入的内容。

设备内存

如上所述,EEPROMS可以有不同的内存页面。页面大小是特定于设备的。 AT24C04C每页有8页16字节。在此示例中,页面内的地址由地址字节的4个LSB(最低有效位)指定。

读取数据

您可以一次读取一个字节(随机读取)或按顺序读取数据。 获取一个数据字节:

  1. 向设备写入您想要阅读的地址
  2. 从设备中读取字节
  3. 设备有一个内部地址计数器。如果要对多个字节进行顺序读取,只需继续从器件读取,它将继续在其存储器中发送下一个字节。大多数设备的地址计数器都会翻转,因此您必须小心不要求提供比设备实际拥有的数据更多的数据,否则可能会给您带来意想不到的结果。

    停止和开始信号

    在从I2C主设备到从设备的通信开始时,主设备通过在SCL(时钟)线为高电平时拉低SDA(串行数据A)线来控制总线。 (在正常数据传输期间,SDL在SCL为高电平时不得更改,但在SCL为低电平时可能会发生变化)。当SCL为高电平时,主机在SDA升高时发出控制信号。这会影响您编写代码的方式并指定读写标记。

    示例:读取前32个字节

    1. 写入地址0xA8:data = 0x00
    2. 从地址0xA9读取
    3. 重复步骤2(31次以上)
    4. 在代码中,这可能类似于:

      Const DEV0_READ__PAGE0 As Integer = &HA9
      Const DEV0_WRITE_PAGE0 As Integer = &HA8
      Dim startAddress() As Byte = New Byte() {0}
      Dim data() as Byte = new Byte(32)
      Dim writeResult As Integer = _
          AardvarkApi.aa_i2c_write( _
              handle, DEV0_WRITE_PAGE0, _
              AardvarkI2cFlags.AA_I2C_NO_STOP, 1, startAddress)
      Dim readResult As Integer = _
          AardvarkApi.aa_i2c_read( _
              handle, DEV0_READ__PAGE0,
              AardvarkI2cFlags.AA_I2C_NO_FLAGS, 32, data)
      If readResult <> 32 Then
          Console.WriteLine("Read Error {0} bytes requested, {1} bytes received", 32, readResult)
      Else
          For i As Integer = 0 to 31
              Console.Write(data(i).ToString() & ", ")
          Next
      End If
      

      您必须阅读EEPROM手册,以了解执行给定操作所涉及的读写顺序,以及如何指定器件的总线地址和EEPROM中的存储器地址。

答案 1 :(得分:0)

Nusbio设备可以更轻松地从C#或VB.NET读取/写入EEPROM。 查看他们的github样本

https://github.com/madeintheusb/Nusbio.Samples/tree/master/CS/MadeInTheUSB.Nusbio.SPI.EEPROM_25AA1024

https://github.com/madeintheusb/Nusbio.Samples/tree/master/CS/MadeInTheUSB.Nusbio.I2C.EEPROM_24LC256

using (var nusbio = new Nusbio(serialNumber))
{
var _eeprom = new EEPROM_25AA1024(
nusbio: nusbio, clockPin: NusbioGpio.Gpio0,mosiPin: NusbioGpio.Gpio1,
misoPin: NusbioGpio.Gpio2, selectPin: NusbioGpio.Gpio3
);
byte[] buf;

var r = _eeprom.ReadPage(p * _eeprom.PAGE_SIZE, _eeprom.PAGE_SIZE);
if (r.Succeeded)
{
    buf = r.Buffer;
}

}

答案 2 :(得分:0)

您可以编写一个脚本,在写入每个象限后增加设备地址,即 64KB。在您的情况下,0x54 将增加到 0x55,依此类推。根据 EEPROM 的总大小计算象限数。然而,每个象限的字节地址都是相同的,即 0x0000 到 0xFFFF