I2C——24C02

I2C——24C02
I2C:
1.I2C传数据先传高bit位,丛机收到数据后,若有应答,第9个时钟高电平期间,需要把SDA拉低。
2.I2C主机接收数据,若有应答,第9个时钟高电平期间,需要把SDA拉低。
3.起始信号后必须传送一个从机的地址(7位),第8位是数据的传送方向位(R/T),用“0”表示主机发送数据(T),“1”表示主机接收数据(R)


4.24c02先关的时序要求:
在这里插入图片描述
在这里插入图片描述


测试能正常工作的程序:

#include <reg52.h>
//stdio.h,string.h用于printf函数原型
#include <stdio.h>

typedef unsigned int u16;
typedef unsigned char u8;

sbit scl = P2^1;
sbit sda = P2^0;


void delay10us(void)
{
	unsigned char a,b;
	for(b=1;b>0;b--)
		for(a=2;a>0;a--);
}

//scl=0  sda=0
void i2c_start(void)
{
	sda = 1;
	delay10us();
	scl = 1;
	delay10us();
	sda = 0;
	delay10us();
	scl = 0;
	delay10us();
}

//scl=1 sda=1  表示总线空闲
void i2c_stop(void)
{
	sda = 0;
	delay10us();
	scl = 1;
	delay10us();
	sda = 1;
	delay10us();
}

//发送完一个字节SCL=0,SDA=1
u8 i2c_send_byte(u8 dat)
{
	u8 i = 0;
	u8 timeout = 0;
	for (i=0; i<8; i++)
	{
		sda = dat >> 7;
		dat <<= 1;
		delay10us();
		scl = 1;
		delay10us(); //建立时间>4.7us
		scl = 0;
		delay10us(); //时间大于4us
	}
	sda = 1;
	delay10us();
	scl = 1;
	delay10us();
	while (sda)
	{
		timeout++;
		//如果超过2000us没有应答发送失败,或者为非应答,表示接收结束
		if (timeout > 200) 
		{
			scl = 0;
			delay10us();
			return 0;
		}
	}
	scl = 0;
	delay10us();
	return 1;
}

u8 i2c_read_byte(void)
{
	u8 dat = 0;
	u8 i = 0;
	delay10us();
	for (i=0; i<8; i++)
	{
		scl = 1;
		delay10us();
		dat <<= 1;
		dat |= sda;
		delay10us();
		scl = 0;
		delay10us();
	}
	sda = 1;
	delay10us();
	scl = 1;
	delay10us();
	scl = 0;
	return dat;
}

void at24c02_write(u8 addr, u8 dat)
{
	i2c_start();
	i2c_send_byte(0xa0);
	i2c_send_byte(addr);
	i2c_send_byte(dat);
	i2c_stop();
}

u8 at24c02_read(u8 addr)
{
	u8 dat = 0;
	i2c_start();
	i2c_send_byte(0xa0);
	i2c_send_byte(addr);
	i2c_start();
	i2c_send_byte(0xa1);
	dat = i2c_read_byte();
	i2c_stop();
	return dat;
}


void uart_init(void)
{
	//波特率:4800
	//设置为工作方式1
	SCON=0X50;
	//设置定时器工作方式2
	TMOD=0X20;
	//波特率加倍
	PCON=0X80;
	//计数器初始值设置,注意波特率是4800的
	TH1=0XF3;
	TL1=0XF3;
	//串行口中断允许位(这个是包含串口的接收和发送中断的)
	ES=1;
	//打开总中断
	EA=1;
	//打开计数器
	TR1=1;
	
	TI=1;//直接使用printf必须加入此句才能实现发送
}

/*大概delay 1ms左右*/
void delay(unsigned int z)
{
	unsigned int x,y;
	for(x=z;x>0;x--)
		for(y=110;y>0;y--);
}

 
int main(void)
{
	u8 dat = 0;
	uart_init();

	while (1)
	{
		at24c02_write(1, 'k');
		delay(1000);
		dat = at24c02_read(1);
		printf("read: %c\n", dat);
		delay(1000);
	}
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值