USB小白学习之路(6) IIC EEPROM读取解析
IIC EEPROM读取解析
1. 编译错误处理(这里可以忽略)
在解压包解压了程序后,直接编译,出现如下错误。
*** WARNING L14: INCOMPATIBLE MEMORY MODEL
MODULE: .\EZUSB.LIB (RESUME)
MODEL: SMALL
*** WARNING L14: INCOMPATIBLE MEMORY MODEL
MODULE: .\EZUSB.LIB (DISCON)
MODEL: SMALL
*** WARNING L14: INCOMPATIBLE MEMORY MODEL
MODULE: .\EZUSB.LIB (EZREGS)
MODEL: SMALL
*** WARNING L14: INCOMPATIBLE MEMORY MODEL
MODULE: .\EZUSB.LIB (GET_STRD)
MODEL: SMALL
*** ERROR L102: EXTERNAL ATTRIBUTE MISMATCH
SYMBOL: PSTRINGDSCR
MODULE: .\EZUSB.LIB (GET_STRD)
*** WARNING L14: INCOMPATIBLE MEMORY MODEL
MODULE: .\EZUSB.LIB (DELAY)
MODEL: SMALL
*** ERROR L107: ADDRESS SPACE OVERFLOW
SPACE: CODE
SEGMENT: ?C_INITSEG
LENGTH: 16BFH
*** ERROR L107: ADDRESS SPACE OVERFLOW
SPACE: CODE
SEGMENT: ?C_INITSEG
LENGTH: 16BFH
*** ERROR L120: CONTENT BELONGS TO ERRONEOUS SEGMENT
SEGMENT: ?C_INITSEG
MODULE: periph.obj (PERIPH)
*** ERROR L118: REFERENCE MADE TO ERRONEOUS EXTERNAL
SYMBOL: PSTRINGDSCR
MODULE: .\EZUSB.LIB (GET_STRD)
ADDRESS: 0B27H
*** ERROR L118: REFERENCE MADE TO ERRONEOUS EXTERNAL
SYMBOL: PSTRINGDSCR
MODULE: .\EZUSB.LIB (GET_STRD)
ADDRESS: 0B29H
*** ERROR L120: CONTENT BELONGS TO ERRONEOUS SEGMENT
SEGMENT: ?C_INITSEG
MODULE: firmware.obj (FIRMWARE)
*** ERROR L119: REFERENCE MADE TO ERRONEOUS SEGMENT
SEGMENT: ?C_C51STARTUP
MODULE: E:\SOFTWAREINSTALL\PROJECT\KEIL_FOR_51\C51\LIB\C51L.LIB (?C_INIT)
ADDRESS: 0838H
*** ERROR L120: CONTENT BELONGS TO ERRONEOUS SEGMENT
SEGMENT: ?C_INITSEG
MODULE: E:\SOFTWAREINSTALL\PROJECT\KEIL_FOR_51\C51\LIB\C51L.LIB (?C_INIT)
面对错误,首先是百度了下,甚至还翻墙google,好多说是keil为不完全版本,只能编译2kB的程序,超出会报错overflow,给出的方案是
方案一:下载完整版keil,重装试一下。
方案二:对图 1中的箭头位置进行修改,在这里看出,方案一不适用。

图 1 修改配置
按照方案二试着修改(各种实验修改)配置后,warming消除了,但是对error没有什么卵用。后来发现图 2中所示的Device没有选对。

