I2C之IO模拟方式-记录

//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;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值