bbhhvlgp 发表于 2026-3-21 14:05:32

STC32G128K硬件I2C输出波形异常

我用的MCU(STC32G12K128)的I2C模块,当SDA输出start信号(拉低)后,会有一个拉高的时间,然后在拉低。导致与IC通讯不上,不知道是什么原因

代码如下
#include"I2C.h"
#include <intrins.h>

#define SOFT_I2C_SCL    P25   
#define SOFT_I2C_SDA    P24   

u8 const CRC8Table[]=
{                                                       
        0x00,0x07,0x0E,0x09,0x1C,0x1B,0x12,0x15,0x38,0x3F,0x36,0x31,0x24,0x23,0x2A,0x2D,
        0x70,0x77,0x7E,0x79,0x6C,0x6B,0x62,0x65,0x48,0x4F,0x46,0x41,0x54,0x53,0x5A,0x5D,
        0xE0,0xE7,0xEE,0xE9,0xFC,0xFB,0xF2,0xF5,0xD8,0xDF,0xD6,0xD1,0xC4,0xC3,0xCA,0xCD,
        0x90,0x97,0x9E,0x99,0x8C,0x8B,0x82,0x85,0xA8,0xAF,0xA6,0xA1,0xB4,0xB3,0xBA,0xBD,
        0xC7,0xC0,0xC9,0xCE,0xDB,0xDC,0xD5,0xD2,0xFF,0xF8,0xF1,0xF6,0xE3,0xE4,0xED,0xEA,
        0xB7,0xB0,0xB9,0xBE,0xAB,0xAC,0xA5,0xA2,0x8F,0x88,0x81,0x86,0x93,0x94,0x9D,0x9A,
        0x27,0x20,0x29,0x2E,0x3B,0x3C,0x35,0x32,0x1F,0x18,0x11,0x16,0x03,0x04,0x0D,0x0A,
        0x57,0x50,0x59,0x5E,0x4B,0x4C,0x45,0x42,0x6F,0x68,0x61,0x66,0x73,0x74,0x7D,0x7A,
        0x89,0x8E,0x87,0x80,0x95,0x92,0x9B,0x9C,0xB1,0xB6,0xBF,0xB8,0xAD,0xAA,0xA3,0xA4,
        0xF9,0xFE,0xF7,0xF0,0xE5,0xE2,0xEB,0xEC,0xC1,0xC6,0xCF,0xC8,0xDD,0xDA,0xD3,0xD4,
        0x69,0x6E,0x67,0x60,0x75,0x72,0x7B,0x7C,0x51,0x56,0x5F,0x58,0x4D,0x4A,0x43,0x44,
        0x19,0x1E,0x17,0x10,0x05,0x02,0x0B,0x0C,0x21,0x26,0x2F,0x28,0x3D,0x3A,0x33,0x34,
        0x4E,0x49,0x40,0x47,0x52,0x55,0x5C,0x5B,0x76,0x71,0x78,0x7F,0x6A,0x6D,0x64,0x63,
        0x3E,0x39,0x30,0x37,0x22,0x25,0x2C,0x2B,0x06,0x01,0x08,0x0F,0x1A,0x1D,0x14,0x13,
        0xAE,0xA9,0xA0,0xA7,0xB2,0xB5,0xBC,0xBB,0x96,0x91,0x98,0x9F,0x8A,0x8D,0x84,0x83,
        0xDE,0xD9,0xD0,0xD7,0xC2,0xC5,0xCC,0xCB,0xE6,0xE1,0xE8,0xEF,0xFA,0xFD,0xF4,0xF3
};

u16I2C_StateFlowUW;
u8   I2C_DeviceAdrrUB;
u8   I2C_DeviceRegAddrUB;
u8   I2C_DeviceRegDtUB;
u8   I2C_crcResUB;
u16I2C_DeviceDtRtUW;
u8   I2C_hdAckUB;
u8   I2C_stWrkStUB;

I2C_wtFifo_S   I2C_wtDeviceBuf;
I2C_rdFifo_S   I2C_deviceBackBuf;

voidI2C_EnterLowPowerMode(void)
{
// stop all I2C communication
for(;;)
{
    I2C_Update();
   
}

}

voidI2C_RecoveryFromLowPowerMode(void)
{

}

