[STM32]怎么根据时序参数确定IIC的延时啊

[STM32]怎么根据时序参数确定IIC的延时啊

[STM32]

怎么根据时序参数确定IIC的延时啊

[复制链接]

电梯直达

楼主

楼主|

c834706901

发表于 2018-11-18 23:04

|

只看该作者

|倒序浏览

|阅读模式

iic, 时序, ic, 读写

各位,我想知道怎么根据这些时序参数来确定IIC启动或者读写数据的时候延时多少啊,我看网上很多程序都是4us这个不适用吧

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?注册

×

回复

举报

相关帖子

• 【APM32E030R Micro-EVB开发板评测】+ 使用定时器

• 小朋友高铁上被发试卷一秒静音

• Microchip的调试器都支持哪些开发环境呢

• MPLAB PICkit Basic 调试器

• Microchip哪款更适合做服务器芯片

• PIC16LF1566/1567数据手册

• PIC16F570数据手册

• PIC16F527数据手册

• PIC16F15213/14/23/24/43/44数据手册

• PIC16F18056/76介绍

沙发

楼主|

c834706901

发表于 2018-11-18 23:17

|

只看该作者

有人教教我吗,教会我50元红包 加Q直接发

回复

举报

板凳

ayb_ice

发表于 2018-11-19 08:40

|

只看该作者

最简单的方法,高低电平各延时2US,读取数据时延时1US

回复

举报

地板

楼主|

c834706901

发表于 2018-11-19 10:45

来自手机

|

只看该作者

ayb_ice 发表于 2018-11-19 08:40

最简单的方法,高低电平各延时2US,读取数据时延时1US

你是怎么判断延时这么长时间的呢

回复

举报

5楼

ayb_ice

发表于 2018-11-19 11:39

|

只看该作者

c834706901 发表于 2018-11-19 10:45

你是怎么判断延时这么长时间的呢

上面不是写的

SCL高电平时间吗,最小0.6,可以大于这个时间,不可以小于这个时间,所以2US是合适的。。。

回复

举报

6楼

ningling_21

发表于 2018-11-19 11:54

|

只看该作者

c834706901 发表于 2018-11-18 23:17

有人教教我吗,教会我50元红包 加Q直接发

不能小于0.6US,可以大于

回复

举报

7楼

楼主|

c834706901

发表于 2018-11-19 12:15

来自手机

|

只看该作者

ayb_ice 发表于 2018-11-19 11:39

上面不是写的

SCL高电平时间吗,最小0.6,可以大于这个时间,不可以小于这个时间,所以2US是合适的。。。 ...

下面的sda保持时间和有效时间是什么意思是,有什么作用吗

回复

举报

8楼

ningling_21

发表于 2018-11-19 13:35

|

只看该作者

本帖最后由 ningling_21 于 2018-11-19 13:36 编辑

c834706901 发表于 2018-11-19 12:15

下面的sda保持时间和有效时间是什么意思是,有什么作用吗

保持时间:MCU输出数据到SDA线,并要维持该数据电平的时间长度有效时间:MCU输出的数据电平,能被外部器件识别到的时间长度,不在这个时间范围内可能识别不了

回复

举报

9楼

雪山飞狐D

发表于 2018-11-19 16:55

|

只看该作者

c834706901 发表于 2018-11-19 10:45

你是怎么判断延时这么长时间的呢

I2C 大部分器件是SCL 100K ,小部分高速是400K,为了通用,SCL频率要小于100K即可

回复

举报

10楼

雪山飞狐D

发表于 2018-11-19 17:02

|

只看该作者

本帖最后由 雪山飞狐D 于 2018-11-19 17:46 编辑

c834706901 发表于 2018-11-19 12:15

下面的sda保持时间和有效时间是什么意思是,有什么作用吗

SDA的保持时间是指I2C时钟进入到0电位时,MUC上数据SDA保持上一次的逻辑电平不改变的时间,以便I2C器件进行数据采样输入有一个稳定性

回复

举报

11楼

雪山飞狐D

发表于 2018-11-19 17:11

|

只看该作者

本帖最后由 雪山飞狐D 于 2018-11-19 17:14 编辑

c834706901 发表于 2018-11-19 12:15

下面的sda保持时间和有效时间是什么意思是,有什么作用吗

SDA 有效时间是指,当SLC时钟跳变成0电平时,I2C器件会在这个有效时间内进行逻辑电平跳变,输出下一个数据,你的数据手册上描述对象应该是指I2C本身器件的特性,按照这个特性给单片机适量的延迟就可以了,12周期的51单片机可能都不需要延迟,本身指令周期都是1uS 了,最好买个USB逻辑分析仪,边写边对着时序就容易调通了

