我遇到了I2C通信问题,我需要你的帮助
目前,我正在使用微控制器(MCU) C8051F130 。我需要通过I2C在MCU和传感器之间进行通信。
据我所知,该MCU上的I2C可以通过寄存器 SMB0CN 中的 ENSMB 位启用。但是当我将该位设置为1并在IDE调试模式下检查SMB0CN状态时,我看到它总是SMB0CN = 0x00。这意味着仍未启用I2C。结果, I2C SDA& MCU输出上的SCL信号始终为高电平状态。
我还检查了SDA&上的上拉电阻。 SCL MCU端口,它们连接到电阻10KOhm 。我认为应该没事。
这是我的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();
}