C51 - I2C总线操作 24C02 EEPROM

一.I2C总线概述

  • 解决芯片与芯片之间的通讯
  • uart ,485 解决板子与板子之间通讯
    在这里插入图片描述

数据传输速率为从机控制。
SDA :数据传输总线
SCL :时钟线
在这里插入图片描述
总线上连接多少个从机设备是与线间电容有关,线间电容不超过400pF 即可

I2C总线为内部开漏接口方式,需在SCL与SDA处加上拉电阻
SDA与SCL要为高电平,则挂在总线上的从机设备线都应该为高电平。(线与关系)

在这里插入图片描述

二.I2C总线协议数据

(1)只有总线空闲时才允许启动数据传输。
(2)在数据传输时,当时钟线为高电平时,数据线必须保证稳定状态,不允许有跳变。

一.字节传送与应答

在这里插入图片描述

二.I2C总线的寻址

器件(从机)的地址由7位组成,它与一位方向位构成了I2C总线数据传输时起始状态S之后第一个字节。
在这里插入图片描述
当主机发送了第一个字节后,系统中的每一个从机都在起始状态S之后把高7位与本机地址比较,如果与本机地址一样,则被主机选中,是接收数据还是发送数据由R/W 确定。方向位(R/W),用“ 0”表示主机发送(写)数据(W),“ 1”表示主机接收 数据(R)

在这里插入图片描述
在这里插入图片描述

二.I2C数据代码

NOP指令
#include <intrins.h> 包含其文件
(1)一个NOP就是一个机器周期

(2)空指令,延时一个机器周期

(3)这个与单片机型号、指令类型和使用的晶振频率有关,比如AT89C51,是一个12个时钟周期等于1个机器周期的单片机 ,如果使用的晶振是12MHz的话,执行一条单指令的
NOP 需要 12x(1/12M)=1微秒的时间。

在这里插入图片描述
SCL维持Tsu-STA时间后,SDA 开始变为低电平。
BSP_I2C.c
在这里插入图片描述

起始信号:当SCL 线在高电平期间 SDA 线从高电平向低电平切换。
注意:
起始信号和停止信号是在SCL 是高电平期间,SDA线电平切换的过程,而不是单纯的高低电平。

/*******************************************************************************
Function    : bsp_I2c_start
Description : i2c驱动 起始函数
Input       : 无
Output      : 无
Return      : 无
*******************************************************************************/
void bsp_I2c_start(void)
{
    I2C_SCL = 1;         
    I2C_SDA = 1;
    I2C_Delay();         //scl需要维持4.7us,拉低SDA,产生起始信号
    I2C_SDA = 0;         //此时SCL仍维持在高电平。SDA进行信号跳变
	I2C_Delay();  
	I2C_SCL = 0;         //产生起始信号后,SCL线应拉低。否则SCL高电平默认发送数据。而此时的SDA线为低电平会当作地址(数据)
}                     

在这里插入图片描述

/*******************************************************************************
Function    : bsp_I2c_Stop
Description : i2c驱动 停止函数
Input       : 无
Output      : 无
Return      : 无
*******************************************************************************/
void bsp_I2c_Stop(void)
{
    I2C_SDA = 0;         
    I2C_SCL = 1;
    I2C_Delay();        
    I2C_SDA = 1;         
	IC_Delay();   
}                     

在这里插入图片描述

/*******************************************************************************
Function    : bsp_I2c_ACK
Description : i2c驱动 停止函数
Input       : 无
Output      : 无
Return      : 无
*******************************************************************************/
void bsp_I2c_ACK(void)
{
    I2C_SCL = 0;
    I2C_Delay();  
    I2C_SDA = 0;         
    I2C_Delay(); 
    I2C_SCL = 1;  
    I2C_Delay();
    I2C_SCL =0;
    I2C_Delay();       
    I2C_SDA = 1; //应答完成以后立马释放总线。       
	IC_Delay();   
}     
/*******************************************************************************
Function    : bsp_I2c_NACK
Description : i2c驱动 应答函数
Input       : 无
Output      : 无
Return      : 无
*******************************************************************************/
void bsp_I2c_NACK(void)
{
    I2C_SCL =0;
    I2C_Delay();
    I2C_SDA = 1;         
    I2C_Delay(); 
    I2C_SCL = 1;  
    I2C_Delay();   
    I2C_SCL = 0;        
	I2C_Delay();    
}     
               
