IIC通信控制的AD5259------在调试过程中遇到的奇葩问题
首先说一下的遇到的问题:
1.AD5259按照SCL是100KHz的情况下,可以正常接收上位机的数据,但是一段时间后,就不能正确的按照时序来走了
原因在于AD5259在接收到上位机的数据后需要一定的响应时间,而在这个响应时间内,scl和sda都不应该有任何的活动,否则会导致不能准确接收下一个数据的开始信号,但要特别注意的是,这段时间内的SCL以及SDA的设置也是有一个说法的。
2.断电后可以保持在正常工作的条件下。
断电相当于是一个复位的过程,也就是说,复位后可以正常工作~
3.网上找到的完整的IIC分析
IIC协议
IIC协议是一种多机通讯,由SDA数据线和SCL时钟线构成串行总线,所有的IIC设备都可以挂载到总线上,但每个设备都有唯一的设备读地址和设备写地址。在使用IIC作为数字接口的芯片datasheet中都可以看到该设备的设备读/写地址情况,并可以查找到相应的读写时序,以及对速率的要求。下图是一个通用的IIC协议时序:

我们可以总结出五种IIC协议的时序状态:
1. 空闲状态,当SDA和SCL两条信号线都处于高电平时总线处于空闲状态。
2. 开始信号,SCL为高电平期间SDA信号线上产生了下降沿标志着的一次数据传输的开始。开始信号应当由主机发起。
3. 数据传输,在SCL同步控制下SDA串行的传送每一位,因此传送8bits的数据需要8个SCL时钟。SCL为高电平时期SDA电平状态必须稳定;SCL为低电平期间才允许SDA改变状态。
4. 应答信号,IIC总线上每传送一个8位字节,第9个脉冲期间便会释放总线,由接收器发出一个应答信号,反馈有没有成功接收。
5. 停止信号,在SCL保持高电平期间,将SDA信号线释放恢复到高电平,标志一次数据传输的结束,IIC总线也重新回到了空闲状态。
计数器控制IIC读写
在“FPGA基础设计(三):UART串口通信”中已经接触到了使用计数器控制时序的方法,这个方法在控制IIC通信时同样实用。一次完整的写入操作如下所示:
case( i )
0: // iic Start
begin
isOut <= 1; //SDA端口输出
if( C1 == 0 ) rSCL <= 1'b1;
else if( C1 == 200 ) rSCL <= 1'b0; //SCL由高变低
if( C1 == 0 ) rSDA <= 1'b1;
else if( C1 == 100 ) rSDA <= 1'b0; //SDA先由高变低
if( C1 == 250 -1) begin C1 <= 9'd0; i <= i + 1'b1; end
else C1 <= C1 + 1'b1;
end
1: // Write Device Addr
begin rData <= {4'b1010, 3'b000, 1'b0}; i <= 5'd7; Go <= i + 1'b1; end
2: // Wirte Word Addr
begin rData <= Addr_Sig; i <= 5'd7; Go <= i + 1'b1; end
3: // Write Data
begin rData <= WrData; i <= 5'd7; Go <= i + 1'b1; end
4: //iic Stop
begin
isOut <= 1'b1;
if( C1 == 0 ) rSCL <= 1'b0;
else if( C1 == 50 ) rSCL <= 1'b1; //SCL先由低变高
if( C1 == 0 ) rSDA <= 1'b0;
else if( C1 == 150 ) rSDA <= 1'b1; //SDA由低变高
if( C1 == 250 -1 ) begin C1 <= 9'd0; i <= i + 1'b1; end
else C1 <= C1 + 1'b1;
end
5:
begin isDone <= 1'b1; i <= i + 1'b1; end //写I2C 结束
6:
begin isDone <= 1'b0; i <= 5'd0; end
7,8,9,10,11,12,13,14: //发送Device Addr/Word Addr/Write Data
begin
isOut <= 1'b1;
rSDA <= rData[14-i]; //高位先发送
if( C1 == 0 ) rSCL <= 1'b0;
else if( C1 == 50 ) rSCL <= 1'b1;
else if( C1 == 150 ) rSCL <= 1'b0;
if( C1 == F250K -1 ) begin C1 <= 9'd0; i <= i + 1'b1; end
else C1 <= C1 + 1'b1;
end
15: // waiting for acknowledge
begin
isOut <= 1'b0; //SDA端口改为输入
if( C1 == 100 ) isAck <= SDA;
if( C1 == 0 ) rSCL <= 1'b0;
else if( C1 == 50 ) rSCL <= 1'b1;
else if( C1 == 150 ) rSCL <= 1'b0;
if( C1 == F250K -1 ) begin C1 <= 9'd0; i <= i + 1'b1; end
else C1 <= C1 + 1'b1;
end
16:
if( isAck != 0 ) i <= 5'd0;
else i <= Go;
endcase
向IIC总线写数据时,需要依次写入待写入的设备写地址、设备中的写地址和待写入的数据共3个8bits字节数据。i代表总线上不同的状态,通过计数器来控制状态之间的跳转。i为0时发出开始信号;i为7~14时控制8bits数据的发送;i为1、2、3时分别为设备地址、字节地址和数据,依次调用7-14完成数据的传输;其余还有停止位、应答位、IIC通信完成置位等状态。
从器件中读取数据的方法与此一样,只不过通常都需要先向IIC总线写入待读取的设备地址和器件地址,之后再读数据。读数据整体过程比写数据要麻烦一点,但只要控制好状态之间跳转的过程即可。
分频时钟控制IIC读写
由计数器控制通信时序的方法优点是很灵活,几乎所有的时序方法都可以用这种方法完成;缺点就是太麻烦,需要控制好状态之间的跳转,时序越复杂使用越麻烦,其实在“FPGA采集-传输-显示系统(二):基于FPGA的温度采集和以太网传输”中,我对DS18B20的时序控制就是采用计数器控制的方法。DS18B20的时序要求较多,因此其中的状态跳转已经相当复杂。
其实在控制IIC这种时钟速率固定的串行协议时,还可以在外部分频或PLL生成一个低频的通信时钟,用这个时钟来控制数据传输过程。如下所示:
always@(posedge clock_i2c)
begin
if(reset_n==1'b0) begin
tr_end<=0;
ack1<=1;
ack2<=1;
ack3<=1;
sclk<=1;
reg_sdat<=1;
end
else
case(cyc_count)
begin ack1<=1;ack2<=1;tr_end<=0;sclk<=1;reg_sdat<=1;end
reg_sdat<=0; //开始传输
sclk<=0;
reg_sdat<=i2c_data[23];
reg_sdat<=i2c_data[22];
reg_sdat<=i2c_data[21];
reg_sdat<=i2c_data[20];
reg_sdat<=i2c_data[19];
reg_sdat<=i2c_data[18];
reg_sdat<=i2c_data[17];
reg_sdat<=i2c_data[16];
reg_sdat<=1; //应答信号
begin reg_sdat<=i2c_data[15];ack1<=i2c_sdat;end
reg_sdat<=i2c_data[14];
reg_sdat<=i2c_data[13];
reg_sdat<=i2c_data[12];
reg_sdat<=i2c_data[11];
reg_sdat<=i2c_data[10];
reg_sdat<=i2c_data[9];
reg_sdat<=i2c_data[8];
reg_sdat<=1; //应答信号
begin reg_sdat<=i2c_data[7];ack2<=i2c_sdat;end
reg_sdat<=i2c_data[6];
reg_sdat<=i2c_data[5];
reg_sdat<=i2c_data[4];
reg_sdat<=i2c_data[3];
reg_sdat<=i2c_data[2];
reg_sdat<=i2c_data[1];
reg_sdat<=i2c_data[0];
reg_sdat<=1; //应答信号
begin ack3<=i2c_sdat;sclk<=0;reg_sdat<=0;end
sclk<=1;
begin reg_sdat<=1;tr_end<=1;end //IIC传输结束
endcase
IIC通信控制的AD5259------在调试过程中遇到的奇葩问题的更多相关文章
- 关于火狐浏览器在开发调试过程中,出现javascript:void(0)的状态
关于火狐浏览器在开发调试过程中,出现javascript:void(0)的状态 由于火狐浏览器没有安装 Adobe Flash Player 19 NPAPI这个插件 安装好了之后就可以直接运行了
- Android APP 调试过程中遇到的问题。
调试过过程中APP安装完启动后有的时候会异常退出,报这个错误.有的时候可以直接启动.查找不到原因.网上说把commit方法替换成commitAllowingStateLoss() 也无效. Andro ...
- 调试过程中发现按f5无法走进jdk源码
debug 模式 ,在fis=new FileInputStream(file); 行打断点 调试过程中发现按f5无法走进jdk源码 package com.lzl.spring.test; impo ...
- VS·调试过程中某个操作导致调试突然退出之解决方案
阅文时长 | 0.11分钟 字数统计 | 232字符 主要内容 | 1.引言&背景 2.声明与参考资料 『VS·调试过程中某个操作导致调试突然退出之解决方案』 编写人 | SCscHero 编 ...
- C语言调试过程中duplicate symbol错误分析
说明:在我们调试C语言的过程中,经常会遇到duplicate symbol错误(在Mac平台下利用Xcode集成开发环境).如下图: 一.简单分析一下C语言程序的开发步骤. 由上图我们可以看出C语言由 ...
- 【转】MFC中调试过程中查看输出信息 -- 不错
原文网址:http://blog.sina.com.cn/s/blog_4e24d9c501014o39.html 笔记&&方便查阅. ~~~~~~~~~~~~~~~~~~~~~~~~ ...
- Android Studio 调试过程中快捷查看断点处变量值(Ctrl+Shift+I无效)?
当你在做Keymap到Eclipse后,在debug过程中,在Eclipse中我们很喜欢用Ctrl+Shift+I去查看一个运算或者调用的结果,这样用起来很方便.但是keymap到Eclipse后,你 ...
- [ISE调试] 在ISE调试过程中,遇到过的warning以及消除办法
1.在generate的过程中,在Map环节遇到了下面这个warning 意思:告诉你是黑盒子,而且他本来在设计里面就是黑盒子. 解决办法:点击图中的,会弹出一个代码文件,是声明这个IP核的文件,代码 ...
- 代码调试过程中easy遇到的问题
前两天身体有些不舒服,也没写啥新文章,昨天下了一天的雨.今天阳光明媚,空气也非常新奇.心情大好. 继翻译为什么输出是String而不是Object,今天先写一下调试方面的东西.java中自带的函数调试 ...
随机推荐
- [极客大挑战 2019]Secret File
0x00知识点 没有过滤file 使用php的file伪协议去读取文件 ?file=php://filter/convert.base64-encode/resource=flag.php 0x01解 ...
- 3.react 基础 - JSX 语法
1.最基础的 JSX 语法 普通javaScript中 引入 标签 let html = '<h1>hello</h1>'; jsx语法 let JSX_html = < ...
- 【WPF学习】第三十七章 触发器
WPF中有个主题,就是以声明方式扩展代码的功能.当使用样式.资源或数据绑定时,将发现即使不使用代码,也能完成不少工作. 触发器是另一个实现这种功能的例子.使用触发器,可自动完成简单的样式改变,而这通常 ...
- Java8之深入理解Lambda
lambda表达式实战 从例子引出lambda 传递Runnable创建Thread java8之前 Thread thread=new Thread(new Runnable() { @Overri ...
- 理解自动梯度计算autograd
理解自动求导 例子 def f(x): a = x * x b = x * a c = a + b return c 基于图理解 代码实现 def df(x): # forward pass a = ...
- Python中列表的copy方法
1.在列表中存在一个名为copy的方法,就像字面意思一样copy方法是用于复制列表元素的,示例如下: names = [‘Zhangsan’,’Lisi’,’WangErgou’] names2 = ...
- java读取本地json数组并解析
1.本地json位置 2,json数据 {"garbages":[{"id":"/m/011k07","ename":& ...
- C++对象的动态建立与释放
new运算符动态分配堆内存 (从堆分配一块“类型”大小的存储空间,并且返回首地址) 1.写程序的时候,经常需要动态的分配和撤销内存空间,C语言中常常是利用库函数 malloc 和 free 来分配和 ...
- StartDT AI Lab | 需求预测引擎如何助力线下零售业降本增效?
在当下经济明显进入存量博弈的阶段,大到各经济体,小到企业,粗放的增长模式已不适宜持续,以往高增长的时代已经成为过去,亟需通过变革发掘新的增长点.对于竞争激烈的线下零售行业而言,则更需如此. 零售行业一 ...
- 使用spark
更新说明 免密码登录 for f in `cat ~/machines`; do scp .ssh/id_dsa.pub $f:~/ ssh $f "cat id_dsa.pub >& ...