STM32——AT24C02

   日期:2020-09-24     浏览:115    评论:0    
核心提示:STM32——AT24C02简介AT24C02是一个2K位串行CMOS E2PROM, 内部含有256个8位字节,CATALYST公司的先进CMOS技术实质上减少了器件的功耗。AT24C02有一个8字节页写缓冲器。该器件通过IIC总线接口进行操作,有一个专门的写保护功能。特点与 400KHz I2C 总线兼容 。1.8 到 6.0 伏工作电压范围低功耗 CMOS 技术写保护功能 当 WP 为高电平时进入写保护状态页写缓冲器自定时擦写周期1,000,000 编程/擦除周期可保存数据 10

STM32——AT24C02

  • 简介
    • 特点
    • 地址意义
  • 时序图
  • 代码

简介

AT24C02是一个2K位串行CMOS E2PROM, 内部含有256个8位字节,CATALYST公司的先进CMOS技术实质上减少了器件的功耗。AT24C02有一个8字节页写缓冲器。该器件通过IIC总线接口进行操作,有一个专门的写保护功能。

特点

与 400KHz I2C 总线兼容 。
1.8 到 6.0 伏工作电压范围
低功耗 CMOS 技术
写保护功能 当 WP 为高电平时进入写保护状态
页写缓冲器
自定时擦写周期
1,000,000 编程/擦除周期
可保存数据 100 年
8 脚 DIP SOIC 或 TSSOP 封装
温度范围 商业级 工业级和汽车级

地址意义

时序图

写操作

读操作(读之前要进行一边写操作才能获取地址)

代码



#define SCL PBout(8)
#define SDA_IN PBin(9)
#define SDA_OUT PBout(9)

void Iic_Init(void) //IIC引脚配置
{ 
	GPIO_InitTypeDef GPIO_InitStruct;  //结构体
	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);	//使能GPIO B组时钟

	GPIO_InitStruct.GPIO_Pin	= GPIO_Pin_8|GPIO_Pin_9;     	//引脚8 9
	GPIO_InitStruct.GPIO_Mode	= GPIO_Mode_OUT;	//输出模式
	GPIO_InitStruct.GPIO_OType	= GPIO_OType_PP;    //输出推挽
	GPIO_InitStruct.GPIO_PuPd	= GPIO_PuPd_UP;	    //上拉
	GPIO_InitStruct.GPIO_Speed	= GPIO_Speed_50MHz; //输出速度
	GPIO_Init(GPIOB, &GPIO_InitStruct);
	
	//总线空闲
	SCL = 1;
	SDA_OUT = 1;

}

//引脚模式变更
void Iic_Sda_Mode(GPIOMode_TypeDef mode)
{ 
	GPIO_InitTypeDef  	GPIO_InitStructure;
	
	GPIO_InitStructure.GPIO_Pin   = GPIO_Pin_9;				//第9号引脚
	GPIO_InitStructure.GPIO_Mode  = mode;					//输入/输出模式
	GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;			//推挽输出,增强驱动能力,引脚的输出电流更大
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;		//引脚的速度最大为100MHz
	GPIO_InitStructure.GPIO_PuPd  = GPIO_PuPd_NOPULL;		//没有使用内部上拉电阻
	GPIO_Init(GPIOB, &GPIO_InitStructure);	
}

//启动信号
void Iic_Start(void)
{ 
	Iic_Sda_Mode(GPIO_Mode_OUT);
	
	//总线空闲
	SCL = 1;
	SDA_OUT = 1;	
	delay_us(5);
	
	//启动信号
	SDA_OUT = 0;
    delay_us(5);	
	SCL = 0;

}

//停止信号
void Iic_Stop(void)
{ 
	Iic_Sda_Mode(GPIO_Mode_OUT);	

	SCL = 0;
	SDA_OUT = 0;
	delay_us(5);
	
	SCL = 1;
	delay_us(5);
	SDA_OUT = 1;
	
}

//引脚发送一位数据
void Iic_Send_Ack(u8 ack)
{ 
	Iic_Sda_Mode(GPIO_Mode_OUT);

	SCL = 0;
	
	
	
	//发数据1
	if(ack == 1)
	{ 
		SDA_OUT = 1;  //引脚输出
	}
	//发数据0
	if(ack == 0)
	{ 
		SDA_OUT = 0; //引脚输出
	}	
	
	delay_us(5);
	SCL = 1;
	delay_us(5);
	SCL = 0;
}


