STM32 —— AT24C02

Introducción

AT24C02 es un CMOS E2PROM serie de 2K bits con 256 bytes de 8. La tecnología CMOS avanzada de CATALYST reduce sustancialmente el consumo de energía del dispositivo. AT24C02 tiene un búfer de escritura de página de 8 bytes. El dispositivo funciona a través de la interfaz de bus IIC y tiene una función especial de protección contra escritura.

Caracteristicas

Compatible con bus I2C de 400 KHz.
Rango de voltaje de operación de 1.8 a 6.0 voltios
Tecnología CMOS de bajo consumo de energía
Función de protección contra escritura Cuando WP es alto, ingresa al estado de protección contra
escritura Búfer de escritura de página
Ciclos de escritura y borrado temporizados
1,000,000 Ciclos de programa / borrado
Puede guardar datos durante 100 años
DIP SOIC de 8 pines o
Rango de temperatura del paquete TSSOP grado comercial grado industrial y grado automotriz

Significado de la dirección

Inserte la descripción de la imagen aquí

Diagrama de tiempo

Operación de escritura Operación de
Inserte la descripción de la imagen aquí
lectura (se debe realizar una operación de escritura antes de leer para obtener la dirección)
Inserte la descripción de la imagen aquí

Código

/*
引脚说明
SCL -- PB8
SDA -- PB9

*/

#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");
}

Supongo que te gusta

Origin blog.csdn.net/weixin_46026429/article/details/108716771
Recomendado
Clasificación