//IIC地址
#define EEPROM_SLAVE_ADDR 0xa0
//每页大小
#define EEPROM_PAGE_SIZE 32
//设置SCL和SDA输出电平
#define READ_SDA //补充读SDA电平接口函数
#define IIC_SCL(n) //设置SCL电平接口函数
#define IIC_SDA(n) //设置SDA电平接口函数
void I2c_init(void); //设置I2C的SDA和SCL的引脚初始化,设置为高电平
uint8_t I2c_eepBufWrite(uint16_t eepAddr,uint8_t *pData, uint32_t len);
uint8_t I2c eepBufRead(uint16 eepAddr,uint8_t *pData,uint32_t len);
uint8_t I2c_memWrite(uint8_t addr,uint16_t reg_addr,uint8_t *buf,uint16_t size);
uint8 I2c_memRead(uint8_t addr,uint16_t reg addr,uint8_t *rbuf, uint16_t rsize);
void SDA_IN(void); //补充设置SDA方向为输入, 根据芯片设置此接口
void sDA_OUT(void); //补充设置SDA方向为输出, 根据芯片设置此接口
void IIc_start(void);
void IIC_Ack(void);
void IIC_NAck(void);
uint8_t IIc_Wait_Ack(void);
void IIc_stop(void);
void IIc_send_Byte(uint8_t txd);
uint8_t IIc_Read_Byte(uint8_t ack);
void IIc start(void)
{
SDA_OUT();
IIC_SDA(1);
IIC_SCL(1);
delayus(1);
IIC SDA(0),
delayus(1);
IIC_SCL(0);
delayus(1);
}
void IIc stop(void)
{
SDA_OUT();
IIC_SCL(0);
IIC SDA(0);
delayus(2);
IIC SCL(1);
delayus(2);
IIC_SDA(1);
delayus(2);
}
uint8_t IIc_Wait_Ack(void)
{
uint8_t Time =0;
IIC_SDA(1);
SDA_IN();
delayus(1);
IIC_SCL(1);
delayus(1);
while(READ_SDA)
{
Time ++;
if(Time >250)
{
IIC_stop();
return 1;
}
}
IIC_SCL(0);
delayus(2);
return 0;
}
void IIC Ack(void)
{
IIC_SDA(0);
SDA_OUT();
IIC_SCL(0);
delayus(1);
IIC_SDA(0);
delayUs(1);
IIC SCL(1);
delayus(2);
IIC SCL(0);
delayUs(1);
}
void IIC NAck(void)
{
IIC SDA(0);
SDA OUT();
IIC_SCL(8);
delayus(2);
IIC_SDA(1);
delayus(2);
IIC_SCL(1);
delayus(2);
IIC_SCL(0);
delayus(1);
}
void IIc_send_Byte(c uint8 txd)
{
uint8_t t;
SDA OUT();
IIC SCL(0);
for(t = ;t< 8; t++)
{
IIC SDA((txd&0x80)>>7);
txd <<= 1;
delayus(1);
IIC_SCL(1);
delayus(2);
IIC_SCL(0);
delayus(1);
}
}
uint8_t IIC_Read_Byte(c uint8 ack)
{
uint8_t i,receive = 0;
SDA_IN();
for(i=0;i< 8;i++ )
{
IIC SCL(1);
delayus(2);
receive<<=·1;
if(READ SDA)receive++;
IIC SCL(0);
delayus(2);
}
if (!ack)
IIC_NAck();
else
IIC_Ack();
return receive;
}
uint8_t I2C_memWrite(uint8_t addr,uint16_t reg_addr,uint8_t *buf,uint16_t size)
{
vPortEnterCritical();
IIC_start();
IIC_Send_Byte(addr);
IIC_Wait_Ack();
IIC_Send_Byte(reg_addr>>8);
Wait_Ack();
IIC_Send_Byte(reg_addr%256);
IIC_Wait_Ack();
for(cuint32i=0;i<size; i++)
{
IIc Send Byte( buf[i] );
IIC Wait Ack();
}
IIC stop();
delayus(2);
vPortExitCritical();
delayms(5);
return 0;
}
uint8_t I2c_memRead(uint8_t addr,uint16_t reg_addr,uint8_t *rbuf,uint16_t rsize)
{
vPortEnterCritical();
IIC_start();
IIc_Send_Byte(addr);
IIC_Wait_Ack();
IIC_Send_Byte(reg_addr >>8);
IIC Wait Ack();
IIC_Send_Byte(reg_addr % 256);
IIC Wait Ack();
IIC start();
IIC Send Byte(addr | 1 );
IIC Wait Ack();
for(uint32_t i=0;i<(rsize-1);i++·)
{
rbuf[i]= IIC Read Byte(1);
}
rbuf[rsize -1]= IIC_Read_Byte(0);
IIC stop();
vPortExitCritical();
return·0;
}
uint8_t I2c_eepBufRead(uint16_t eepAddr,uint8_t *pData,uint32_t len)
{
uint8_t ret=0;
ret = I2C_memRead(EEPROM_SLAVE_ADDR, eepAddr,pData, len);
delayms(5)
return ret;
}
uint8_t I2c_eepBufWrite(uint16_t eepAddr,uint8_t *pData, uint32_t len)
{
uint8_t NumOfPage= 0;
uint8_t Numofsingle=0;
uint8_t Addr.=0;
uint8_t count = 0;
uint32_t ret=0;
Addr = eepAddr % SOFT EEPROM PAGE SIZE;
count=EEPROM_PAGE_SIZE – Addr; //差count个数据对齐到页地址
NumOfPage =len / EEPROM_PAGE_SIZE;//页数
Numofsingle = len % EEPROM_PAGE_SIZE;//剩余不满一页字节数
/*eeprom寄存器地址是否与page对齐*/
if(Addr== 0)
{
//len不满一页
if(NumOfPage== 0)
{
ret = I2C_memWrite(SOFT EEPROM SLAVE ADDR,eepAddr,pData,Numofsingle);
}
else
{
while(NumOfPage--)
{
ret = I2C_memWrite(EEPROM_SLAVE_ADDR,eepAddr, pData, EEPROM_PAGE_SIZE);
eepAddr+= EEPROM PAGE_SIZE;
pData +=EEPROM_PAGE_SIZE;
}
if(Numofsingle !=0)
{
ret = I2C_memNrite(EEPROM_SLAVE_ADDR, eepAddr, pData, Numofsingle);
}
}
}
else
{
if (NumOfPage ==0)
{
ret= I2c_memWrite(EEPROM_SLAVE_ADDR,eepAddr, pData, Numofsingle);
}
else
{
len -= count;
NumOfPage = len / EEPROM_PAGE_SIZE;
NumOfsingle = len % EEPROM_PAGE_SIZE;
if(count !=0)
{
ret = I2C_memNrite(EEPROM_SLAVE_ADDR,eepAddr, pData, count);
eepAddr+= count;
pData+= count;
}
while(NumOfPage--)
{
ret = I2C_memNrite(EEPROM_SLAVE_ADDR,eepAddr, pData,EEPROM_PAGE_SIZE);
eepAddr += SOFT EEPROM PAGE SIZE;
pData+=SOFT EEPROM PAGE SIZE;
}
if(Numofsingle !=0)
{
ret = I2c_memWrite(EEPROM_SLAVE_ADDR,eepAddr, pData, Numofsingle);
}
}
}
return ret;
}
I2C之IO模拟方式-记录
于 2024-07-14 15:43:43 首次发布