IIC驱动24cxx外部存储芯片

📅 2026/7/17 11:50:31
IIC驱动24cxx外部存储芯片
话不多说直接上源代码。实测可用#includemyiic.h#includedelay.h//初始化IICvoidIIC_Init(void){GPIO_InitTypeDef GPIO_InitStructure;RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);//使能GPIOB时钟GPIO_InitStructure.GPIO_PinGPIO_Pin_6|GPIO_Pin_7;GPIO_InitStructure.GPIO_ModeGPIO_Mode_Out_PP;//推挽输出GPIO_InitStructure.GPIO_SpeedGPIO_Speed_50MHz;GPIO_Init(GPIOB,GPIO_InitStructure);GPIO_SetBits(GPIOB,GPIO_Pin_6|GPIO_Pin_7);//PB6,PB7 输出高}//产生IIC起始信号voidIIC_Start(void){SDA_OUT();//sda线输出IIC_SDA1;IIC_SCL1;delay_us(4);IIC_SDA0;//START:when CLK is high,DATA change form high to lowdelay_us(4);IIC_SCL0;//钳住I2C总线准备发送或接收数据}//产生IIC停止信号voidIIC_Stop(void){SDA_OUT();//sda线输出IIC_SCL0;IIC_SDA0;//STOP:when CLK is high DATA change form low to highdelay_us(4);IIC_SCL1;IIC_SDA1;//发送I2C总线结束信号delay_us(4);}//等待应答信号到来//返回值1接收应答失败// 0接收应答成功u8IIC_Wait_Ack(void){u8 ucErrTime0;SDA_IN();//SDA设置为输入IIC_SDA1;delay_us(1);IIC_SCL1;delay_us(1);while(READ_SDA){ucErrTime;if(ucErrTime250){IIC_Stop();return1;}}IIC_SCL0;//时钟输出0return0;}//产生ACK应答voidIIC_Ack(void){IIC_SCL0;SDA_OUT();IIC_SDA0;delay_us(2);IIC_SCL1;delay_us(2);IIC_SCL0;}//不产生ACK应答voidIIC_NAck(void){IIC_SCL0;SDA_OUT();IIC_SDA1;delay_us(2);IIC_SCL1;delay_us(2);IIC_SCL0;}//IIC发送一个字节//返回从机有无应答//1有应答//0无应答voidIIC_Send_Byte(u8 txd){u8 t;SDA_OUT();IIC_SCL0;//拉低时钟开始数据传输for(t0;t8;t){//IIC_SDA(txd0x80)7;if((txd0x80)7)IIC_SDA1;elseIIC_SDA0;txd1;delay_us(2);//对TEA5767这三个延时都是必须的IIC_SCL1;delay_us(2);IIC_SCL0;delay_us(2);}}//读1个字节ack1时发送ACKack0发送nACKu8IIC_Read_Byte(unsignedcharack){unsignedchari,receive0;SDA_IN();//SDA设置为输入for(i0;i8;i){IIC_SCL0;delay_us(2);IIC_SCL1;receive1;if(READ_SDA)receive;delay_us(1);}if(!ack)IIC_NAck();//发送nACKelseIIC_Ack();//发送ACKreturnreceive;}#ifndef__MYIIC_H#define__MYIIC_H#includesys.h//IO方向设置#defineSDA_IN(){GPIOB-CRL0X0FFFFFFF;GPIOB-CRL|(u32)828;}#defineSDA_OUT(){GPIOB-CRL0X0FFFFFFF;GPIOB-CRL|(u32)328;}//IO操作函数#defineIIC_SCLPBout(6)//SCL#defineIIC_SDAPBout(7)//SDA#defineREAD_SDAPBin(7)//输入SDA//IIC所有操作函数voidIIC_Init(void);//初始化IIC的IO口voidIIC_Start(void);//发送IIC开始信号voidIIC_Stop(void);//发送IIC停止信号voidIIC_Send_Byte(u8 txd);//IIC发送一个字节u8IIC_Read_Byte(unsignedcharack);//IIC读取一个字节u8IIC_Wait_Ack(void);//IIC等待ACK信号voidIIC_Ack(void);//IIC发送ACK信号voidIIC_NAck(void);//IIC不发送ACK信号voidIIC_Write_One_Byte(u8 daddr,u8 addr,u8 data);u8IIC_Read_One_Byte(u8 daddr,u8 addr);#endif#include24cxx.h#includedelay.h//初始化IIC接口voidAT24CXX_Init(void){IIC_Init();}//在AT24CXX指定地址读出一个数据//ReadAddr:开始读数的地址//返回值 :读到的数据u8AT24CXX_ReadOneByte(u16 ReadAddr){u8 temp0;IIC_Start();if(EE_TYPEAT24C16){IIC_Send_Byte(0XA0);//发送写命令IIC_Wait_Ack();IIC_Send_Byte(ReadAddr8);//发送高地址IIC_Wait_Ack();}elseIIC_Send_Byte(0XA0((ReadAddr/256)1));//发送器件地址0XA0,写数据IIC_Wait_Ack();IIC_Send_Byte(ReadAddr%256);//发送低地址IIC_Wait_Ack();IIC_Start();IIC_Send_Byte(0XA1);//进入接收模式IIC_Wait_Ack();tempIIC_Read_Byte(0);IIC_Stop();//产生一个停止条件returntemp;}//在AT24CXX指定地址写入一个数据//WriteAddr :写入数据的目的地址//DataToWrite:要写入的数据voidAT24CXX_WriteOneByte(u16 WriteAddr,u8 DataToWrite){IIC_Start();if(EE_TYPEAT24C16){IIC_Send_Byte(0XA0);//发送写命令IIC_Wait_Ack();IIC_Send_Byte(WriteAddr8);//发送高地址}else{IIC_Send_Byte(0XA0((WriteAddr/256)1));//发送器件地址0XA0,写数据}IIC_Wait_Ack();IIC_Send_Byte(WriteAddr%256);//发送低地址IIC_Wait_Ack();IIC_Send_Byte(DataToWrite);//发送字节IIC_Wait_Ack();IIC_Stop();//产生一个停止条件delay_ms(10);}//在AT24CXX里面的指定地址开始写入长度为Len的数据//该函数用于写入16bit或者32bit的数据.//WriteAddr :开始写入的地址//DataToWrite:数据数组首地址//Len :要写入数据的长度2,4voidAT24CXX_WriteLenByte(u16 WriteAddr,u32 DataToWrite,u8 Len){u8 t;for(t0;tLen;t){AT24CXX_WriteOneByte(WriteAddrt,(DataToWrite(8*t))0xff);}}//在AT24CXX里面的指定地址开始读出长度为Len的数据//该函数用于读出16bit或者32bit的数据.//ReadAddr :开始读出的地址//返回值 :数据//Len :要读出数据的长度2,4u32AT24CXX_ReadLenByte(u16 ReadAddr,u8 Len){u8 t;u32 temp0;for(t0;tLen;t){temp8;tempAT24CXX_ReadOneByte(ReadAddrLen-t-1);}returntemp;}//检查AT24CXX是否正常//这里用了24XX的最后一个地址(255)来存储标志字.//如果用其他24C系列,这个地址要修改//返回1:检测失败//返回0:检测成功u8AT24CXX_Check(void){u8 temp;tempAT24CXX_ReadOneByte(255);//避免每次开机都写AT24CXXif(temp0X55)return0;else//排除第一次初始化的情况{AT24CXX_WriteOneByte(255,0X55);tempAT24CXX_ReadOneByte(255);if(temp0X55)return0;}return1;}//在AT24CXX里面的指定地址开始读出指定个数的数据//ReadAddr :开始读出的地址 对24c02为0~255//pBuffer :数据数组首地址//NumToRead:要读出数据的个数voidAT24CXX_Read(u16 ReadAddr,u8*pBuffer,u16 NumToRead){while(NumToRead){*pBufferAT24CXX_ReadOneByte(ReadAddr);NumToRead--;}}//在AT24CXX里面的指定地址开始写入指定个数的数据//WriteAddr :开始写入的地址 对24c02为0~255//pBuffer :数据数组首地址//NumToWrite:要写入数据的个数voidAT24CXX_Write(u16 WriteAddr,u8*pBuffer,u16 NumToWrite){while(NumToWrite--){AT24CXX_WriteOneByte(WriteAddr,*pBuffer);WriteAddr;pBuffer;}}#ifndef__24CXX_H#define__24CXX_H#includemyiic.h#defineAT24C01127#defineAT24C02255#defineAT24C04511#defineAT24C081023#defineAT24C162047#defineAT24C324095#defineAT24C648191#defineAT24C12816383#defineAT24C25632767//Mini STM32开发板使用的是24c02所以定义EE_TYPE为AT24C02#defineEE_TYPEAT24C02u8AT24CXX_ReadOneByte(u16 ReadAddr);//指定地址读取一个字节voidAT24CXX_WriteOneByte(u16 WriteAddr,u8 DataToWrite);//指定地址写入一个字节voidAT24CXX_WriteLenByte(u16 WriteAddr,u32 DataToWrite,u8 Len);//指定地址开始写入指定长度的数据u32AT24CXX_ReadLenByte(u16 ReadAddr,u8 Len);//指定地址开始读取指定长度数据voidAT24CXX_Write(u16 WriteAddr,u8*pBuffer,u16 NumToWrite);//从指定地址开始写入指定长度的数据voidAT24CXX_Read(u16 ReadAddr,u8*pBuffer,u16 NumToRead);//从指定地址开始读出指定长度的数据u8AT24CXX_Check(void);//检查器件voidAT24CXX_Init(void);//初始化IIC#endif