固件说明
I2C接口初始化
一旦使能I2C模块,SCL和SDA必须配置成漏极开路状态,以确保I2C总线通信正常。由于I2C是GPIO端口的一个替代功能,固件必须确保SCL和SDA输入在初始化期间禁止上拉(通过对端口控制器的输出位写零实现)。
示例中,时钟频率为250kHz。首先需要配置MAX2990的I2C接口: PO1_bit.Bit2 = 0; // Disables the GPIO function of the
PO1_bit.Bit3 = 0; // I2C pins
I2CCN_bit.I2CEN = 0; // Makes sure that I2C is disabled
// to allow the changing of the I2C settings
I2CCN_bit.I2CMST = 1; // Sets the I2C engine to master mode
I2CCN_bit.I2CEA = 0; // 7-bit address mode
I2CCK_bit.I2CCKL = 0x40; // 2μs CLK-low, to define I2C frequency
I2CCK_bit.I2CCKH = 0x40; // 2μs CLK-high, to define I2C frequency
读模式
读取我们写入EEPROM的数据时,为24C04留出足够的写时间非常关键。通常在“停止条件”后留出几个毫秒的时间,请参考数据资料,确认您的时间设置符合IC的要求。 i2c_init_write(); // Sets the MAX2990 I2C engine into write mode
i2c_write(0x50); // 24C04 write (adr = 0b1010 000 0) = 0xA0
// The MAX2990 I2C engine shifts the I2C address by
// 1 bit, because it will generate the R/W bit
// automatically
i2c_write(0x00); // word address location
i2c_init_read(); // Sets the MAX2990 I2C engine into read mode
i2c_write(0x50); // 24C04 read (adr = 0b1010 000 1) = 0xA1
// The MAX2990 I2C engine shifts the I2C address by
// 1 bit, because it will generate the R/W bit
// automatically
unsigned char data[5]; // Array to store the received data
i2c_read(data[0]); // Reads 1 byte from I2C and writes it to the array
i2c_read(data[1]); // Reads 1 byte from I2C and writes it to the array
i2c_read(data[2]); // Reads 1 byte from I2C and writes it to the array
i2c_read(data[3]); // Reads 1 byte from I2C and writes it to the array
i2c_read(data[4]); // Reads 1 byte from I2C and writes it to the array
I2C_STOP; // Sends I2C stop-condition
void i2c_init_write(void)
{
I2CCN_bit.I2CMODE = 0; // I2C transmit mode
I2CCN_bit.I2CACK = 1; // Creates I2C NACK so that slave can create ACK
I2C_START; // Generates I2C START condition
while( I2CCN_bit.I2CSTART == 1 ); // Waits until the START condition
// was put to the I2C bus
I2CST_bit.I2CSRI = 0; // Resets the I2C interrupt flag
}
while( I2CCN_bit.I2CSTART == 1 ); // Waits until the START condition
I2CST_bit.I2CSRI = 0; // Resets the I2C interrupt flag
}
void i2c_write(UINT8 data)
{
I2CBUF = data; // Puts the data on the I2C bus
while( I2CST_bit.I2CTXI == 0 ); // Waits for transfer complete
I2CST_bit.I2CTXI = 0; // Resets the I2C transmit complete
// interrupt flag
}
void i2c_read(UINT8 *data)
{
I2CBUF = 0xff; // Puts "all ones" on the I2C bus so that slave can pull
// the bus down to generate zeros
while( !I2CST_bit.I2CRXI ); // Waits for receive complete
I2CST_bit.I2CRXI=0; // Resets the I2C receive complete
// interrupt flag
*data = I2CBUF; // Writes the data to the pointer
}