单片机I2C总线

void iic_start()//开始
{
	IIC_SCL=1;
	IIC_SDA=1;
	delay_10us(1);
	IIC_SDA=0;
	delay_10us(1);
	IIC_SCL=0;//变为低电平,繁忙状态,1为空闲状态
}
void iic_stop()//结束
{
	IIC_SCL=1;
	IIC_SDA=0;
	delay_10us(1);
	IIC_SDA=1;
	delay_10us(1);//SCL在高电平,空闲状态
}

SCL:时钟信号

SDA:一根线,半双工的

         

 上拉电阻

开漏模式下,开关接0闭合,开关接1断开(什么也没接,电平不稳定)

 与传输不一样:传输时候SDA稳定 

SCL为低电平时,发送器向数据线上发送一位数据,在此期间数据线上的数据允许发生变化,时钟线SCL为高电平期间接收器从数据线上读取一位数据,不允许发生变化了,必须保持稳定

 

 主机发,地址是向谁发

一帧包含9位,最后一位是应答位

RA:接收应答,从机收到发0

蓝色S:开始

绿色S:发送地址与字节

 R/W是读写位,1是读2是写

地址前四位固定,后三位可变换A0,A1,A2

        

 

 

 

 主机读,地址是向谁读

 发与收,去掉P

 SA=1,停

功能实现:

sbit SCL=P2^1;
sbit SDA=P2^0;

void I2C_Start()
{
	SDA=1;//确保SDA是1
	SCL=1;//拉高时钟
	SDA=0;//拉低SDA
	SCL=0;//拉低时钟,形成时钟
}
void I2C_Stop()
{
	SDA=0;//不知道SDA是啥,先拉低
	
	SCL=1;//拉高时钟
	SDA=1;//拉高SDA
	SCL=0;
}

发送模块

因为开始的时候scl已经拉低了,发送字节只用放入数据在拉高读取就行,然后在拉低这是一个循环过程

void I2C_SendByte(unsigned char Byte)
{
	unsigned char i;
	for(i=0;i<8;i++)
	{
		SDA=Byte&(0x80>>i);
		SCL=1;
		SCL=0;
	}
}

先高后低,不延时是1us,SCL拉高立马拉低不影响

 

接收模块:

 因为主机在接收之前要释放SDA 所以将SDA又设置为默认的高电平了

unsigned char I2C_ReceiveByte()
{
	
	unsigned char i,Byte=0x00;
	SDA=1;
	for(i=0;i<8;i++)
	{
		SCL=1;
		if(SDA){Byte|=0x80;}
		SCL=0;
	}

}

#include <REGX52.H>
sbit SCL=P2^1;
sbit SDA=P2^0;
//我写一个东西要知道从机收没收到要读出SDA,
//我收一个数据我收到了要将SDA置1告诉从机
void I2C_Start()
{
	SDA=1;//确保SDA是1
	SCL=1;//拉高时钟
	SDA=0;//拉低SDA
	SCL=0;//拉低时钟,形成时钟
}
void I2C_Stop()
{
	SDA=0;//不知道SDA是啥,先拉低
	
	SCL=1;//拉高时钟
	SDA=1;//拉高SDA
	SCL=0;
}
void I2C_SendByte(unsigned char Byte)
{
	unsigned char i;
	for(i=0;i<8;i++)
	{
		SDA=Byte&(0x80>>i);
		SCL=1;
		SCL=0;
	}
}

//SDA拉高是为了释放控制,当读取数据时,
//主机拉高,释放控制,从机往SDA上写入数据,
//主机拉高SCL读取数据

unsigned char I2C_ReceiveByte()
{
	unsigned 	char Byte=0x00;
	SDA=1;//控制权交给从机
	for(i=0;i<8;i++)
	{
		SCL=1;	
		if(SDA){Byte|=0x80};//SDA 1接收,0不接收
		SCL=0; 
	}
	
	return Byte;
}

void I2C_SendAck(unsigned char Ackbit)
{
	SDA=Ackbit;
	SCL=1;
	SCL=0;
}

unsigned char I2C_ReceiveAck()
{
	unsigned char =0;
	SDA=1;//接收需要释放总线,所以需要释放SDA,就是让从机有主导权
	SCL=1;
	AckBit=SDA;
	SCL=0;
	return AckBit;
}

普中写法

​​​​​​​

void iic_start()//开始
{
	IIC_SCL=1;
	IIC_SDA=1;
	delay_10us(1);
	IIC_SDA=0;
	delay_10us(1);
	IIC_SCL=0;//变为低电平,繁忙状态,1为空闲状态
}
void iic_stop()//结束
{
	IIC_SCL=1;
	IIC_SDA=0;
	delay_10us(1);
	IIC_SDA=1;
	delay_10us(1);//SCL在高电平,空闲状态
}

void iic_ack()//应答
{
	IIC_SCL=0; //低电平时,数据可以更改
	IIC_SDA=0;
	delay_10us(1);
	IIC_SCL=1;//高电平读取 
	delay_10us(1);
	IIC_SCL=0; 
}
void iic_nack()//非应答
{
	IIC_SCL=0; //低电平时,数据可以更改
	IIC_SDA=1;
	delay_10us(1);
	IIC_SCL=1;//高电平读取 
	delay_10us(1);
	IIC_SCL=0; 
}
u8 iic_wait_ack()//读取从机响应,应答IIC_SDA=0,非应答应答IIC_SDA=1
{
	u8 time_temp=0;
	IIC_SCL=1;
	delay_10us(1);
	while(IIC_SDA)
	{
		time_temp++;
		if(time_temp>100)
		{
			iic_stop();
			return 1;//返回1非应答
		}
	}
	IIC_SCL=0;
	return 0;//返回0应答
}

 

void iic_write_byte(u8 dat)//写字节
{
	 u8 i=0;
	IIC_SCL=0;//等于0数据可以改变
	for(i=0;i<8;i++)
	{
		if((dat&0x80)>0)
			IIC_SDA=1;
		else
			IIC_SDA=0; 
		dat<<=1;
		IIC_SCL=1;
		delay_10us(1);
		IIC_SCL=0;
		delay_10us(1);
	}
}
u8 iic_read_byte(u8 ack)
{
	u8 i=0;
	u8 receive=0;
	
	for(i=0;i<8;i++)
	{
		IIC_SCL=0;
		delay_10us(1);
		IIC_SCL=1;
		delay_10us(1);
		receive<<=1;//因为最高位
		if(IIC_SDA==1)
		{
			receive++;
		}
	}
	if(ack==0)iic_nack();
	else iic_ack();
	
	return receive;
}

 

#include "24c02.h"
void at24c02_write_one_byte(u8 addr,u8 dat)//地址与数据
{
	iic_start();
	iic_write_byte(0xa0);//地址1010 00000 前四位固定
	iic_wait_ack();//等待应答
	iic_write_byte(addr);
	iic_wait_ack();//等待应答
	iic_write_byte(dat);
	iic_wait_ack();
	iic_stop();
	delay_ms(10);
}

u8 at24c02_read_one_byte(u8 addr)
{
	u8 temp=0;
	iic_start();//主机启动
	iic_write_byte(0xa0);//从机地址
	iic_wait_ack();//从机ack返回
	iic_write_byte(addr);//写入读取地址
	iic_wait_ack();
	iic_start();
	iic_write_byte(0xa1);
	iic_wait_ack();
	temp=iic_read_byte(0);
	iic_stop();
	delay_ms(10);
	
}

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值