在没有深入到项目背景的情况下,我们通过使用一些非常有创意的编码,从一些标准文本字段创建了一个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不在那里。
如果任何人能让我走上正轨,那将非常感激!!!!谢谢。
答案 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(最低有效位)指定。
您可以一次读取一个字节(随机读取)或按顺序读取数据。 获取一个数据字节:
设备有一个内部地址计数器。如果要对多个字节进行顺序读取,只需继续从器件读取,它将继续在其存储器中发送下一个字节。大多数设备的地址计数器都会翻转,因此您必须小心不要求提供比设备实际拥有的数据更多的数据,否则可能会给您带来意想不到的结果。
在从I2C主设备到从设备的通信开始时,主设备通过在SCL(时钟)线为高电平时拉低SDA(串行数据A)线来控制总线。 (在正常数据传输期间,SDL在SCL为高电平时不得更改,但在SCL为低电平时可能会发生变化)。当SCL为高电平时,主机在SDA升高时发出控制信号。这会影响您编写代码的方式并指定读写标记。
在代码中,这可能类似于:
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.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