回复

举报

12楼

玄德

发表于 2018-11-20 21:18

|

只看该作者

启动或者读写数据的时候延时多少

这句话是什么意思? 你究竟想知道什么参数?

回复

举报

13楼

Prry

发表于 2018-11-21 00:26

|

只看该作者

将时序抽象出来,方便移植。一般i2c器件都是标准400K,用100K基本通用所有器件。

参考:

https://blog.csdn.net/qq_20553613/article/details/78878211

回复

举报

14楼

qinlu123

发表于 2018-11-21 10:17

|

只看该作者

让IIC一直发用示波器看着SCL和SDA调就行了,计算+实验。

回复

举报

15楼

楼主|

c834706901

发表于 2018-11-23 09:07

|

只看该作者

玄德 发表于 2018-11-20 21:18

启动或者读写数据的时候延时多少

这句话是什么意思? 你究竟想知道什么参数?

我就是想知道delay(4) delay(2)这些延时是怎么得出来的

回复

举报

16楼

玄德

发表于 2018-11-23 14:33

|

只看该作者

一定要先搞明白:

这个时间是芯片自己的行为,还是芯片对你的要求。这很重要。

比如 tsu 这个参数,它是 对“Data In”的规定,所以是对外界、对工程师的要求,

你操作芯片时必须满足这个要求,芯片才能正常接受你的数据。

最小值是 100ns ,意思是:

你在发出 SCL 的上升沿之前,必须把数据的值提前放在 SDA 线上,而且至少提前 100ns;

芯片只关心最小值,所以没有给出最大值,你提前比如 200ns、300ns、1000ns 甚至 1 秒都可以。自己看情况,选个合适的数。

比如 tvd:

这是芯片自身的行为, SCL 的下降沿是“你”提供的,芯片将在这个时间里,把内部数据放在 SDA 线上;

在这个时间内,芯片不能保证 SDA 的数据是正确的;

所以,工程师要在这个时间以后再读取 SDA 的数值。

按说,这个值只会给出最大值。很显然,只有最大值才有意义。

回复

举报

17楼

雪山飞狐D

发表于 2018-11-24 12:30

|

只看该作者

c834706901 发表于 2018-11-23 09:07

我就是想知道delay(4) delay(2)这些延时是怎么得出来的

图片是24CXX的中文数据手册,可以看到,只有电压在5V时,24C系列才能达到400K的时钟速率,2.5V 左右的速率只有100K,IO模拟的时序只有按照100K的速率去写,才能保证兼容,而这个I2C的程序模块可以兼容400K的器件,所以才会出现delay4 us......

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?注册

×

回复

举报

18楼

雪山飞狐D

发表于 2018-11-25 19:45

|

只看该作者

本帖最后由 雪山飞狐D 于 2018-11-26 01:34 编辑

复制#include "stc15f2k60s2.h"

#include

#include "Delay.h"

#include "I2C.h"

void Start_I2c(void);

void Stop_I2c(void);

unsigned char I2c_wait_ack(void);

void Ack_I2c(void);

void Nack_I2c(void);

void SendByte(unsigned char );

unsigned char RcvByte();

//起动总线函数

//Start_I2c();

//功能:启动I2C总线,即发送I2C起始条件.

void Start_I2c()

{

SCL=1;

Delay5us(); //tSU:STA

SDA=0; //发送起始信号

Delay5us(); //tHD:STA

SCL=0; //条件保持SCL处于0状态才能进行写入

}

//结束总线函数

//Stop_I2c();

//功能:结束I2C总线,即发送I2C结束条件.

void Stop_I2c()

{

SCL=0;

SDA=0;

Delay5us(); //tSU:STO

SCL=1; //结束条件建立时间大于4μs

Delay5us(); //tBUF总线空闲时间大于4.7us

SDA=1; //发送I2C总线结束信号

}

//等待应答信号到来

//返回值:1,接收应答失败

// 0,接收应答成功

u8 I2c_wait_ack(void)

{

u8 Time=0;

SCL=0;

SDA=1; //准备接收应答位

Delay5us(); //tAA tLOW

SCL=1;

Delay5us(); //tHIGH

while(SDA)

{

Time++;

if(Time>250)

{

Stop_I2c();

return 1; //超时检测无应答返回1

}

}

SCL=0; //时钟输出0

return 0; //有应答返回0

}

复制

//字节数据发送函数

//SendByte(u8 DAT);

//功能: 将数据DAT发送出去,可以是地址,也可以是数据

void SendByte(u8 DAT)

