STM32 软件 I2C Source Files (No Clock Strech)

发布于:2022-12-21 ⋅ 阅读:(421) ⋅ 点赞:(0)

STM32 软件 I2C Source Files (No Clock Strech)

** 验证程序:**

const uint8_t  ucPattern[8] = { 0x55, 0xAA, 0x66, 0xBB, 0x77, 0xCC, 0x88, 0xDD };
uint8_t  ucBuf[8]= {0};
extern char stringbuf[]; 
/* Show Error Message */
void vDisplayErrorAndHold( uint16_t  errcode)
{
	switch( errcode )
	{
		case 0:
			printf("\r\nIIC Write Error");
			break;
		case 1:
			printf("\r\nIIC Read Error");		
			break;
		case 2:
			printf("\r\nIIC Compare Error");				
			break;
	}
	portBuzzerOn( ); 
	while(1);
}
/*  Test i2c devices  */
void vTestI2CAccess(void)
{
	for( uint16_t  i=0;  i<100;  i++ )
	{
		/* Fill 256bytes */ 
		for(  uint16_t  j=0;  j< 32;  j++ )
		{
			if(  FAIL == SoftIICWrite( 0xA0,  (uint8_t )(j*8),  8, ucPattern ) ) vDisplayErrorAndHold(0);
			DelayXms(10); 
			sprintf( stringbuf, “Write Page: %3u, j)
			LCDPUTSTRING( 0, 0, stringbuf ); 
		}
		/* Read Data Back */ 
		for( uint16_t  j=0;  j< 32;  j++ )
		{
			if( FAIL == SoftIICRead( 0xA1,  (uint8_t )(j*8),  8, ucBuf )) vDisplayErrorAndHold(1);
			for(uint16_t k=0; k<8; k++)  if(  ucBuf[k] != ucPattern[k]  )  vDisplayErrorAndHold(2);
			sprintf( stringbuf, “Read Page: %3u, j );
			LCDPUTSTRING( 0, 1, stringbuf ); 
		}
	}
}

i2C Write
i2C WriteWrite Bytes
No Clock strechI2C Read
i2C Read
Header File: (SoftIIC.h)