//引脚发送一个字节数据
void Iic_Send_Byte(u8 data)
{ 
	u8 i;
	Iic_Sda_Mode(GPIO_Mode_OUT);

	SCL = 0;
	
	//0 1 1 1 1 0 0 0
	for(i=0; i<8; i++)
	{ 
		
		
		//发数据1
		if(data &  (1<<(7-i)))
		{ 
			SDA_OUT = 1;  //引脚输出
		}
		//发数据0
		else
		{ 
			SDA_OUT = 0; //引脚输出
		}	
		
		delay_us(5);
		SCL = 1;
		delay_us(5);
		SCL = 0;
	}
}

//接受一位数据
u8 Iic_Rcv_Ack(void)
{ 
	u8 ack;
	
	Iic_Sda_Mode(GPIO_Mode_IN);

	
	SCL = 0;
	delay_us(5);
	SCL = 1;	
	delay_us(5);
	if(SDA_IN == 1)  //引脚为电平为1
	{ 
		ack = 1;
	}
	
	if(SDA_IN == 0)  //引脚为电平为1
	{ 
		ack = 0;
	}	
	
	SCL = 0;	

	return ack;
}

//接受一个字节数据
u8 Iic_Rcv_Byte(void)
{ 
	u8 i, data = 0; //0 0 0 0 0 0 0 0 比如有数据:1 1 0 0 1 0 0 0 
	Iic_Sda_Mode(GPIO_Mode_IN);
	
	SCL = 0;
	
	//0 1 1 1 1 0 0 0
	for(i=0; i<8; i++)
	{ 

		delay_us(5);
		SCL = 1;
		delay_us(5);
		
	    //接受数据
		if(SDA_IN == 1)  //引脚为电平为1
		{ 
			data |= (1<<(7-i));
		}	
		SCL = 0;
	}
	return data;
}


void AT24c02_Write(u8 addr, u8 *write_buff, u8 len)
{ 
	u8 ack;
	
	//启动信号
	Iic_Start();
	
	//发送设备地址
	Iic_Send_Byte(0xA0);
	ack = Iic_Rcv_Ack();
	if(ack == 1)
	{ 
		printf("ack failure\n");
		return ;
	}
	
	//发送写数据起始地址
	Iic_Send_Byte(addr);
	ack = Iic_Rcv_Ack();
	if(ack == 1)
	{ 
		printf("ack failure\n");
		return ;
	}	
	
	//数据:hello
	while(len--)
	{ 
		//发送数据
		Iic_Send_Byte(*write_buff);
		ack = Iic_Rcv_Ack();
		if(ack == 1)
		{ 
			printf("ack failure\n");
			return ;
		}	
	
		write_buff++;
	}
	
	Iic_Stop();
	printf("write finish\n");
}


void AT24c02_Read(u8 addr, u8 *read_buff, u8 len)
{ 
	u8 ack;
	
	//启动信号
	Iic_Start();
	
	//发送设备地址
	Iic_Send_Byte(0xA0);
	ack = Iic_Rcv_Ack();
	if(ack == 1)
	{ 
		printf("ack failure\n");
		return ;
	}
	
	//发送写数据起始地址
	Iic_Send_Byte(addr);
	ack = Iic_Rcv_Ack();
	if(ack == 1)
	{ 
		printf("ack failure\n");
		return ;
	}	
	
	//启动信号
	Iic_Start();
	
	//发送设备地址
	Iic_Send_Byte(0xA1);
	ack = Iic_Rcv_Ack();
	if(ack == 1)
	{ 
		printf("ack failure\n");
		return ;
	}	
	

	
	//数据:hello 5
	while(len--)
	{ 
		*read_buff = Iic_Rcv_Byte();
		
		if(len > 0)
			Iic_Send_Ack(0); //发送有效应答
	
		read_buff++;
	}
	
	Iic_Send_Ack(1);
	Iic_Stop();
	printf("read finish\n");
}

 
打赏
 本文转载自:网络 
所有权利归属于原作者,如文章来源标示错误或侵犯了您的权利请联系微信13520258486
更多>最近资讯中心
更多>最新资讯中心
0相关评论

推荐图文
推荐资讯中心
点击排行
最新信息
新手指南
采购商服务
供应商服务
交易安全
关注我们
手机网站:
新浪微博:
微信关注:

13520258486

周一至周五 9:00-18:00
(其他时间联系在线客服)

24小时在线客服