首页 > 其他分享 >I2C

I2C

时间:2023-11-14 15:44:37浏览次数:29  
标签:SCL save IIC 数据线 iic I2C 时钟

u8 time_temp=0;
IIC_SCL=1;//时钟线为高电平
delay_10us(1);
while(IIC_SDA){//等待数据线为0
  time_temp++;//计数超时
  if(time_temp>100){
    iic_stop();
    return 1;
  }
}
IIC_SCL=0;//时钟线为0,允许从机写
return 0;

I2C

I2C 总线只有两根双向信号线。一根是数据线 SDA,另一根是时钟线 SCL。

I2C特点

支持多设备。使用仲裁方式防止数据冲突。

连接到总线的设备都有独立地址。

数据线表示数据,时钟线用于数据收发同步。

总线通过上拉电阻接到电源。

速度最快3.4Mbit/s。

 

I2C协议

基本约束:传输数据时,时钟线高电平的时候,数据线不能跳变,时钟线为低电平时,数据线才可以跳变。

信号 作用   跳变 代码   图
起始信号 占用总线 时钟线:高电平;数据线:高->低(下降沿)

IIC_SCL=1;

IIC_SDA=1;

delay_10us(1);

IIC_SDA=0

delay_10us(1);

IIC_SCL=0;//钳住总线

停止信号 释放总线 时钟线:高电平;数据线:低->高(上升沿)

IIC_SCL=1;

IIC_SDA=0;

delay_10us(1);

IIC_SDA=1

delay_10us(1);

应答ACK 希望对方继续发送数据

主机发送完第8个数据帧时,释放数据线,由从机掌控数据线。但时钟线是由主机控制的

时钟线为低电平时,数据线跳到低电平(设定数据线信号为0),然后时钟线跳到高电平稳定一段时间再变低电平。(保持数据线信号)。

若从机在时钟线低电平的时候没来得及跳变,之后时钟线变为高电平就无法跳变,此时就默认是非应答了。(要在主机控制时钟线为低电平时及时决定是否跳变)

IIC_SCL=0;//允许设置

IIC_SDA=0; //设置为0

delay_10us(1);

IIC_SCL=1;//保持

delay_10us(1);

IIC_SCL=0;//释放

非应答ACK 希望对方停止发送数据

主机发送完第8个数据帧时,释放数据线,由从机掌控数据线。但时钟线是由主机控制的。

时钟线为低电平时,数据线跳到高电平(设定数据线信号位1),然后时钟线跳到高电平稳定一段时间再变成低电平。(保持数据线信号)。

IIC_SCL=0;//允许设置

IIC_SDA=1; //设置为1

delay_10us(1);

IIC_SCL=1;//保持

delay_10us(1);

IIC_SCL=0;//释放

 

总线寻址

10为寻址和7位寻址兼容,可以结合使用,10位可以向下兼容7位,因此以7位为例子介绍。

从机地址用7位表示,从机接到一个信号后与自己地址比较,判断自己是否为传输目标。

通常7位寻址位有固定位和可编程位,可编程位的个数决定接入总线期间的最大数目。如7位寻址,有4位固定,3位可编程,则可以接8位。

R/W表示数据传输方向,0表示主机写数据到从机,1表示主机读从机数据。

主机向一个从机发送完后又向另一个从机发送,可以不产生终止信号放弃主线,直接发另一个从机地址即可。

主机向一个从机发送数据后,想改变传输方向,此时需要重复发送一次从机地址和新的方向。

 

数据传输

当寻址完毕后,就可以发送数据,一个数据为8帧。第9帧由从机控制数据线,决定应答还是非应答。

 

 

AT24C系列芯片

芯片作用

用于存储值,即使在断电情况都不会清空。该芯片是接入在I2C上的,同I2C操作

 

芯片  串行CMOS 8位字节个数 字节页缓冲区
AT23C01 1K 128 8字节页
AT23C02 2K 256 16字节页
AT23C03 3K 512 16字节页
AT23C04 8K 1024 16字节页
AT23C05 16K 2048 16字节页

 

AT24C02器件寻址位为7位,高四位固定位1010,低三位由A0,A1,A2表示。

在51开发板中,芯片的A0/A1/A2已经接地,索引该芯片在总线上的器件地址为1010 000;

SDA:数据线引脚

SCL:时钟线引脚

WP:写保护。

VCC:电源。

VSS:接地。

若要从芯片读数据,则发送数据为1010 000 1,十六进制为0xA1;若要向芯片写数据,则发送数据为1010 000 0,十六进制为0xA1。

AT24芯片操作方式

不管是读写操作,都需要先在总线上写入寻址地址,确定寻址之后,才可以继续其他操作。