/****************************************************************************
*  Software IIC Lib @ ARM M3
*  Since STM32F103C8/C6 came-out IIC unstable issue, and C6 lacks I2C2.
*  Porting software IIC for simultaneously switch between C8/C6 by request.
*
*  Usage:
*   1. Modify SoftIIC.H to match hardware pin Configuration.
*   Both SDA/SCL pin as Output_Open_Drain (OD) without pull-up/ pull-down.
*
*   SoftIICRead(uint8_t Dev, uint8_t ucAddr, uint8_t ucLen, uint8_t* pBuf);
*     Dev:    slave device 8-bits address.
*     ucAddr: Register address for access
*     ucLen:  Bytes
*     pBuf:   Data for buffer for store data.
*
*   Example:  ucI2CStaus = SoftIICRead( 0xA0, 0, 8, pBuf );
*
*   SoftIICWrite(uint8_t Dev, uint8_t ucAddr, uint8_t ucLen, uint8_t* pBuf);
*     Dev:    slave device 8-bits address.
*     ucAddr: Register address for access
*     ucLen:  Bytes
*     pBuf:   Data for buffer for store data.
*
*   Example:  ucI2CStaus = SoftIICWrite( 0xA0, 0, 8, pBuf );
*
*                             By Jason Lu. 2022/08/31 @WUXI
*/
#ifndef __SOFTIIC_H_
 #define __SOFTIIC_H_
 #ifdef __cplusplus
   extern "C" {
 #endif 

    #include "brd.h"
    extern void DelayXus(uint32_t );

    typedef enum Acknowledge_Type { ACK=0x00U , NACK=!ACK } Acknowledge_TypeDef;
    
	#define I2C_ERROR_NONE          0x00U    /* No error            */
	#define I2C_ERROR_BERR          0x01U    /* BERR error          */
    #define I2C_ERROR_AF                0x04U    /* AF error            */
	#define I2C_ERROR_TIMEOUT     0x20U    /* Timeout Error       */
    #define I2C_ERROR_BUSBUSY     0x80U    /* BUS BUSY            */

#if 0
    // I2C1 Default Hardware Pin 
	#define hwSCL   (1U << 6)
	#define portSetSCL()     		GPIOB->BSRR = hwSCL
	#define portResetSCL()   		GPIOB->BRR  = hwSCL
	#define portGetSCL()            (0U != (GPIOB->IDR & hwSCL))
	
	#define hwSDA   ( 1U << 7 )
	#define portSetSDA()     		GPIOB->BSRR = hwSDA
	#define portResetSDA()        	GPIOB->BRR  = hwSDA
	#define portGetSDA()            (0U != (GPIOB->IDR & hwSDA))   
#else
    // I2C2 Default Hardware Pin
	#define hwSCL   (1U << 10)
	#define portSetSCL()     		GPIOB->BSRR = hwSCL
	#define portResetSCL()   		GPIOB->BRR  = hwSCL
	#define portGetSCL()            (0U != (GPIOB->IDR & hwSCL))
	
	#define hwSDA   ( 1U << 11 )
	#define portSetSDA()     		GPIOB->BSRR = hwSDA
	#define portResetSDA()        	GPIOB->BRR  = hwSDA
	#define portGetSDA()            (0U != (GPIOB->IDR & hwSDA))
#endif
    
    /* Both High as Bus Free        */
    #define IsBusFree()  			( portGetSCL() && portGetSCL() )
    /* Apply Acknowledge to SDA pin */
    void IICAck(uint8_t bAck);
		#define IIC_ACK()   IICAck(0)
		#define IIC_NACK()  IICAck(1)
    
    /* IIC Bus Start                    */
    void IICStart(void);
    
    /* IIC Bus Stop                     */
    void IICStop(void) ;
    
    /* Write 8-bits & Check Acknowledge */
    uint8_t IICWrite8Bits(  uint8_t  );
    
    /* Read 8-bits without Acknowledge  */
    void IICRead8Bits(unsigned char*  );
 
    /* Read Multiple Bytes              */
    uint8_t SoftIICRead(uint8_t Dev, uint8_t ucAddr, uint8_t ucLen, uint8_t* pBuf);

    /* Write Multiple Bytes             */    
    uint8_t SoftIICWrite(uint8_t Dev, uint8_t ucAddr, uint8_t ucLen, uint8_t* pBuf);

  #ifdef __cplusplus
   }
  #endif	  
#endif

注意事项:

  1. Dummy for /while loop可能会在 gcc 优化时被移除, 造时序要注意, 优化后会太快 > 400KHz.
  2. ATMEL 24Cxx 的 Acknowledge 需要约 700ns才会响应, 要保留反应时间
  3. ATMEL 24Cxx 在写后需要一段写入时间, 旧数据 10ms, 不过这期间 SCL并无 Clock Strech现象(时序上可以明显看出), 可以继续操作其他 Device(s).
  4. 旧版本的 Read时序有问题, 修正:
void IICRead8Bits(uint8_t* pdata)
{
   uint8_t i;

   *pdata = 0;
   for(i = 8; i > 0 ; i--)
     {
	    DelayXus(3);
	    portSetSCL();
		*pdata <<= 1;
		if(portGetSDA())
		  { *pdata +=1; }
	    DelayXus(3);
	    portResetSCL();
 	}
}

STM32 软件 I2C Source Files (No Clock Strech)
数据剪辑自原厂规格书, 版权归原所有人拥有。
档案取自互联网!如有侵权或不适用情形, 请联系移除!
** 使用有风险, 请详阅原厂使用说明!
** 范例码为自用,请勿引用, Ctrl-C, Ctrl-V结果自行承担!


网站公告

今日签到

点亮在社区的每一天
去签到