图 2 选择设备
修改图 2中的设备,选为CY7C68013×××-×后,还要在图 2中的可选项Use Extended Linker(LX51) instead of BL51选中,这样就可以编译通过了。
但是吧,这个虽然编译通过了,但是程序好像是错误的。因为通过0xED vendor command进行读取EEPROM的数据时,提示错误!
我之前用的是历程中已经解压的程序,后来讲例程中的压缩包程序解压后,编译直接通过,上面两处错误(设备和选项)没有改,下进了CY7C68013A中后,通过0xED vendor command进行读取EEPROM时,会有数据返回,虽然返回的不是预期的,再查证。
2. 程序解析
首先初始化:TD_init();
然后是设备描述符的相关处理;
接着是循环执行:TD_Poll()函数,在这个函数里,往IIC接口的EEPROM里面写入数据(写入是一次写一个),同时在EEPOM里面读出数据(读出是一次将写入的3个同时读出),并存入到寄存器中。
在循环函数中,检测控制传输令牌包的到来,一旦接收到令牌包,就会将存放IIC读书数据的寄存器中的数传到主机。
3. 运行错误处理
这个程序可以直接用。并且将1错误处理中的device改为CY7C68013和option选上了。
其实PDF(CE63180)文档里面已经写得非常详细。
就是在上电之前,将EEPROM的跳线帽拔下来,不让他在EEPROM中启动,这样PC才可以识别到设备,上电后,下载程序前将跳线帽插上,这样在下载了程序后,会自动的往EEPROM中写数据。
在PC的上位机软件中做如图 3配置,点击Vend Req按钮,即可读取程序自动写入EEPROM中的数据。但是不知道是没有写入,还是读取不成功,返回来的数据都是00,00,00 ,显然,这是不正确的。经过示波器测试IIC的数字信号,发现发出的都是10100000。再结合IIC的通信协议,发现这是发送的IIC 芯片的地址。读出来的数据时00,00,00是因为程序是按照官方的开发板写的,但是淘宝的开发板和官方的有点区别。图 3和图 4对比所示。由两个不同IC(24LC00和24L128)的datasheet可以看出,他们IIC地址的前4为均为1010,后面三位由电平决定。图 3中A2,A1,A0均为0,所以地址为1010_0000(0xA0)。而淘宝开发板的A0被拉高,所以地址为1010_0010(0xA2)。因为用的是淘宝的开发板,所以这里要修改。
在程序中Periph.c文件中有一个宏定义:#define EEPROM_ADDR 0x50,这个宏在TD_init()函数中赋值给了IIC地址:I2C_Addr = EEPROM_ADDR;
因为在写地址时,先把地址左移一位(I2DAT = I2C_Addr << 1),所以这里的宏定义为地址的右移一位值:0x50 = 0xA0 >> 1。
由于使用了淘宝货,这里没有改的话,就不能往EEPROM中写入数据,也不能读取,所以返回来的是00,00,00,如图 5。这里要在程序中将宏的值改为EEPROM地址的右移一位值:0x51 = 0xA2 >> 1。

图 3 官方开发板原理图

图 4 淘宝开发板原理图

图 5 上位机的配置
进行了如上修改之后,再次烧录,读取。发现读出来的数据不正确如图 6所示,用示波器测试,发现现在不只是发送0xA0那么简单了,具体是什么也没有细究。
接下来继续看程序。在图 7所示的TD_init()中的注释引起了注意,DB_Addr = 1 if the EEPROM is double byte addressing(双字节寻址)

图 6 修改地址后的读取值

图 7 TD_init()函数
将TD_init()中的DB_Addr = 0改为DB_Addr = 1后,下载读取,可以实现将TD_Poll()中写入EEPROM中的数据读出来并返回到host。如图 8所示

图 8 读取正确数据
通过此实验可以证明,开发板上用的ATMEL的24C128 EEPROM是双字节寻址。下了数据手册,看数据手册,在第7页的Device addressing中,如图 9所示,但是这里的8bit是device addressing,是IIC的地址,不是我们写入和读取的存储空间的地址。所以不是看这里。

图 9 datasheet 的描述
接着往下看,在第8页和第9页中,写入时序和读取时序分别如图 10和图 11所示,可以明确看出,前面方框中的device address与上面的描述对应,椭圆中的word address分为了1st,2nd两个字节byte,为double byte addressing(双字节寻址),可以与24LC00 datasheet中的时序图作对比,发现它是单字节寻址,因此官方例程中的DB_Addr = 0。完美解决。睡
图 10 写入时序

图 11 读取时序
此问题的解决,也是通过翻墙,在google搜索中,搜到的别人的答案。连接为:https://www.raspberrypi.org/forums/viewtopic.php?f=44&t=17590
在连接中有启发的回答为图 12所示