/*******************************************************************************
Function: CRC8cal()
Description:
Input:
Output:
********************************************************************************/
u8 CRC8cal(u8 *p, u8 counter)                       //look-up table calculte CRC
{   
u8 crc8 = 0;   
   
        for( ; counter > 0; counter--)
        {
                crc8 = CRC8Table;   
          p++;   
}   
return (crc8);   
}   

/*******************************************************************************
Function: I2C_Init()
Description:
Input:
Output:
********************************************************************************/
void   I2C_Init(void)
{
        P2M0 &= 0xCF;
        P2M1 &= 0xCF;
    P2PU |= 0x30;
        P_SW2 |= 0x90; // i2c mirror to P3.2 P3.3; extern ram aera allow
        I2CCFG = 0xdc;// ENABLE I2C; MASTER MODE; 200K RATE
        I2CMSAUX = 0;   // DISABLE MASTER MODE AUTO SEND ACK
        I2CMSST = 0;
        I2C_StateFlowUW = 0;
I2C_wtDeviceBuf.wP = 0;
I2C_wtDeviceBuf.rP = 0;
I2C_deviceBackBuf.wP = 0;
I2C_deviceBackBuf.rP = 0;
I2CMSCR = 0;
}

/*******************************************************************************
//
********************************************************************************/
voidI2C_SetSlaveAddr(u8 addrUB)
{
I2C_DeviceAdrrUB = addrUB;
}

/*******************************************************************************
//
********************************************************************************/
voidI2C_SendData(u8datUB)
{
        I2CTXD = datUB;
        I2CMSCR = 0x2;
for(;;)
{
    if((I2CMSST & 0x40 ) == 0x40)
    {
      I2CMSST &= ~0x40;
      break;
    }
}
}
/*******************************************************************************
//
********************************************************************************/
voidI2C_StartProc(void)
{
        I2CMSCR = 0x1;
for(;;)
{
    if((I2CMSST & 0x40 ) == 0x40)
    {
      I2CMSST &= ~0x40;
      break;
    }
}
}

/*******************************************************************************
//
********************************************************************************/
voidI2C_ReadAck(void)
{
        I2CMSCR = 0x3;
for(;;)
{
    if((I2CMSST & 0x40 ) == 0x40)
    {
      I2CMSST &= ~0x40;
      break;
    }
}
}

/*******************************************************************************
//
********************************************************************************/
voidI2C_RecvData(void)
{
        I2CMSCR = 0x4;
for(;;)
{
    if((I2CMSST & 0x40 ) == 0x40)
    {
      I2CMSST &= ~0x40;
      break;
    }
}
}

/*******************************************************************************
//
********************************************************************************/
voidI2C_SendAck(u8 ackBool)
{
        if(ackBool == 1)
        {
                I2CMSST |= 1;
        }
        else
        {
                I2CMSST &= 0xfe;
        }
       
        I2CMSCR = 0x5;
for(;;)
{
    if((I2CMSST & 0x40 ) == 0x40)
    {
      I2CMSST &= ~0x40;
      break;
    }
}
}

/*******************************************************************************
//
********************************************************************************/
voidI2C_SendStop(void)
{
        I2CMSCR = 0x6;
for(;;)
{
    if((I2CMSST & 0x40 ) == 0x40)
    {
      I2CMSST &= ~0x40;
      break;
    }
}
}

/*******************************************************************************
// write data to slave device
********************************************************************************/
voidI2C_WriteDeviceBuf(u8 regAddr, u8 dtUB , u8 rdOrWt)
{
u8 idxWtUB;

if((I2C_wtDeviceBuf.wP + 1)%_I2C_WRITE_BUF_SIZE_ != I2C_wtDeviceBuf.rP)
        {
                idxWtUB = I2C_wtDeviceBuf.wP;
    I2C_wtDeviceBuf.addrUB = regAddr;
    I2C_wtDeviceBuf.dtUB = dtUB;
    I2C_wtDeviceBuf.rwflg = rdOrWt;
                I2C_wtDeviceBuf.wP= (u8)((I2C_wtDeviceBuf.wP+ 1)%_I2C_WRITE_BUF_SIZE_);
        }
}