写操作,需要先用写模式,写入想保存的芯片内存位置地址,然后再写入数据。

读操作,需要先用写模式,写入向读取的芯片内存位置地址,然后再发送寻址改变成读模式,开始接收数据。

AT24C2芯片写操作 

void at24c02_write_one_byte(u8 addr,u8 dat)
{
    iic_start();
    iic_write_byte(0XA0); //在总线上寻址芯片地址
    iic_wait_ack();
    iic_write_byte(addr);//发送写地址,data数据存储在AT24芯片的内存位置
    iic_wait_ack();
    iic_write_byte(dat); //发送字节,发送数据
    iic_wait_ack();
    iic_stop(); //产生一个停止条件
    delay_ms(10);
}

AT24C2芯片读操作

u8 at24c02_read_one_byte(u8 addr)
{
    u8 temp=0;
    iic_start();
    iic_write_byte(0XA0); //向AT24芯片发送写命令
    iic_wait_ack();
    iic_write_byte(addr); //向AT24写入要读取的数据在芯片内存的位置
    iic_wait_ack();
    iic_start();
    iic_write_byte(0XA1); //进向AT24芯片发送接收模式
    iic_wait_ack();
    temp=iic_read_byte(0); //开始读取字节
    iic_stop(); //产生一个停止条件
    return temp; //返回读取的数据
}

 

驱动代码

等待ACK

u8 time_temp=0;
IIC_SCL=1;//时钟线为高电平
delay_10us(1);
while(IIC_SDA){//等待数据线为0
  time_temp++;//计数超时
  if(time_temp>100){
    iic_stop();
    return 1;
  }
}

IIC_SCL=0;//时钟线为0,钳住

return 0;    

写一个字节

u8 i=0;
IIC_SCL=0;//设置为0,允许数据线写
for(i=0;i<8;i++) //循环 8 次将一个字节传出,先传高再传低位
{
    if((dat&0x80)>0)//数据线写0和1
        IIC_SDA=1;
    else
        IIC_SDA=0;
    dat<<=1; 
    delay_10us(1);
    IIC_SCL=1;   //时钟线保持
    delay_10us(1); 
    IIC_SCL=0;   //时钟线允许写
    delay_10us(1);
}

读一个字节

u8 i=0,receive=0;
for(i=0;i<8;i++ ) //循环 8 次将一个字节读出,先读高再传低位
{
    IIC_SCL=0;
    delay_10us(1);
    IIC_SCL=1;
    receive<<=1; //从高位开始读
    if(IIC_SDA)receive++; //数据线为1,rec+1,否则为0
    delay_10us(1);
 }
if (!ack) //应答
    iic_nack();
else
    iic_ack();
return receive;
}
/*
假设有14,存储的二进制位1110
进制转换
初始rec=0,左移后,rec=0,读到1,rec=1
rec左移,rec=2,读到1,rec=3
rec左移,rec=6,读到1,rec=7
rec左移,rec=14,读到0,rec=14
左移为乘以2。

二进制转换十进制就是
从高到低遍历,每遍历一次都乘2,如果当前位为1则加1,否则不加。最终的到十进制。
/*

 

数码管按键小程序

/********************************************************************
****************** 实验名称:I2C-EEPROM 实验
接线说明:
实验现象:下载程序后,数码管右 4 位显示 0,按 K1 键将数据写入到 EEPROM 内保存,
按 K2 键读取 EEPROM 内保存的数据,按 K3 键显示数据加 1,按 K4 键显示数据清
零,
最大能写入的数据是 255。
注意事项:
*********************************************************************
******************/
#include "public.h"
#include "24c02.h"
#include "key.h"
#include "smg.h"
#define EEPROM_ADDRESS 0 //定义数据存入 EEPROM 的起始地址
/********************************************************************
***********
* 函 数 名 : main
* 函数功能 : 主函数
* 输 入 : 无
* 输 出 : 无
*********************************************************************
**********/
void main()
{
    u8 key_temp=0;
    u8 save_value=0;
    u8 save_buf[3];
    while(1){    
        key_temp=key_scan(0);
        if(key_temp==KEY1_PRESS){
            at24c02_write_one_byte(EEPROM_ADDRESS,save_value);
        }
        else if(key_temp==KEY2_PRESS){
            save_value=at24c02_read_one_byte(EEPROM_ADDRESS);
        }
        else if(key_temp==KEY3_PRESS){
            save_value++;
            if(save_value==255)save_value=255;
        }
        else if(key_temp==KEY4_PRESS){
            save_value=0;
        }
        save_buf[0]=save_value/100;
        save_buf[1]=save_value%100/10;
        save_buf[2]=save_value%100%10;//save buf用三个位表示,在数码管上三位显示。
        smg_display(save_buf,6);
    }
}

 

