STM8L15X 硬件I2C調試總結


最近接到一個項目需要使用STM8L上硬件I2C與SN3731通信,用戶方是個方案商,硬件設計人員也沒留測試點,直接就把板子焊了拿來了。調試時除了swio口能用所有都不能用,硬件設計大概是為了顯得自己焊接技術牛B吧,調試用的板子用0402的封裝,IC除了找不到QFN的曲阿布都用的QFN,做項目時不能說,在這里我先問候一下他娘親。,,,。

這塊板子經過大量的補焊終於可以上電出時序了。

調試STM8的硬件I2C master 注意一下幾點,可以少走彎路:

1、需要配置GPIO引腳為GPIO_Mode_Out_OD_HiZ_Slow或fast,如果要提高抗干擾能力,完全可以配置為推挽輸出模式的,我使用的是GPIO_Mode_Out_PP_High_Slow,或Fast,否則手摸都可能死鎖。

2、如果是開漏高阻的需要上拉電阻,這個電阻很重要,影響穩定性,手冊上說4.7k是可以,建議小於這個值,否則手摸都可能卡死。這個還取決於slave端的電流拉動能力,其實就是ack時的上拉能力。

3、剛開始調試不建議用中斷模式的

4、I2C的速度可調,數值我測試使用40k,實際測試基本准確,穩定了可根據slave情況提高速度

5、必須有slave端,否則你就在while中加超時以便可以跳出來,要不就會收不到slave的ack信號一直卡死在這里。也可以做解鎖代碼進去,我的如下(這個是為解決抗干擾后加的,實踐證明很有效):

。。。
 while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT)){if(++timeout>MaxTimeOut)goto stop;}

。。。

 stop:
    I2CClearStatus();
    I2C_GenerateSTOP(I2C1,ENABLE);  //停止信號  
    I2C_DeInit(I2C1);
    I2C_SoftwareResetCmd(I2C1,ENABLE);
    I2C_3731_Init(0);

 

硬件I2C並不像網上大部分人認為的這么多坑,對硬件熟悉的話不會走太多彎路,大部分卡死估計主要是地址不對,對於st的例程,如果地址是錯的或者沒接,或者沒上電,或者沒選通,或者關斷使能了等等可能只要有一種情況發生,slave就根本不會響應ack,那么主機就一直在等待中,估計很多人是掉這個坑里了。

硬件I2C速度快(超過400khz沒問題),省代碼,如果軟件的已經調通了還是推薦改成硬件的。

void I2C_3731_Init(unsigned char Addr)
{
 GPIO_Init(GPIOC, GPIO_Pin_0, GPIO_Mode_Out_OD_HiZ_Slow);
                GPIO_Init(GPIOC, GPIO_Pin_1, GPIO_Mode_Out_OD_HiZ_Slow);
                CLK_PeripheralClockConfig(CLK_Peripheral_I2C1, ENABLE);
  /* I2C  clock Enable*/
  CLK_PeripheralClockConfig(CLK_Peripheral_I2C1, ENABLE);  
  
  /* Initialize I2C peripheral */
  I2C_Init(I2C1,40000, Addr, //I2C_MAX_FAST_FREQ
           I2C_Mode_I2C, I2C_DutyCycle_2,
           I2C_Ack_Enable, I2C_AcknowledgedAddress_7bit);
}


void I2C_3731_BufferWrite(u8* pBuffer,u16 WriteAddr,u8 NumByte)//I2Cдº¯Êý
{
    while(I2C_GetFlagStatus(I2C1,I2C_FLAG_BUSY));//»ñȡָ¶¨µÄ±ê־״̬£¨ÅжÏ×ÜÏß·±Ã¦×´Ì¬£©
    
    I2C_GenerateSTART(I2C1, ENABLE);
     while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT));//¼ì²âÖ¸¶¨ÐźÅ״̬£¨EV5ʼþ£©Èç¹ûûÓз¢ËÍÍê³ÉÔÚÕâÀïµÈ´ý£¬×¢Ò⣡ºÅµÄÓ¦ÓÃ

     I2C_Send7bitAddress(I2C1,SLAVE_ADDRESS+((WriteAddr/256)<<1),I2C_Direction_Transmitter);//²»´óÓÚ24C16µÄÆ÷¼þµØÖ·
     while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));
    
    I2C_SendData(I2C1,(u8)(WriteAddr));//µÍ8λ×Ö½ÚµØÖ·
    while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_BYTE_TRANSMITTING));//£¨EV8ʼþ£©
    
    while(NumByte--)
    {
        I2C_SendData(I2C1,*pBuffer);
        pBuffer++;
        
        if(NumByte==0)
        {
            while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_BYTE_TRANSMITTED));
        }
        else
        {
            while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_BYTE_TRANSMITTING));
        }        
    }
    I2C_GenerateSTOP(I2C1,ENABLE);  //Í£Ö¹ÐźŠ  
}

void I2C_3731_BufferRead(u8* pBuffer,u16 ReadAddr,u8 NumByte)
{
    while(I2C_GetFlagStatus(I2C1,I2C_FLAG_BUSY));
    I2C_GenerateSTART(I2C1,ENABLE);    
    while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_MODE_SELECT));
    
//    if(EE_TYPE>AT24C16)
//    {
//        I2C_Send7bitAddress(I2C1,SLAVE_ADDRESS,I2C_Direction_Transmitter);
//        while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED));
//        
//        I2C_SendData(I2C1,(u8)(ReadAddr>>8));
//        while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_BYTE_TRANSMITTING));
//    }
//    else
    {   //1010 000 0
        I2C_Send7bitAddress(I2C1,SLAVE_ADDRESS+((ReadAddr/256)<<1),I2C_Direction_Transmitter);
        while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));
    }
    
    I2C_SendData(I2C1,(u8)(ReadAddr));
    while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_BYTE_TRANSMITTING));
    
    I2C_GenerateSTART(I2C1,ENABLE);    
    while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_MODE_SELECT));
    
    I2C_Send7bitAddress(I2C1,SLAVE_ADDRESS,I2C_Direction_Receiver);
    while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED));
    
    while(NumByte)
    {
        if(NumByte==1)
        {
            I2C_AcknowledgeConfig(I2C1,DISABLE);
            I2C_GenerateSTOP(I2C1,ENABLE); 
        }
        
        if(I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_BYTE_RECEIVED))
        {
            *pBuffer=I2C_ReceiveData(I2C1);
            pBuffer++;
            NumByte--;
        }
    }
    
    I2C_AcknowledgeConfig(I2C1,ENABLE);
}

//main
I2C_3731_Init(0); 

      for (i = 0; i < BUFFERSIZE; i++)
      {
        TxBuffer[i] = i;
      }
      I2C_3731_BufferWrite(TxBuffer,0x00,sizeof(TxBuffer));

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM