I2C总线学习

I2C的时序图,如下所示:
在这里插入图片描述

总线应当时序图:
在这里插入图片描述

I2C时序要求:

  1. 空闲状态
    SCL和SDA都是处于高电平。
  2. 起始信号
    在SCL时钟线为高电平期间,SDA输出下降沿。
  3. 停止信号
    在SCL时钟线为高电平期间,SDA输出上升沿。
  4. 应答信号
    发送器每发送一个字节,就在时钟SCL第9个脉冲释放数据线,由接收器反馈一个应答信号,有效电平为低电平,有效应答(ACK应答);为高电平时,无效应答(NACK应答)

模拟I2C总线的代码,如下:
1.初始化总线——空闲状态。
void init(void)
{
sda = 1;
delay();
scl = 1;
delay();
}
2.起始信号
void start(void)
{
sda = 1;
delay();
scl = 1;
delay();
sda = 0;
delay();
}
3.停止信号
void stop(void)
{
sda = 0;
delay();
scl = 1;
delay();
sda = 1;
delay();
}
4.等待应答信号
void ack(void)
{
uint8 time = 0;
scl = 1;
delay();
/* 等待SDA线是否为低 /
while ((sda == 1) && (time < 250))
time++;
sda = 0;
delay();
}
5.写一个字节数据
void write_one_byte(uint8 value)
{
uint8 i = temp = 0;
temp = value;
for (i = 0; i < 8; i++)
{
temp = temp << 1;
scl = 0; /
时钟为低时,允许SDA数据变化 /
delay();
sda = CY;
delay();
scl = 1; /
时钟为高时,SDA数据稳定 /
delay();
}
scl = 0;
delay();
sda = 1;/
释放sda总线,由从设备应答 /
delay();
}
6.读一个字节数据
uint8 read_one_byte(void)
{
uint8 i = value = 0;
scl = 0;
delay();
sda = 1;
delay();
for (i = 0; i < 8; i++)
{
scl = 1;/
上升沿时,把数据放在sda数据线上,在高电平期间稳定读取 */
delay();
value = (value << 1) | sda;
scl = 0;
delay();
}
return value;
}
7.向任意地址写一个字节数据
void write_addr_one_byte(uint8 addr, uint8 value)
{
start();//起始信号
write_one_byte(0xa0);//写从设备地址
ack();//等待应答
write_one_byte(addr);//写芯片地址
ack();//等待相应
write_one_byte(value);//写数据
ack();//等待相应
stop();//停止
}
8.向任意地址读一个字节数据
uint8 read_addr_one_byte(uint8 addr)
{
uint8 value = 0;
start();//起始信号
write_one_byte(0xa0);//写从设备地址
ack();//等待应答
write_one_byte(addr);//写芯片地址
ack();//等待相应
start();//起始信号
write_one_byte(0xa1);//写读操作
ack();//等待相应
value = read_one_byte();//读取数据
stop();//停止信号
return value;
}

以上便是I2C时序的代码实现。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值