标签:SCL,save,IIC,数据线,iic,I2C,时钟
From: https://www.cnblogs.com/RedNoseBo/p/17831006.html

相关文章

  • 嵌入式中的I2C通信:串行通信的精华
    I2C(Inter-IntegratedCircuit),通常简称为IIC,是一种流行的串行通信协议,广泛应用于嵌入式系统中。本文将介绍I2C通信的基本原理,并提供代码示例,演示如何在嵌入式系统中使用I2C进行设备间的通信。I2C概述I2C是一种多主从结构的串行通信协议,最初由飞利浦(Philips)开发。它具有以下特点:双线......
  • 05-I2C详解
    目录一.什么是IIC1.相关概念和硬件连接2.I2C通信过程二.I2C时序基本单元1.起始信号和停止信号2.数据发送和接收一.什么是IIC1.相关概念和硬件连接IIC也称I2C,是一个多主从的串行总线,由飞利浦公司发明的通讯总线.属于半双工同步传输类总线,仅由两条线就能完成多机通讯,......
  • 基于rk3588----i2c驱动框架学习(2)-总线驱动 algorithm 分析
    rk3588i2calgorithm分析来了来了,上次分析完i2c的驱动框架今天我们就看看i2c的algorithm是如何实现的staticconststructi2c_algorithmrk3x_i2c_algorithm={.master_xfer=rk3x_i2c_xfer,.master_xfer_atomic......
  • ArmSom--I2C开发指南
    1.简介RK3588从入门到精通本⽂介绍在rockchip平台下如何配置i2c接口的方法并且添加调试验证i2c外设的例子开发板:ArmSoM-W3Kernel:5.10.160OS:Debian112.i2c接口概述i2c总线控制器通过串行数据(SDA)线和串行时钟(SCL)线在连接到总线的器件间传递信息。i2c总线一些......
  • ArmSom--I2C开发指南
    1.简介RK3588从入门到精通本⽂介绍在rockchip平台下如何配置i2c接口的方法并且添加调试验证i2c外设的例子开发板:ArmSoM-W3Kernel:5.10.160OS:Debian11  2.i2c接口概述i2c总线控制器通过串行数据(SDA)线和串行时钟(SCL)线在连接到总线的器件间传递信息。i2c......
  • C语言数据类型占用字节大小+rand_mode/randomize_mode/static constraint+I2C和SPI的
    C语言数据类型占用字节大小https://blog.csdn.net/sinan1995/article/details/79577106对于整形,最大8字节,超出8字节的计算,要么用库,要么不用。64位编译器:char/unsignedchar:1字节char*:8字节shortint:2字节int/unsignedint:4字节longint:8字节float:4字节double:8字节lon......
  • STM32---I2C通讯
    STM32的I2C通讯可以使用两种方式实现,分别是软件I2C,和硬件I2C。软件I2C主要是通过代码手动翻转电平来模拟时序;硬件I2C主要使用通过STM32自带的硬件外设实现。以下,我着重讲述一下硬件I2C的部分。 想要使用硬件I2C,主要分为以下四个步骤:第一步,开启GPIO和I2C的时钟跟GPIO一样,I2C需......
  • STM32之I2C通信
    I2C通信学习资料:江科大-STM32入门教程全面解析I2C通信协议-电子工程专辑爱上半导体-I2C通讯协议前言线与:连接在总线上的设备只要有一个输出低电平(0)总线就为低电平(0),只有全部设备都为高阻态时总线才是高电平(1)I2C简介I2C(InterICBus)是由Philips公司开发的一种通用数据总......
  • I2c_Adapter驱动框架讲解与编写-11
    参考资料:Linux内核文档:Linux-4.9.88\Documentation\devicetree\bindings\i2c\i2c-gpio.txtLinux-5.4\Documentation\devicetree\bindings\i2c\i2c-gpio.yamlLinux内核驱动程序:使用GPIO模拟I2CLinux-4.9.88\drivers\i2c\busses\i2c-gpio.cLinux-5.4\driver......
  • OpenHarmony:如何使用HDF平台驱动控制I2C
    1、程序介绍本程序是基于OpenHarmony标准系统编写的平台驱动案例:I2C目前已在凌蒙派-RK3568开发板跑通。详细资料请参考官网:https://gitee.com/Lockzhiner-Electronics/lockzhiner-rk3568-openharmony/tree/master/samples/b06_platform_device_i2c详细资料请参考官网:I2C平台驱......