Я застрял на проблеме связи I2C, и мне нужна ваша помощь
В настоящее время я использую микроконтроллер (MCU) C8051F130 .Мне нужно связаться между MCU и датчиком через I2C.
Как я знаю, I2C на этом MCU может быть включен битом ENSMB в регистре SMB0CN ,Но когда я устанавливаю этот бит в 1 и проверяю состояние SMB0CN в режиме отладки IDE, я всегда вижу его SMB0CN = 0x00.Это означает, что I2C все еще не включен.В результате сигналы I2C SDA & SCL на выходе MCU всегда имеют высокий статус .
Я также проверил подтягивающий резистор на портах MCA SDA и SCL, они подключены к резистору 10 кОм .Я думаю, что все должно быть в порядке.
Вот мой код для настройки регистра I2C и отправки / получения / подтверждения.Пожалуйста, дайте мне предложение.
#define SMB0_PAGE 0x00 /* SMBUS 0 */
void main()
{
SMBUS_Initial();
}
// I2C SFR setting
void SMBUS_Initial()
{
unsigned char SFRPAGE_BUF; // SFR page of SMB0CN is 0
SFRPAGE_BUF = SFRPAGE;
SFRPAGE = SMB0_PAGE;
/*
BUSY = 0;
// AA = 1;
STA = 1;
STO = 1;*/
ENSMB = 1;
SFRPAGE = SFRPAGE_BUF;
}
sfr SMB0CN = 0xC0; /* SMBUS 0 CONTROL */
/* SMB0CN 0xC0 */
sbit BUSY = SMB0CN ^ 7; // SMBUS 0 BUSY
sbit ENSMB = SMB0CN ^ 6; // SMBUS 0 ENABLE
sbit STA = SMB0CN ^ 5; // SMBUS 0 START FLAG
sbit STO = SMB0CN ^ 4; // SMBUS 0 STOP FLAG
sbit SI = SMB0CN ^ 3; // SMBUS 0 INTERRUPT PENDING FLAG
sbit AA = SMB0CN ^ 2; // SMBUS 0 ASSERT/ACKNOWLEDGE FLAG
sbit SMBFTE = SMB0CN ^ 1; // SMBUS 0 FREE TIMER ENABLE
sbit SMBTOE = SMB0CN ^ 0;
// I2C communication
void I2C_START()
{
unsigned char SFRPAGE_BUF;
SFRPAGE_BUF = SFRPAGE;
SFRPAGE = CONFIG_PAGE;
Delay2us(6);
I2C_SDA = 1;
Delay2us(2);
I2C_SCL = 1;
Delay2us(8);
I2C_SDA = 0;
Delay2us(5);
I2C_SCL = 0;
Delay2us(5);
SFRPAGE = SFRPAGE_BUF;
}
//=======================================================================================
// I2C_1 Ack by slave
//=======================================================================================
void I2C_ACK(void)
{
unsigned char SFRPAGE_BUF;
SFRPAGE_BUF = SFRPAGE;
SFRPAGE = CONFIG_PAGE;
Delay2us(3);
I2C_SDA = 1;
Delay2us(1);
I2C_SCL = 1;
Delay2us(3);
if(!I2C_SDA)
// ACK_f = 1;
Delay2us(2);
I2C_SCL = 0;
Delay2us(1);
I2C_SDA = 0;
Delay2us(5);
SFRPAGE = SFRPAGE_BUF;
}
// I2C_1 Ack by master
//=======================================================================================
void I2C_ACK_master()
{
unsigned char SFRPAGE_BUF;
SFRPAGE_BUF = SFRPAGE;
SFRPAGE = CONFIG_PAGE;
I2C_SDA = 0;
I2C_SCL = 1;
Delay2us(1);
I2C_SCL = 0;
I2C_SDA = 1;
SFRPAGE = SFRPAGE_BUF;
}
void I2C_NAK()
{
unsigned char SFRPAGE_BUF;
SFRPAGE_BUF = SFRPAGE;
SFRPAGE = CONFIG_PAGE;
I2C_SDA = 1;
I2C_SCL = 1;
Delay2us(1);
I2C_SCL = 0;
I2C_SDA = 1;
SFRPAGE = SFRPAGE_BUF;
}
//=======================================================================================
// I2C Start
//=======================================================================================
//=======================================================================================
// I2C Stop
//=======================================================================================
void I2C_STOP(void)
{
unsigned char SFRPAGE_BUF;
SFRPAGE_BUF = SFRPAGE;
SFRPAGE = CONFIG_PAGE;
I2C_SCL = 0;
I2C_SDA = 0;
Delay2us(8);
I2C_SCL = 1;
Delay2us(5);
I2C_SDA = 1;
SFRPAGE = SFRPAGE_BUF;
}
// I2C Tx
//=======================================================================================
void I2C_TX(unsigned char Tx_data)
{
unsigned char x;
unsigned char SFRPAGE_BUF;
SFRPAGE_BUF = SFRPAGE;
SFRPAGE = CONFIG_PAGE;
for(x=0;x<8;x++)
{
I2C_SCL = 0;
Delay2us(1);
if(Tx_data & 0x80)
I2C_SDA = 1;
else
I2C_SDA = 0;
Tx_data <<= 1;
Delay2us(1);
I2C_SCL = 1;
Delay2us(2);
}
I2C_SCL = 0;
SFRPAGE = SFRPAGE_BUF;
}
//=======================================================================================
// I2C Rx
//=======================================================================================
unsigned char I2C_RX(unsigned char I2C_ACK)
{
unsigned char x;
unsigned char Rx_Data, I2C_rx_buf;
unsigned char SFRPAGE_BUF;
SFRPAGE_BUF = SFRPAGE;
SFRPAGE = CONFIG_PAGE;
I2C_SDA = 1;
// Delay2us(10);
Delay2us(2);
for(x=0;x<8;x++)
{
I2C_rx_buf <<= 1;
do{
I2C_SCL = 1;
}while(I2C_SCL == 0);
Delay2us(1);
if(I2C_SDA)
I2C_rx_buf |= 1;
I2C_SCL = 0;
}
if(I2C_ACK)
I2C_SDA = 0;
else
I2C_SDA = 1;
Delay2us(2);
I2C_SCL = 0;
I2C_SDA = 1;
return I2C_ACK;
SFRPAGE = SFRPAGE_BUF;
}
///// Configuration register ///////////
void ALS_config(unsigned char slave_write,unsigned char dataA,unsigned char dataB)
{
I2C_START();
I2C_TX(slave_write);
I2C_ACK();
I2C_TX(0x01);
I2C_ACK();
I2C_TX(dataA);
// I2C_RX();
I2C_ACK();
I2C_TX(dataB);
// I2C_RX();
I2C_ACK();
I2C_STOP();
}
unsigned int MCU_read(unsigned char slave_write,unsigned char slave_read)
{
unsigned char i, ALS_MSB, ALS_LSB, DSI_val[52];
unsigned int ALS_lux;
// High-speed I2C ////
I2C_START();
I2C_TX(0x08);
I2C_NAK();
/////////////////
////// Partial write ////////
I2C_START();
I2C_TX(slave_write);
I2C_ACK();
I2C_TX(0x00);
I2C_ACK();
I2C_STOP();
delay1m(1);
//////////////// Read from ALS /////////////////////////////
I2C_START();
I2C_TX(slave_read);
I2C_ACK();
I2C_RX(I2C_ACK);
I2C_ACK_master();
ALS_MSB = I2C_rx_buf;
// ALS_MSB = ALS_MSB&0x0F;
// ALS_MSB = I2C_rx_buf<<8;
delay1m(3);
I2C_RX(I2C_ACK);
I2C_ACK_master();
I2C_NAK();
ALS_LSB = I2C_rx_buf;
I2C_STOP();
ALS_lux = ALS_MSB | ALS_LSB;
return ALS_lux;
}
void low_limit_ALS(unsigned char slave_write,unsigned char low_limit_MSB,unsigned char low_limit_LSB)
{
I2C_START();
I2C_TX(slave_write);
I2C_ACK();
I2C_TX(0x02);
I2C_ACK();
I2C_TX(low_limit_MSB);
// I2C_RX();
I2C_ACK();
I2C_TX(low_limit_LSB);
// I2C_RX();
I2C_ACK();
I2C_STOP();
}
void high_limit_ALS(unsigned char slave_write,unsigned char high_limit_MSB,unsigned char high_limit_LSB)
{
I2C_START();
I2C_TX(slave_write);
I2C_ACK();
I2C_TX(0x03);
I2C_ACK();
I2C_TX(high_limit_MSB);
// I2C_RX();
I2C_ACK();
I2C_TX(high_limit_LSB);
// I2C_RX();
I2C_ACK();
I2C_STOP();
}