找回密码
 立即注册
查看: 14|回复: 0

STC32G128K硬件I2C输出波形异常

[复制链接]
  • 打卡等级:初来乍到
  • 打卡总天数:1
  • 最近打卡:2026-03-21 14:05:32
已绑定手机

1

主题

0

回帖

5

积分

新手上路

积分
5
发表于 前天 14:05 | 显示全部楼层 |阅读模式
我用的MCU(STC32G12K128)的I2C模块,当SDA输出start信号(拉低)后,会有一个拉高的时间,然后在拉低。导致与IC通讯不上,不知道是什么原因

数据分析仪抓取的I2C波形

数据分析仪抓取的I2C波形

代码如下
  1. #include  "I2C.h"
  2. #include <intrins.h>
  3. #define SOFT_I2C_SCL    P25   
  4. #define SOFT_I2C_SDA    P24   
  5. u8 const CRC8Table[]=
  6. {                                                       
  7.         0x00,0x07,0x0E,0x09,0x1C,0x1B,0x12,0x15,0x38,0x3F,0x36,0x31,0x24,0x23,0x2A,0x2D,
  8.         0x70,0x77,0x7E,0x79,0x6C,0x6B,0x62,0x65,0x48,0x4F,0x46,0x41,0x54,0x53,0x5A,0x5D,
  9.         0xE0,0xE7,0xEE,0xE9,0xFC,0xFB,0xF2,0xF5,0xD8,0xDF,0xD6,0xD1,0xC4,0xC3,0xCA,0xCD,
  10.         0x90,0x97,0x9E,0x99,0x8C,0x8B,0x82,0x85,0xA8,0xAF,0xA6,0xA1,0xB4,0xB3,0xBA,0xBD,
  11.         0xC7,0xC0,0xC9,0xCE,0xDB,0xDC,0xD5,0xD2,0xFF,0xF8,0xF1,0xF6,0xE3,0xE4,0xED,0xEA,
  12.         0xB7,0xB0,0xB9,0xBE,0xAB,0xAC,0xA5,0xA2,0x8F,0x88,0x81,0x86,0x93,0x94,0x9D,0x9A,
  13.         0x27,0x20,0x29,0x2E,0x3B,0x3C,0x35,0x32,0x1F,0x18,0x11,0x16,0x03,0x04,0x0D,0x0A,
  14.         0x57,0x50,0x59,0x5E,0x4B,0x4C,0x45,0x42,0x6F,0x68,0x61,0x66,0x73,0x74,0x7D,0x7A,
  15.         0x89,0x8E,0x87,0x80,0x95,0x92,0x9B,0x9C,0xB1,0xB6,0xBF,0xB8,0xAD,0xAA,0xA3,0xA4,
  16.         0xF9,0xFE,0xF7,0xF0,0xE5,0xE2,0xEB,0xEC,0xC1,0xC6,0xCF,0xC8,0xDD,0xDA,0xD3,0xD4,
  17.         0x69,0x6E,0x67,0x60,0x75,0x72,0x7B,0x7C,0x51,0x56,0x5F,0x58,0x4D,0x4A,0x43,0x44,
  18.         0x19,0x1E,0x17,0x10,0x05,0x02,0x0B,0x0C,0x21,0x26,0x2F,0x28,0x3D,0x3A,0x33,0x34,
  19.         0x4E,0x49,0x40,0x47,0x52,0x55,0x5C,0x5B,0x76,0x71,0x78,0x7F,0x6A,0x6D,0x64,0x63,
  20.         0x3E,0x39,0x30,0x37,0x22,0x25,0x2C,0x2B,0x06,0x01,0x08,0x0F,0x1A,0x1D,0x14,0x13,
  21.         0xAE,0xA9,0xA0,0xA7,0xB2,0xB5,0xBC,0xBB,0x96,0x91,0x98,0x9F,0x8A,0x8D,0x84,0x83,
  22.         0xDE,0xD9,0xD0,0xD7,0xC2,0xC5,0xCC,0xCB,0xE6,0xE1,0xE8,0xEF,0xFA,0xFD,0xF4,0xF3
  23. };
  24. u16  I2C_StateFlowUW;
  25. u8   I2C_DeviceAdrrUB;
  26. u8   I2C_DeviceRegAddrUB;
  27. u8   I2C_DeviceRegDtUB;
  28. u8   I2C_crcResUB;
  29. u16  I2C_DeviceDtRtUW;
  30. u8   I2C_hdAckUB;
  31. u8   I2C_stWrkStUB;
  32. I2C_wtFifo_S   I2C_wtDeviceBuf;
  33. I2C_rdFifo_S   I2C_deviceBackBuf;
  34. void  I2C_EnterLowPowerMode(void)
  35. {
  36.   // stop all I2C communication
  37.   for(;;)
  38.   {
  39.     I2C_Update();
  40.    
  41.   }
  42.   
  43. }
  44. void  I2C_RecoveryFromLowPowerMode(void)
  45. {
  46.   
  47. }
  48. /*******************************************************************************
  49. Function: CRC8cal()
  50. Description:
  51. Input:
  52. Output:
  53. ********************************************************************************/
  54. u8 CRC8cal(u8 *p, u8 counter)                       //look-up table calculte CRC
  55. {   
  56.   u8 crc8 = 0;   
  57.    
  58.         for( ; counter > 0; counter--)
  59.         {
  60.                 crc8 = CRC8Table[crc8^*p];   
  61.           p++;   
  62.   }   
  63.   return (crc8);   
  64. }   
  65. /*******************************************************************************
  66. Function: I2C_Init()
  67. Description:
  68. Input:
  69. Output:
  70. ********************************************************************************/
  71. void   I2C_Init(void)
  72. {
  73.         P2M0 &= 0xCF;
  74.         P2M1 &= 0xCF;
  75.     P2PU |= 0x30;
  76.         P_SW2 |= 0x90; // i2c mirror to P3.2 P3.3; extern ram aera allow
  77.         I2CCFG = 0xdc;  // ENABLE I2C; MASTER MODE; 200K RATE
  78.         I2CMSAUX = 0;   // DISABLE MASTER MODE AUTO SEND ACK
  79.         I2CMSST = 0;
  80.         I2C_StateFlowUW = 0;
  81.   I2C_wtDeviceBuf.wP = 0;
  82.   I2C_wtDeviceBuf.rP = 0;
  83.   I2C_deviceBackBuf.wP = 0;
  84.   I2C_deviceBackBuf.rP = 0;
  85.   I2CMSCR = 0;
  86. }
  87. /*******************************************************************************
  88. //
  89. ********************************************************************************/
  90. void  I2C_SetSlaveAddr(u8 addrUB)
  91. {
  92.   I2C_DeviceAdrrUB = addrUB;
  93. }
  94. /*******************************************************************************
  95. //
  96. ********************************************************************************/
  97. void  I2C_SendData(u8  datUB)
  98. {
  99.         I2CTXD = datUB;
  100.         I2CMSCR = 0x2;
  101.   for(;;)
  102.   {
  103.     if((I2CMSST & 0x40 ) == 0x40)
  104.     {
  105.       I2CMSST &= ~0x40;
  106.       break;
  107.     }
  108.   }
  109. }
  110. /*******************************************************************************
  111. //
  112. ********************************************************************************/
  113. void  I2C_StartProc(void)
  114. {
  115.         I2CMSCR = 0x1;
  116.   for(;;)
  117.   {
  118.     if((I2CMSST & 0x40 ) == 0x40)
  119.     {
  120.       I2CMSST &= ~0x40;
  121.       break;
  122.     }
  123.   }
  124. }
  125. /*******************************************************************************
  126. //
  127. ********************************************************************************/
  128. void  I2C_ReadAck(void)
  129. {
  130.         I2CMSCR = 0x3;
  131.   for(;;)
  132.   {
  133.     if((I2CMSST & 0x40 ) == 0x40)
  134.     {
  135.       I2CMSST &= ~0x40;
  136.       break;
  137.     }
  138.   }
  139. }
  140. /*******************************************************************************
  141. //
  142. ********************************************************************************/
  143. void  I2C_RecvData(void)
  144. {
  145.         I2CMSCR = 0x4;
  146.   for(;;)
  147.   {
  148.     if((I2CMSST & 0x40 ) == 0x40)
  149.     {
  150.       I2CMSST &= ~0x40;
  151.       break;
  152.     }
  153.   }
  154. }
  155. /*******************************************************************************
  156. //
  157. ********************************************************************************/
  158. void  I2C_SendAck(u8 ackBool)
  159. {
  160.         if(ackBool == 1)
  161.         {
  162.                 I2CMSST |= 1;
  163.         }
  164.         else
  165.         {
  166.                 I2CMSST &= 0xfe;
  167.         }
  168.        
  169.         I2CMSCR = 0x5;
  170.   for(;;)
  171.   {
  172.     if((I2CMSST & 0x40 ) == 0x40)
  173.     {
  174.       I2CMSST &= ~0x40;
  175.       break;
  176.     }
  177.   }
  178. }
  179. /*******************************************************************************
  180. //
  181. ********************************************************************************/
  182. void  I2C_SendStop(void)
  183. {
  184.         I2CMSCR = 0x6;
  185.   for(;;)
  186.   {
  187.     if((I2CMSST & 0x40 ) == 0x40)
  188.     {
  189.       I2CMSST &= ~0x40;
  190.       break;
  191.     }
  192.   }
  193. }
  194. /*******************************************************************************
  195. // write data to slave device
  196. ********************************************************************************/
  197. void  I2C_WriteDeviceBuf(u8 regAddr, u8 dtUB , u8 rdOrWt)
  198. {
  199.   u8 idxWtUB;
  200.   
  201.   if((I2C_wtDeviceBuf.wP + 1)%_I2C_WRITE_BUF_SIZE_ != I2C_wtDeviceBuf.rP)
  202.         {
  203.                 idxWtUB = I2C_wtDeviceBuf.wP;
  204.     I2C_wtDeviceBuf.addrUB[idxWtUB] = regAddr;
  205.     I2C_wtDeviceBuf.dtUB[idxWtUB] = dtUB;
  206.     I2C_wtDeviceBuf.rwflg[idxWtUB] = rdOrWt;
  207.                 I2C_wtDeviceBuf.wP  = (u8)((I2C_wtDeviceBuf.wP  + 1)%_I2C_WRITE_BUF_SIZE_);
  208.         }
  209. }
  210. /*******************************************************************************
  211. //
  212. ********************************************************************************/
  213. void  I2C_WriteDeviceBack(u8 regAddr , u16 back)
  214. {
  215.   u8 idxWtUB;
  216.   
  217.   if((I2C_deviceBackBuf.wP + 1)%_I2C_READ_BUF_SIZE_ != I2C_deviceBackBuf.rP)
  218.         {
  219.                 idxWtUB = I2C_deviceBackBuf.wP;
  220.     I2C_deviceBackBuf.addrUB[idxWtUB] = regAddr;
  221.     I2C_deviceBackBuf.dtUW[idxWtUB] = back;
  222.                 I2C_deviceBackBuf.wP  = (u8)((I2C_deviceBackBuf.wP  + 1)%_I2C_READ_BUF_SIZE_);
  223.         }
  224. }
  225. /*******************************************************************************
  226. //
  227. ********************************************************************************/
  228. u16  I2C_ReadDeviceBackBuf(u8* regAddr)
  229. {
  230.   u16 retUW;
  231.   
  232.   if(I2C_deviceBackBuf.wP != I2C_deviceBackBuf.rP)
  233.   {
  234.     *regAddr = I2C_deviceBackBuf.addrUB[I2C_deviceBackBuf.rP];
  235.     retUW = I2C_deviceBackBuf.dtUW[I2C_deviceBackBuf.rP];
  236.     I2C_deviceBackBuf.rP = (u8)((I2C_deviceBackBuf.rP + 1)%_I2C_READ_BUF_SIZE_);
  237.   }
  238.   else
  239.   {
  240.     *regAddr = 0xff;
  241.     retUW = 0xffff;
  242.   }
  243.   return  retUW;
  244. }
  245. /*******************************************************************************
  246. //
  247. ********************************************************************************/
  248. void  I2C_Update(void)
  249. {
  250.   static u8 TempBuf[5];
  251.   u8 rdBuf , crcBack ;
  252.   if((I2C_wtDeviceBuf.wP != I2C_wtDeviceBuf.rP)&&(I2C_StateFlowUW == 0)&&((I2CMSST & 0x80 ) == 0))
  253.   {  
  254.     rdBuf = I2C_wtDeviceBuf.rP;
  255.     I2C_DeviceRegAddrUB = I2C_wtDeviceBuf.addrUB[rdBuf];
  256.     I2C_DeviceRegDtUB = I2C_wtDeviceBuf.dtUB[rdBuf];
  257.    
  258.     // write 4 byte ( I2C_DeviceAdrrUB , I2C_DeviceRegAddrUB , I2C_DeviceRegDtUB , I2C_crcResUB ) to
  259.     // slave device -- SH367306
  260.     TempBuf[0] = I2C_DeviceAdrrUB;
  261.     TempBuf[1] = I2C_DeviceRegAddrUB;
  262.    
  263.     if(I2C_wtDeviceBuf.rwflg[rdBuf] == 0) // write to SH367306
  264.     {
  265.       TempBuf[2] = I2C_DeviceRegDtUB;
  266.       I2C_crcResUB = CRC8cal(TempBuf, 3);
  267.       
  268.       I2C_StateFlowUW = 0x8000;
  269.       I2C_StartProc();
  270.                         I2C_SendData(I2C_DeviceAdrrUB);
  271.                         I2C_StateFlowUW |= 0x01;
  272.     }
  273.     if(I2C_wtDeviceBuf.rwflg[rdBuf] == 1) // read from SH367306
  274.     {
  275.       I2C_DeviceDtRtUW = 0;
  276.       TempBuf[2] = I2C_DeviceAdrrUB | 0x01;
  277.       
  278.       I2C_StateFlowUW = 0x4000;
  279.       I2C_StartProc();
  280.       I2C_SendData(I2C_DeviceAdrrUB);
  281.       I2C_StateFlowUW |= 0x01;
  282.     }
  283.     I2C_wtDeviceBuf.rP = (u8)((I2C_wtDeviceBuf.rP + 1)%_I2C_WRITE_BUF_SIZE_);
  284.    
  285.   }
  286.         if((I2C_StateFlowUW &0x8000) == 0x8000) // write device -- SH367306
  287.         {
  288.                 // STEP 9
  289.                 if(I2C_StateFlowUW == 0x80ff)  //  send stop
  290.                 {
  291.       I2C_SendStop();
  292.                         I2C_StateFlowUW = 0;
  293.                 }
  294.     // STEP 8
  295.     if(I2C_StateFlowUW == 0x807f)  //  wait second ack from SH367306
  296.                 {
  297.                         I2C_ReadAck();
  298.                         I2C_StateFlowUW |= 0x80;
  299.                 }
  300.     // STEP 7
  301.     if(I2C_StateFlowUW == 0x803f)  //  write SH367306 CRC
  302.                 {
  303.       I2C_SendData(I2C_crcResUB);  
  304.                         I2C_StateFlowUW |= 0x40;
  305.                 }
  306.     // STEP 6
  307.     if(I2C_StateFlowUW == 0x801f)  //  wait second ack from SH367306
  308.                 {
  309.                         I2C_ReadAck();
  310.                         I2C_StateFlowUW |= 0x20;
  311.                 }
  312.     // STEP 5
  313.                 if(I2C_StateFlowUW == 0x800f)  //  write SH367306 register data
  314.                 {
  315.       I2C_SendData(I2C_DeviceRegDtUB);  
  316.                         I2C_StateFlowUW |= 0x10;
  317.                 }
  318.                 // STEP 4
  319.                 if(I2C_StateFlowUW == 0x8007)  //  wait second ack from SH367306
  320.                 {
  321.                         I2C_ReadAck();
  322.                         I2C_StateFlowUW |= 0x08;
  323.                 }
  324.                 // STEP 3
  325.                 if(I2C_StateFlowUW == 0x8003)  // write SH367306 register address
  326.                 {
  327.       I2C_SendData(I2C_DeviceRegAddrUB);  
  328.                         I2C_StateFlowUW |= 0x04;
  329.                 }
  330.                 // STEP 2
  331.                 if(I2C_StateFlowUW  == 0x8001)  // wait first ack from SH367306
  332.                 {
  333.                         I2C_ReadAck();
  334.                         I2C_StateFlowUW |= 0x02;
  335.                 }
  336.         }
  337.        
  338.         if((I2C_StateFlowUW &0x4000) == 0x4000) // read SH367306
  339.         {
  340.                 // STEP 14
  341.                 if(I2C_StateFlowUW == 0x7fff)  //  send stop
  342.                 {
  343.                         I2C_SendStop();
  344.                         I2C_StateFlowUW = 0;
  345.                 }
  346.     // STEP 14
  347.     if(I2C_StateFlowUW == 0x5fff)  // read low byte of word register from SH367306
  348.                 {
  349.                         crcBack = I2CRXD;
  350.       I2C_crcResUB = CRC8cal(TempBuf, 5);
  351.       I2C_SendAck(0);         
  352.                 //if(crcBack == I2C_crcResUB)
  353.       {
  354.         I2C_WriteDeviceBack(I2C_DeviceRegAddrUB , I2C_DeviceDtRtUW);  // (u8 regAddr , u16 back)
  355.       }
  356. //                else
  357. //                {
  358. //                I2C_WriteDeviceBack(I2C_DeviceRegAddrUB , 0xffff);  // (u8 regAddr , u16 back)
  359. //                }        
  360.                         I2C_StateFlowUW |= 0x2000;
  361.                 }
  362.     // STEP 13
  363.                 if(I2C_StateFlowUW == 0x4fff)  // read CRC from SH367306
  364.                 {
  365.                         I2C_RecvData();     
  366.                         I2C_StateFlowUW |= 0x1000;
  367.                 }
  368.                 // STEP 12
  369.                 if(I2C_StateFlowUW == 0x47ff)  // read low byte of word register from SH367306
  370.                 {
  371.                         I2C_SendAck(0);
  372.       I2C_DeviceDtRtUW += I2CRXD;
  373.       TempBuf[4] = I2CRXD;
  374.                         I2C_StateFlowUW |= 0x800;
  375.                 }
  376.     // STEP 11
  377.                 if(I2C_StateFlowUW == 0x43ff)  // read low byte of word register from SH367306
  378.                 {
  379.                         I2C_RecvData();     
  380.                         I2C_StateFlowUW |= 0x400;
  381.                 }
  382.                 // STEP 10
  383.                 if(I2C_StateFlowUW == 0x41ff)  // read high byte of word register from SH367306
  384.                 {
  385.                         I2C_DeviceDtRtUW = I2CRXD;
  386.       TempBuf[3] = I2CRXD;
  387.                         I2C_SendAck(0);        
  388.       I2C_DeviceDtRtUW <<= 8;
  389.                         I2C_StateFlowUW |= 0x200;
  390.                 }
  391.     // STEP 9
  392.     if(I2C_StateFlowUW == 0x40ff)
  393.     {
  394.       I2C_RecvData();  
  395.       I2C_StateFlowUW |= 0x100;
  396.     }
  397.     // STEP 8
  398.     if(I2C_StateFlowUW == 0x407f)  // wait ack from SH367306
  399.     {
  400.       I2C_ReadAck();
  401.                         I2C_StateFlowUW |= 0x80;
  402.     }
  403.     // STEP 7
  404.     if(I2C_StateFlowUW == 0x403f)  // write SH367306 address for reading data
  405.                 {
  406.                         I2C_SendData(I2C_DeviceAdrrUB|0x01);   
  407.                         I2C_StateFlowUW |= 0x40;
  408.                 }
  409.                 // STEP 6
  410.                 if(I2C_StateFlowUW == 0x401f)  // RESTART SH367306 COMM -- very important
  411.                 {
  412.                         I2C_StartProc();     
  413.                         I2C_StateFlowUW |= 0x20;
  414.                 }
  415.    
  416.     // STEP 5
  417.     if(I2C_StateFlowUW == 0x400f)  // RESTART SH367306 COMM -- very important
  418.                 {
  419.                         I2C_SendStop();     
  420.                         I2C_StateFlowUW |= 0x10;
  421.                 }
  422.                 // STEP 4
  423.                 if(I2C_StateFlowUW == 0x4007)  // wait ack from SH367306
  424.                 {
  425.                         I2C_ReadAck();      
  426.                         I2C_StateFlowUW |= 0x08;
  427.                 }
  428.                 // STEP 3
  429.                 if(I2C_StateFlowUW == 0x4003)  //  
  430.                 {
  431.                         I2C_SendData(I2C_DeviceRegAddrUB);   
  432.                         I2C_StateFlowUW |= 0x04;
  433.                 }
  434.                 // STEP 2
  435.                 if(I2C_StateFlowUW == 0x4001)  // wait ack from SH367306
  436.                 {
  437.                         I2C_ReadAck();
  438.                         I2C_StateFlowUW |= 0x02;
  439.                 }
  440.         }
  441. }
复制代码



回复

使用道具 举报 送花

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|手机版|深圳国芯人工智能有限公司 ( 粤ICP备2022108929号-2 )

GMT+8, 2026-3-23 18:21 , Processed in 0.106074 second(s), 45 queries .

Powered by Discuz! X3.5

© 2001-2026 Discuz! Team.

快速回复 返回顶部 返回列表