/*******************************************************************************
//
********************************************************************************/
voidI2C_WriteDeviceBack(u8 regAddr , u16 back)
{
u8 idxWtUB;

if((I2C_deviceBackBuf.wP + 1)%_I2C_READ_BUF_SIZE_ != I2C_deviceBackBuf.rP)
        {
                idxWtUB = I2C_deviceBackBuf.wP;
    I2C_deviceBackBuf.addrUB = regAddr;
    I2C_deviceBackBuf.dtUW = back;
                I2C_deviceBackBuf.wP= (u8)((I2C_deviceBackBuf.wP+ 1)%_I2C_READ_BUF_SIZE_);
        }
}

/*******************************************************************************
//
********************************************************************************/
u16I2C_ReadDeviceBackBuf(u8* regAddr)
{
u16 retUW;

if(I2C_deviceBackBuf.wP != I2C_deviceBackBuf.rP)
{
    *regAddr = I2C_deviceBackBuf.addrUB;
    retUW = I2C_deviceBackBuf.dtUW;
    I2C_deviceBackBuf.rP = (u8)((I2C_deviceBackBuf.rP + 1)%_I2C_READ_BUF_SIZE_);
}
else
{
    *regAddr = 0xff;
    retUW = 0xffff;
}
returnretUW;
}

