day49-硬件学习之I2C(续)

发布于:2025-06-28 ⋅ 阅读:(20) ⋅ 点赞:(0)

一、I2C(续)

1.1 I2C寄存器

I2C_IADR 地址寄存器(作为从机使用)
I2C_IFDR 频率分频寄存器
I2C_I2CR 控制寄存器
I2C_I2SR 状态寄存器
I2C_I2DR 数据寄存器

1.2 代码编写

初始化:

void init_i2c_io(I2C_Type *base)
{
    if(base == I2C1)
    {
        IOMUXC_SetPinMux(IOMUXC_UART4_RX_DATA_I2C1_SDA, 1);
        IOMUXC_SetPinMux(IOMUXC_UART4_TX_DATA_I2C1_SCL, 1);

        IOMUXC_SetPinConfig(IOMUXC_UART4_RX_DATA_I2C1_SDA, 0x70B0);
        IOMUXC_SetPinConfig(IOMUXC_UART4_TX_DATA_I2C1_SCL, 0x70B0);
    }
}

void init_i2c(I2C_Type *base)
{
    init_i2c_io(base);
    if(base == I2C1)
    {
        base->I2CR &= ~(1 << 7);
        base->IFDR = 0x15;
        base->I2CR |= (1 << 7);
    }
}

写操作 : 

void i2c_write(I2C_Type *base, unsigned char dev_addr, unsigned char reg_addr, unsigned char *data, unsigned int len)
{
    base->I2SR &= ~((1 << IAL) | (1 << IIF));
    while((base->I2SR & (1 << ICF)) == 0);

    base->I2CR |= (1 << MSTA) | (1 << MTX);
    base->I2CR &= ~(1 << TXAK);

    base->I2SR &= ~(1 << IIF);
    base->I2DR = dev_addr << 1;
    while((base->I2SR & (1 << IIF)) == 0);
    
    base->I2SR &= ~(1 << IIF);
    base->I2DR = reg_addr;
    while((base->I2SR & (1 << IIF)) == 0);
    
    while(len--)
    {
        base->I2SR &= ~(1 << IIF);
        base->I2DR = *data++;
        while((base->I2SR & (1 << IIF)) == 0);
    }

    base->I2CR &= ~(1 << 5);
    while((base->I2SR & (1 << IBB)) != 0)
    {
        delay_us(100);
    }
}

 读操作:

void i2c_read(I2C_Type *base,  unsigned char dev_addr, unsigned char reg_addr, unsigned char *data, unsigned int len)
{
    base->I2SR &= ~((1 << IAL) | (1 << IIF));
    while((base->I2SR & (1 << ICF)) == 0);

    base->I2CR |= (1 << MSTA) | (1 << MTX);
    base->I2CR &= ~(1 << TXAK);

    base->I2SR &= ~(1 << IIF);
    base->I2DR = dev_addr << 1;
    while((base->I2SR & (1 << IIF)) == 0);
    
    base->I2SR &= ~(1 << IIF);
    base->I2DR = reg_addr;
    while((base->I2SR & (1 << IIF)) == 0);
    
    base->I2CR |= (1 << RSTA);
    base->I2SR &= ~(1 << IIF);
    base->I2DR = (dev_addr << 1 ) | 1;
    while((base->I2SR & (1 << IIF)) == 0);

    base->I2CR &= ~(1 << MTX);
    base->I2SR &= ~(1 << IIF);
    if(1 == len)
    {
        base->I2CR |= (1 << TXAK);
    }

    *data = base->I2DR;
    while(len--)
    {
        while((base->I2SR & (1 << IIF)) == 0);
        base->I2SR &= ~(1 << IIF);
        if(1 == len)
        {
            base->I2CR |= (1 << TXAK);
        }
        else if(0 == len)
        {
            unsigned int t;
            base->I2CR &= ~((1 << MSTA) | (1 << TXAK));
            while(((base->I2SR & (1 << IBB)) != 0) && t < 10)
            {
                t++;
                delay_us(100);
            }
        }

        *data++ = base->I2DR;
    }
}

想要实现浮点型运算,需打开相应的FPU。


网站公告

今日签到

点亮在社区的每一天
去签到