{

u8 i=0;

SCL=0;

for(i=0;i<8;i++) //要传送的数据长度为8位

{

if((DAT<

{

SDA=1; //判断发送位 发送是由高位开始发送

}

else

{

SDA=0;

}

Delay5us();

SCL=1; //置时钟线为高,通知被控器开始接收数据位

Delay5us();

SCL=0; //出函数保持SLC=0

_nop_(); //tHD 数据输出保持时间0ns

}

}

//功能: 用来接收从器件传来的数据,并判断总线错误(不发应答信号),

//发完后请用应答函数应答从机。

u8 RcvByte()

{

u8 Dat=0;

u8 i=0;

for(i=0;i<8;i++)

{

SCL=0; //置时钟线为低,准备接收数据位

_nop_(); //tDH从器件数据输出保持时间100ns

SDA=1; //释放总线准备接收数据位

Delay5us();

SCL=1; //置时钟线为高使数据线上数据有效

Dat<<=1; //最后一位不需要移位,所以移位放在此处

if(SDA==1)

{

Dat|=0x01; //读数据位,接收的数据位放入Dat中

}

Delay5us();

}

SCL=0; //出函数保持SLC=0

_nop_(); //tDH从器件数据输出保持时间100ns

return Dat;

}

//应答子函数

//主机应答

void Ack_I2c(void)

{

SCL=0;

SDA=0;

Delay5us();

SCL=1;

Delay5us();

SCL=0; //清时钟线,钳住I2C总线以便继续接收

}

//主机不应答

void Nack_I2c(void)

{

SCL=0;

SDA=1;

Delay5us();

SCL=1;

Delay5us();

SCL=0;

}

复制 /*************************此部分为AT2402的驱动程序使用I2C总线连接*************************************/

#include "stc15f2k60s2.h"

#include "Delay.h"

#include "24C04.h"

#include "I2C.h"

//24c 默认的硬件地址都是 0xa0 即 1010 然后A2 A1 A0 最后一位 为读写位 1读 0写

//24c02 256x8 bit

//24c04 512x8 bit

//而子地址 只是8位的 即最大也就256个字节 那么24c04 就要占用2个256个字节

//这里24c04硬件上采用的是 分页方法 即有24c02里有A2 A1 A0 当是24c04时 A0做为分页位

//当A0为0 表示第一页 写入第一页256字节

//当A0为1 表示第二页 写入第二页256字节

//在AT24CXX指定地址读出一个数据

//Addr:开始读数的地址

//返回值 :读到的数据

u8 AT24C_Rcvone(u8 Addr)

{

u8 temp=0;

Start_I2c(); //启动总线

SendByte(0xa0); //发送器件I2C地址,写模式

I2c_wait_ack(); //等待应答

SendByte(Addr); //发送器件存储地址

I2c_wait_ack(); //等待应答

Start_I2c(); //重新启动总线

SendByte(0xa1); //设置为读操作

I2c_wait_ack(); //等待应答;

temp=RcvByte(); //读字节

Nack_I2c(); //非应答

Stop_I2c(); //结束总线

return temp;

}

//在AT24CXX指定地址写入一个数据 此函数只限于 c02-c16

//Addr:写入数据的目的地址

//Data:要写入的数据

void AT24C_Sendone(u8 Addr,u8 Data)

{

Start_I2c(); //启动总线

SendByte(0xa0); //发送写命令

I2c_wait_ack(); //等待应答

SendByte(Addr); //发送地址

I2c_wait_ack(); //等待应答

SendByte(Data); //发送字节数据

I2c_wait_ack(); //等待应答

Stop_I2c(); //结束总线

Delay10ms(); //tWR 周期,等待I2C器件写完毕

}

楼主搞定了没,你对着我严格按datasheet写24C04的100K SCL程序,注意红色的标注的地方,不同器件参数不太一样,要全部通用的话可以统一延迟为1us, 那么就可以对应上你的器件上的最大900ns

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?注册

×

回复

举报

19楼

天风立马

发表于 2018-12-2 13:29

|

只看该作者

本帖最后由 天风立马 于 2018-12-2 13:32 编辑

我喜欢追渔的人. 去找我QQ, 你应该能找到. 我教你, 不收费. 你也可以去下载我之前分享的一个资料自己学.

回复

举报

相关推荐

【马克时空】梭鱼100M 红狼导弹登场
365bet官网备用网站

【马克时空】梭鱼100M 红狼导弹登场

📅 08-04 👁️ 5966
为什么要做广告?广告的作用和意义
365bet官网备用网站

为什么要做广告?广告的作用和意义

📅 07-09 👁️ 1865
全服探宝 萝卜玩《传奇霸业》苍月秘境
365服务热线

全服探宝 萝卜玩《传奇霸业》苍月秘境

📅 07-02 👁️ 1664