2

在不深入了解项目背景的情况下,我们通过使用一些非常有创意的编码,从一些标准文本字段创建了一个 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)

...这是支持文档的定义:

主写入 (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 要从中读取的从站标志特殊操作,如“注释”部分所述 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。

如果有人能让我走上正确的轨道,将不胜感激!!!!谢谢你。

4

3 回答 3

0

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

它最有可能使用此处Aardvark 文档中讨论的 Phillips 协议。示例代码有一些内置的常量和假设。第一个假设是您的 I2C 网络以 100KHz 工作,EEPROM 是从机,它位于地址 0x54(Const I2C_DEVICE As UShort = &H54来自代码示例)。

寻址

I2C 可以使用 7 位或 10 位设备(总线)寻址。的最高有效位 (MSB) 用于识别设备类型。EEPROM 的设备类型为 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. 从设备读取字节

该设备有一个内部地址计数器。如果您想连续读取多个字节,只需继续从设备读取,它将继续发送其内存中的下一个字节。大多数设备的地址计数器都会翻转,因此您必须小心不要要求比设备实际拥有的数据更多的数据,否则可能会给您带来意想不到的结果。

停止和启动信号

在从 I2C 主机到从机的通信开始时,主机通过将 SDA(串行数据 A)线拉低而 SCL(时钟)线拉高来断言对总线的控制。(在正常的数据传输过程中,SDA 不能在 SCL 为高电平时改变,但可以在 SCL 为低电平时改变)。主机在 SCL 为高电平时升高 SDA 时发出控制结束信号。这对您如何编写代码和指定读写标志有影响。

示例:读取前 32 个字节

  1. 写入地址 0xA8:data=0x00
  2. 从地址 0xA9 读取
  3. 重复第 2 步(再重复 31 次)

在代码中,这可能类似于:

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 中的内存地址。

于 2015-04-08T06:06:27.757 回答
0

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

于 2021-02-26T05:37:50.000 回答
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;
}

}

于 2016-12-10T01:29:54.830 回答