/*******************************************************************************
Function    : bsp_I2c_WaitACK 
Description : CPU产生一个时钟,并读取器件的ACK信号
Input       : 无
Output      : 无
Return      : 返回0表示正确应答,1表示无应答
*******************************************************************************/
unsigned char bsp_I2c_WaitACK(void)
{
    unsigned char ret;
    I2C_SDA = 1;        //CPU释放总线
    I2c_Delay();        
    I2C_SCL=1();        //cpu驱动SCL=1,此时器件会返回ACK信号
    i2c_Delay();
    if(EEPROM_I2C_SDA_READ())    //CPU读取SDA线状态,有应答返回1,无应答返回0
    {
        ret = 1;
    }
    else
    {
        ret = 0; 
    }
    I2C_SCL=1();  //准备接收下一个字节
    I2c_Delay();
    return ret;
}
/*******************************************************************************
Function    : bsp_I2c_write
Description : 主机通过i2c 写一个字节给从机
Input       : byte:写入的一个字节
Output      : 无
Return      : 无
*******************************************************************************/
void bsp_I2c_start(unsigned char byte)
{
    unsigned char temp;
    for (temp = 0x80;temp != 0;0x80 >>=  1)
	  {
		    if((byte & temp) == 0)
				{
                    I2C_SCL = 0;
				}
				else
				{
				    I2C_SCL = 1;
				}
				I2C_Delay();  
				I2C_SCL = 1;  
				I2C_Delay();
			    I2C_SCL = 0;
   }
}	
//bit  是变量类型,相当于boot 只占一个位,最多可定128个bit变量
//sbit 是给可位寻址的变量(或特殊功能寄存器)的某一个位定个别名,不另占空间
bit I2C_RecvAck()
{
    bit ack;
    I2C_SDA = 1;  //主机主动释放SDA,为读ack做准备
    I2C_Delay(); 
    I2C_SCL = 1;
    ack = I2C_SDA;
    I2C_Delay(); 
    I2C_SCL = 0;
    return ack;
}

BSP_I2C.h

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
void start 开始信号 void stop 停止信号 void Ack 发确认信号 void NoAck 发无确认信号 void init 初始化信号 拉高SDA和SCL两条总线 bit write byte uchar date 写一字节 将 date 写入AT24C02 中 uchar read byte 读一字节 从 AT24C02 中读一字节 bit busy 应答查询 stop 后 启动AT24C02内部写周期 启动查询 初始化EEPROM子程序内容为0XFF nPage 0 31 void Init Flash uchar nPage 8 bytes 1 page init 0xFF void write add uchar address uchar date 向 AT24C02 中写数据 从AT24C02中给定的地址nAddr起 将存放在以指针nContent开头的存储空间中的nLen个字节数据 连续写入AT24C02 void write flash uchar nContent uchar nAddr uchar nLen uchar read add uchar address 从 AT24C02 中读出数据 从AT24C02中给定的地址nAddr起 读取nLen个字节数据存放在以指针nContent开头的存储空间 void read flash uchar nContent uchar nAddr uchar nLen 单片机P2口接74HC138(三八译码器)P2 3 74HC138: EI P2 2 74HC138:A2 P2 1 74HC138:A1 P2 0 74HC138:A0 译码器输出 Y0 Y1 Y2 Y3 Y4 Y5 Y6 Y7均低电平有效 分别选通1 8个数码管 包括2个四位一体数码管LG3641BH 共2x4 8个数码管 数码管数据口为P0口 数码管为共阳4位一体数码管 功能: 译码器输出为1 8个数码管的段选信号 轮流选择1 8数码管 void display uchar nContent uchar nLen 功能:在8段数码管上显示nLen个字符 这些字符存储在指针nContent开头的往下的内容中 显示原理: 1 送出要显示的段数 2 P2译码 选择要显示的位 3 延时1 2ms 时间不能太长 否则会闪烁 也不能太短 否则会很暗 4 取消段选 消隐 若要显示多段 重复以上4步 ">void start 开始信号 void stop 停止信号 void Ack 发确认信号 void NoAck 发无确认信号 void init 初始化信号 拉高SDA和SCL两条总线 bit write byte uchar date 写一字节 将 date 写入AT24C02 中 uchar read byte 读一字节 从 AT24C02 中读一 [更多]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值