/*******************************************************************************
//
********************************************************************************/
voidI2C_Update(void)
{
static u8 TempBuf;
u8 rdBuf , crcBack ;

if((I2C_wtDeviceBuf.wP != I2C_wtDeviceBuf.rP)&&(I2C_StateFlowUW == 0)&&((I2CMSST & 0x80 ) == 0))
{
    rdBuf = I2C_wtDeviceBuf.rP;
    I2C_DeviceRegAddrUB = I2C_wtDeviceBuf.addrUB;
    I2C_DeviceRegDtUB = I2C_wtDeviceBuf.dtUB;
   
    // write 4 byte ( I2C_DeviceAdrrUB , I2C_DeviceRegAddrUB , I2C_DeviceRegDtUB , I2C_crcResUB ) to
    // slave device -- SH367306
    TempBuf = I2C_DeviceAdrrUB;
    TempBuf = I2C_DeviceRegAddrUB;
   
    if(I2C_wtDeviceBuf.rwflg == 0) // write to SH367306
    {
      TempBuf = I2C_DeviceRegDtUB;
      I2C_crcResUB = CRC8cal(TempBuf, 3);
      
      I2C_StateFlowUW = 0x8000;
      I2C_StartProc();
                        I2C_SendData(I2C_DeviceAdrrUB);
                        I2C_StateFlowUW |= 0x01;

    }
    if(I2C_wtDeviceBuf.rwflg == 1) // read from SH367306
    {
      I2C_DeviceDtRtUW = 0;
      TempBuf = I2C_DeviceAdrrUB | 0x01;
      
      I2C_StateFlowUW = 0x4000;
      I2C_StartProc();
      I2C_SendData(I2C_DeviceAdrrUB);
      I2C_StateFlowUW |= 0x01;
    }
    I2C_wtDeviceBuf.rP = (u8)((I2C_wtDeviceBuf.rP + 1)%_I2C_WRITE_BUF_SIZE_);
   
}
        if((I2C_StateFlowUW &0x8000) == 0x8000) // write device -- SH367306
        {
                // STEP 9
                if(I2C_StateFlowUW == 0x80ff)//send stop
                {
      I2C_SendStop();
                        I2C_StateFlowUW = 0;
                }
    // STEP 8
    if(I2C_StateFlowUW == 0x807f)//wait second ack from SH367306
                {
                        I2C_ReadAck();
                        I2C_StateFlowUW |= 0x80;
                }
    // STEP 7
    if(I2C_StateFlowUW == 0x803f)//write SH367306 CRC
                {
      I2C_SendData(I2C_crcResUB);
                        I2C_StateFlowUW |= 0x40;
                }
    // STEP 6
    if(I2C_StateFlowUW == 0x801f)//wait second ack from SH367306
                {
                        I2C_ReadAck();
                        I2C_StateFlowUW |= 0x20;
                }
    // STEP 5
                if(I2C_StateFlowUW == 0x800f)//write SH367306 register data
                {
      I2C_SendData(I2C_DeviceRegDtUB);
                        I2C_StateFlowUW |= 0x10;
                }
                // STEP 4
                if(I2C_StateFlowUW == 0x8007)//wait second ack from SH367306
                {
                        I2C_ReadAck();
                        I2C_StateFlowUW |= 0x08;
                }
                // STEP 3
                if(I2C_StateFlowUW == 0x8003)// write SH367306 register address
                {
      I2C_SendData(I2C_DeviceRegAddrUB);
                        I2C_StateFlowUW |= 0x04;
                }
                // STEP 2
                if(I2C_StateFlowUW== 0x8001)// wait first ack from SH367306
                {
                        I2C_ReadAck();
                        I2C_StateFlowUW |= 0x02;
                }
        }
       
        if((I2C_StateFlowUW &0x4000) == 0x4000) // read SH367306
        {
                // STEP 14
                if(I2C_StateFlowUW == 0x7fff)//send stop
                {
                        I2C_SendStop();
                        I2C_StateFlowUW = 0;
                }
    // STEP 14
    if(I2C_StateFlowUW == 0x5fff)// read low byte of word register from SH367306
                {
                        crcBack = I2CRXD;
      I2C_crcResUB = CRC8cal(TempBuf, 5);
      I2C_SendAck(0);         
                //if(crcBack == I2C_crcResUB)
      {
      I2C_WriteDeviceBack(I2C_DeviceRegAddrUB , I2C_DeviceDtRtUW);// (u8 regAddr , u16 back)
      }
//                else
//                {
//                I2C_WriteDeviceBack(I2C_DeviceRegAddrUB , 0xffff);// (u8 regAddr , u16 back)
//                }      
                        I2C_StateFlowUW |= 0x2000;
                }
    // STEP 13
                if(I2C_StateFlowUW == 0x4fff)// read CRC from SH367306
                {
                        I2C_RecvData();   
                        I2C_StateFlowUW |= 0x1000;
                }
                // STEP 12
                if(I2C_StateFlowUW == 0x47ff)// read low byte of word register from SH367306
                {
                        I2C_SendAck(0);
      I2C_DeviceDtRtUW += I2CRXD;
      TempBuf = I2CRXD;
                        I2C_StateFlowUW |= 0x800;
                }
    // STEP 11
                if(I2C_StateFlowUW == 0x43ff)// read low byte of word register from SH367306
                {
                        I2C_RecvData();   
                        I2C_StateFlowUW |= 0x400;
                }
                // STEP 10
                if(I2C_StateFlowUW == 0x41ff)// read high byte of word register from SH367306
                {
                        I2C_DeviceDtRtUW = I2CRXD;
      TempBuf = I2CRXD;
                        I2C_SendAck(0);      
      I2C_DeviceDtRtUW <<= 8;
                        I2C_StateFlowUW |= 0x200;
                }
    // STEP 9
    if(I2C_StateFlowUW == 0x40ff)
    {
      I2C_RecvData();
      I2C_StateFlowUW |= 0x100;
    }
    // STEP 8
    if(I2C_StateFlowUW == 0x407f)// wait ack from SH367306
    {
      I2C_ReadAck();
                        I2C_StateFlowUW |= 0x80;
    }
    // STEP 7
    if(I2C_StateFlowUW == 0x403f)// write SH367306 address for reading data
                {
                        I2C_SendData(I2C_DeviceAdrrUB|0x01);   
                        I2C_StateFlowUW |= 0x40;
                }
                // STEP 6
                if(I2C_StateFlowUW == 0x401f)// RESTART SH367306 COMM -- very important
                {
                        I2C_StartProc();   
                        I2C_StateFlowUW |= 0x20;
                }
   
    // STEP 5
    if(I2C_StateFlowUW == 0x400f)// RESTART SH367306 COMM -- very important
                {
                        I2C_SendStop();   
                        I2C_StateFlowUW |= 0x10;
                }
                // STEP 4
                if(I2C_StateFlowUW == 0x4007)// wait ack from SH367306
                {
                        I2C_ReadAck();      
                        I2C_StateFlowUW |= 0x08;
                }
                // STEP 3
                if(I2C_StateFlowUW == 0x4003)//
                {
                        I2C_SendData(I2C_DeviceRegAddrUB);   
                        I2C_StateFlowUW |= 0x04;
                }
                // STEP 2
                if(I2C_StateFlowUW == 0x4001)// wait ack from SH367306
                {
                        I2C_ReadAck();
                        I2C_StateFlowUW |= 0x02;
                }
        }
}


页: [1]
查看完整版本: STC32G128K硬件I2C输出波形异常