day49-硬件学习之I2C(续)
一、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。