图 12 有启示的回答
USB小白学习之路(6) IIC EEPROM读取解析的更多相关文章
- USB小白学习之路(10) CY7C68013A Slave FIFO模式下的标志位(转)
转自良子:http://www.eefocus.com/liangziusb/blog/12-11/288618_bdaf9.html CY7C68013含有4个大端点,可以用来处理数据量较大的传输, ...
- USB小白学习之路(11) Cy7c68013A驱动电路设计注意事项(转)
Cy7c68013A驱动电路设计注意事项 转自:http://group.chinaaet.com/116/79029#0-tsina-1-71467-397232819ff9a47a7b7e80a4 ...
- USB小白学习之路(8)FX2LP cy7c68013A——Slave FIFO 与FPGA通信(转)
此博客转自CSDN:http://blog.csdn.net/xx116213/article/details/50535682 这个博客只对自己理解CY7C68013的配置有一定的帮助,对于配置CY ...
- USB小白学习之路(5) HID鼠标程序
HID鼠标程序 1. 特别注意 需要特别注意,各个例程中的设备描述符,配置描述符等各种描述符都是已经配置好了的,我们需要做的只是在例程中将代码修改为自己需要的部分即可,一般情况下是不可以串搭配的. 2 ...
- USB小白学习之路(4)HID键盘程序
HID键盘程序 1. 特别注意 需要特别注意,各个例程中的设备描述符,配置描述符等各种描述符都是已经配置好了的,我们需要做的只是在例程中将代码修改为自己需要的部分即可,一般情况下是不可以串搭配的. 2 ...
- USB小白学习之路(3) 通过自定义请求存取外部RAM
通过自定义请求存取外部RAM 1. 实验简述 此实验是对自定义的供应商特殊命令(vendor specific command bRequest = 0xA3)进行解析,程序中的read me说明如下 ...
- USB小白学习之路(2)端点IN/OUT互换
端点2(out)和端点6(in)的out_in互换 注:这里的out和in都是以host为标准说的,out是host的out,在设备(Cy7c68013)这里其实是输入端口:in是host的in,在设 ...
- USB小白学习之路(1) Cypress固件架构解析
Cypress固件架构彻底解析及USB枚举 1. RAM的区别 56pin或者100pin的cy7c68013A,只有内部RAM,不支持外部RAM 128pin的cy7c68013A在pin脚EA=0 ...
- USB小白学习之路(12) Cy7c68013A固件之Slave FIFO(转)
Cy7c68013固件之Slave FIFO 转自:http://blog.csdn.net/zengshaoqing/article/details/53053539 选择SlaveFIFO传输方式 ...
随机推荐
- RDD(二)——创建
RDD的创建 1)从内存中创建 从集合中创建RDD,Spark主要提供了两种函数:parallelize和makeRDD val raw: RDD[Int] = sc.parallelize(1 to ...
- TPO4-2 Cave Art in Europe
Perhaps, like many contemporary peoples, Upper Paleolithic men and women believed that the drawing o ...
- 887A. Div. 64#模特的数学技巧(字符串处理)
问题出处:http://codeforces.com/problemset/problem/887/A 问题大意:对于给出的一串二进制数,能否通过去掉一些数字,使之成为十进制下64的倍数 #inclu ...
- bzoj1396识别子串(SAM+线段树)
复习SAM板子啦!考前刷水有益身心健康当然这不是板子题/水题…… 很容易发现只在i位置出现的串一定是个前缀串.那么对答案的贡献分成两部分:一部分是len[x]-fa~len[x]的这部分贡献会是r-l ...
- [HNOI2019]JOJO(KMP自动机+主席树)
一道神仙题,考察选手对KMP的深入理解. 先考虑没有2操作的做法.设每一段为一个二元组(x,c),考虑一段前缀匹配后缀,除了第一段的字符,其他段的二元组(x,c)必须相等,所以可以将其视为特殊字符进行 ...
- 我的 xelatex 模板
\documentclass[twoside,11pt]{article} \usepackage{amsmath,amsfonts} \usepackage{hyperref} \usepackag ...
- 吴裕雄--天生自然 JAVA开发学习: 泛型
public class GenericMethodTest { // 泛型方法 printArray public static < E > void printArray( E[] i ...
- 5-7 学生cpp成绩统计
完成“学生cpp成绩计算”之后,修改Person和Student类,各自增加两个无参构造函数. 仍以Person类为基础,建立一个派生类Teacher,增加以下成员数据: int ID;//教师工号 ...
- java第二节课 java语法基础动手动脑
动手动脑1:枚举变量 运行EnumTest.java package test2; public class EnumTest { public static void main(String[ ...
- python学习笔记(5)数据类型-字典
字典是另一种可变容器模型,且可存储任意类型对象. 字典的每个键值 key=>value 对用冒号 : 分割,每个键值对之间用逗号 , 分割,整个字典包括在花括号 {} 中 ,格式如下所示: d ...
